优化最佳特征的数量

Posted

技术标签:

【中文标题】优化最佳特征的数量【英文标题】:Optimizing number of optimum features 【发布时间】:2018-07-18 10:23:12 【问题描述】:

我正在使用 Keras 训练神经网络。每次训练我的模型时,我都会使用通过ExtraTreesClassifier() 选择的Tree-based feature selection 选择的一组略有不同的特征。每次训练后,我在验证集上计算AUCROC,然后返回循环以使用不同的特征集再次训练模型。这个过程非常低效,我想使用某些 python 库中可用的一些优化技术来选择最佳数量的功能。 要优化的函数是用于交叉验证的auroc,它只能在对选定特征训练模型后计算。通过以下函数选择特征ExtraTreesClassifier(n_estimators=10, criterion=’gini’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=’auto’) 这里我们看到目标函数不直接依赖于要优化的参数。目标函数auroc与神经网络训练有关,神经网络以特征为输入,根据其重要性从ExtraTreesClassifier中提取。 所以在某种程度上,我优化auroc 的参数是n_estimators=10, criterion=’gini’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=’auto’ExtraTreesClassifier 中的一些其他变量。这些与auroc 没有直接关系。

【问题讨论】:

可能我需要使用sklearn pipeline 【参考方案1】:

您应该结合使用 GridSearchCV 和 Pipeline。 Find more here 当您需要按顺序运行一组指令以获得最佳配置时,请使用 Pipeline。

例如,您需要运行以下步骤: 1. 选择 KBest 功能 2.使用分类器DecisionTree或NaiveBayes

通过结合 GridSearchCV 和 Pipeline,您可以根据评分标准选择最适合特定分类器的功能、分类器上的最佳配置等。

例子:

#set your configuration options 
param_grid = [
    'classify': [DecisionTreeClassifier()], #first option use DT
    'kbest__k': range(1, 22), #range of n in SelectKBest(n)

    #classifier's specific configs
    'classify__criterion': ('gini', 'entropy'), 
    'classify__min_samples_split': range(2,10),
    'classify__min_samples_leaf': range(1,10)
,

    'classify': [GaussianNB()], #second option use NB
    'kbest__k': range(1, 22), #range of n in SelectKBest(n)
]

pipe =  Pipeline(steps=[("kbest", SelectKBest()), ("classify",  DecisionTreeClassifier())]) #I put DT as default, but eventually the program will ignore this when you use GridSearchCV.

# Here the might of GridSearchCV working, this may takes time especially if you have more than one classifiers to be evaluated
grid = GridSearchCV(pipe, param_grid=param_grid, cv=10, scoring='f1')
grid.fit(features, labels)

#Find your best params if you want to use optimal setting later without running the grid search again (by commenting all these grid search lines)
print grid.best_params_

#You can now use pipeline again to wrap the steps with it best configs to build your model
pipe =  Pipeline(steps=[("kbest", SelectKBest(k=12)), ("classify",  DecisionTreeClassifier(criterion="entropy", min_samples_leaf=2, min_samples_split=9))])

希望对你有帮助

【讨论】:

我在这里用细节实现了它,但我仍然对使用网格搜索应用管道感到困惑。 (***.com/questions/48730921/…)【参考方案2】:

我的程序流程分为两个阶段。

我正在使用 Sklearn ExtraTreesClassifierSelectFromModel 方法来选择最重要的功能。这里需要注意的是,ExtraTreesClassifier 将许多参数作为输入,如n_estimators 等用于分类,并最终通过SelectFromModeln_estimators 的不同值提供不同的重要特征集。这意味着我可以优化n_estimators 以获得最佳功能。

在第二阶段,我正在根据第一阶段选择的特征训练我的 NN keras 模型。我使用 AUROC 作为网格搜索的分数,但这个 AUROC 是使用基于 Keras 的神经网络计算的。我想在我的ExtraTreesClassifier 中使用n_estimators 的网格搜索来优化keras 神经网络的AUROC。我知道我必须使用 Pipline,但我对同时实现两者感到困惑。

我不知道在我的代码中将 Pipeline 放在哪里。我收到一条错误消息,上面写着TypeError: estimator should be an estimator implementing 'fit' method, <function fs at 0x0000023A12974598> was passed

#################################################################################
I concatenate the CV set and the train set so that I may select the most important features  
in both CV and Train together.
##############################################################################

frames11 = [train_x_upsampled, cross_val_x_upsampled]
train_cv_x = pd.concat(frames11)
frames22 = [train_y_upsampled, cross_val_y_upsampled]
train_cv_y = pd.concat(frames22)


def fs(n_estimators):
  m = ExtraTreesClassifier(n_estimators = tree_number)
  m.fit(train_cv_x,train_cv_y)
  sel = SelectFromModel(m, prefit=True)


  ##################################################
  The code below is to get the names of the selected important features
  ###################################################

  feature_idx = sel.get_support()
  feature_name = train_cv_x.columns[feature_idx]
  feature_name =pd.DataFrame(feature_name)

  X_new = sel.transform(train_cv_x)
  X_new =pd.DataFrame(X_new)

 ######################################################################
 So Now the important features selected are in the data-frame X_new. In 
 code below, I am again dividing the data into train and CV but this time 
 only with the important features selected.
 #################################################################### 

  train_selected_x = X_new.iloc[0:train_x_upsampled.shape[0], :]
  cv_selected_x = X_new.iloc[train_x_upsampled.shape[0]:train_x_upsampled.shape[0]+cross_val_x_upsampled.shape[0], :]

  train_selected_y = train_cv_y.iloc[0:train_x_upsampled.shape[0], :]
  cv_selected_y = train_cv_y.iloc[train_x_upsampled.shape[0]:train_x_upsampled.shape[0]+cross_val_x_upsampled.shape[0], :]

  train_selected_x=train_selected_x.values
  cv_selected_x=cv_selected_x.values
  train_selected_y=train_selected_y.values
  cv_selected_y=cv_selected_y.values

  ##############################################################
  Now with this new data which only contains the important features,
  I am training a neural network as below.
  #########################################################
  def create_model():
     n_x_new=train_selected_x.shape[1]

     model = Sequential()
     model.add(Dense(n_x_new, input_dim=n_x_new, kernel_initializer='glorot_normal', activation='relu'))
     model.add(Dense(10, kernel_initializer='glorot_normal', activation='relu'))
     model.add(Dropout(0.8))

     model.add(Dense(1, kernel_initializer='glorot_normal', activation='sigmoid'))
     optimizer = keras.optimizers.Adam(lr=0.001)


     model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])

  seed = 7
  np.random.seed(seed)

model = KerasClassifier(build_fn=create_model, epochs=20, batch_size=400, verbose=0)

n_estimators=[10,20,30]
param_grid = dict(n_estimators=n_estimators)

grid = GridSearchCV(estimator=fs, param_grid=param_grid,scoring='roc_auc',cv = PredefinedSplit(test_fold=my_test_fold), n_jobs=1)
grid_result = grid.fit(np.concatenate((train_selected_x, cv_selected_x), axis=0), np.concatenate((train_selected_y, cv_selected_y), axis=0))

【讨论】:

以上是关于优化最佳特征的数量的主要内容,如果未能解决你的问题,请参考以下文章

Sklearn k-means聚类(加权),确定每个特征的最佳样本权重?

推荐系统中稀疏特征Embedding的优化表示方法

基于特征匹配和迭代优化的航拍图像拼接

如何使用 SelectKBest 选择的特征训练模型?

人脸人脸特征点检测

机器学习基础知识-持续更新