首页 > 解决方案 > 在带有预处理的 GridSearchCV 管道中使用 SMOTEENN

问题描述

我正在处理一个高度不平衡的数据集的分类问题。我正在尝试SMOTEENN在网格搜索管道中使用,但是我不断收到这个 ValueError:

ValueError: Invalid parameter randomforestclassifier for estimator Pipeline(memory=None,
         steps=[('preprocessor_X',
                 ColumnTransformer(n_jobs=None, remainder='drop',
                                   sparse_threshold=0.3,
                                   transformer_weights=None,
                                   transformers=[('num',
                                                  Pipeline(memory=None,
                                                           steps=[('scaler',
                                                                   StandardScaler(copy=True,
                                                                                  with_mean=True,
                                                                                  with_std=True))],
                                                           verbose=False),
                                                  ['number_of_participants',
                                                   'count_timely_submission',
                                                   'count_by_self',
                                                   'count_at_ra...
                                                         class_weight='balanced',
                                                         criterion='gini',
                                                         max_depth=None,
                                                         max_features='auto',
                                                         max_leaf_nodes=None,
                                                         max_samples=None,
                                                         min_impurity_decrease=0.0,
                                                         min_impurity_split=None,
                                                         min_samples_leaf=1,
                                                         min_samples_split=2,
                                                         min_weight_fraction_leaf=0.0,
                                                         n_estimators=100,
                                                         n_jobs=None,
                                                         oob_score=False,
                                                         random_state=0,
                                                         verbose=0,
                                                         warm_start=False))],
                          verbose=False))],
         verbose=False). Check the list of available parameters with `estimator.get_params().keys()`.

我在网上发现,如果导入了来自 imblearn 的管道,SMOTEENN 可以与 GridSearchCV 一起使用。我正在使用来自 imblearn 的管道,但它仍然给我这个错误。

当我尝试使用SMOTEENN和获取 X 和 y 变量时,问题首先开始。我有一个prepare_data()将数据分解为 X,y 的函数。我想SMOTEENN在该函数中使用并返回平衡数据。但是,我的功能之一是字符串类型 - 并且需要放入OneHotEncoder. 出于某种原因,SMOTEENN似乎不处理字符串。因此,我需要在管道中使用它,这样SMOTEENN才能有效post-preprocessing

我在下面粘贴我的管道代码。任何帮助或解释将不胜感激!谢谢!

def ML_RandomF(X, y, random_state, n_folds, oneHot_ftrs, 
               num_ftrs, ordinal_ftrs, ordinal_cats, beta, test_size, score_type):

    scoring = {'roc_auc_score': make_scorer(roc_auc_score), 
               'f_beta': make_scorer(fbeta_score, beta=beta, average='weighted'), 
               'accuracy': make_scorer(accuracy_score)}

    X_other, X_test, y_other, y_test = train_test_split(X, y, test_size=test_size, random_state = random_state)
    kf = StratifiedKFold(n_splits=n_folds,shuffle=True,random_state=random_state)  

    reg = RandomForestClassifier(random_state=random_state, n_estimators=100, class_weight="balanced")
    sme = SMOTEENN(random_state=random_state)

    model = Pipeline([
        ('sampling', sme),
        ('classification', reg)])

    # ordinal encoder
    ordinal_transformer = Pipeline(steps=[
        ('ordinal', OrdinalEncoder(categories = ordinal_cats))])

    # oneHot encoder
    onehot_transformer = Pipeline(steps=[
        ('ordinal', OneHotEncoder(sparse=False, handle_unknown='ignore'))])

    # standard scaler
    numeric_transformer = Pipeline(steps=[
        ('scaler', StandardScaler())])

    preprocessor_X = ColumnTransformer(
        transformers=[
            ('num', numeric_transformer, num_ftrs),
            ('oneH', onehot_transformer, oneHot_ftrs),
            ('ordinal', ordinal_transformer, ordinal_ftrs)])

    pipe = Pipeline(steps=[('preprocessor_X', preprocessor_X), ('model', model)])

    param_grid = {'randomforestclassifier__max_depth': [3,5,7,10], 
                  'randomforestclassifier__min_samples_split': [10,25,40]}
    grid = GridSearchCV(pipe,param_grid=param_grid,
                        scoring=scoring,cv=kf, refit=score_type,
                        return_train_score=True,iid=True, verbose=2, n_jobs=-1)

    grid.fit(X_other, y_other)
    return grid, grid.score(X_test, y_test)

标签: random-forestsklearn-pandasgrid-searchimblearnimbalanced-data

解决方案


您已命名RandomForestClassifier为,classification并且该管道model在您的下一个管道中被命名为 as。因此你必须改变你param_grid的如下


param_grid = {'model__classification__max_depth': [3,5,7,10], 
              'model__classification__min_samples_split': [10,25,40]}

推荐阅读