使用 Sklearn 进行蛮力模型选择

Posted

技术标签:

【中文标题】使用 Sklearn 进行蛮力模型选择【英文标题】:Brute force model selection with Sklearn 【发布时间】:2020-12-16 06:42:24 【问题描述】:

我有一个用于分类任务(3 个类别)的特征矩阵 (X_train_balanced) 和一个目标向量 (y_train_balanced)。为了执行模型选择和超参数调整,我打算在我想要比较的每个模型(LR、SVC、RF 和 KNN)上使用 sklearn 的 GridsearchCV。

然后我的想法是比较 GridsearchCV 产生的每个模型的最佳结果,以选择最佳模型。

我想知道这种方法是否有意义,以及我为该任务开发的代码是否正确。

模型搜索空间

models = 
        'LogisticRegression'     : LogisticRegression(),
        'SVM'                    : SVC(),
        'RandomForestClassifier' : RandomForestClassifier(),
        'KNN'                    : KNeighborsClassifier()

超参数搜索空间

hyper = 
        
        'LogisticRegression':
                                    'penalty'     : ['l2'],
                                    'C'           : np.logspace(0, 4, 10),
                                    'solver'      : ['lbfgs', 'liblinear', 'saga'],
                                    'class_weight': ['balanced'],
                                    'random_state': [0],
        
        'SVM':
                                    'C'           : [0.01, 0.1, 1, 10, 100, 1000],
                                    'gamma'       : [1, 0.1, 0.01, 0.001, 0.0001],
                                    'kernel'      : ['rbf', 'linear'],
                                    'class_weight': ['balanced'],
                                    'random_state': [0],
        
        'RandomForestClassifier':
                                    'max_depth': [2, 3, 4],
                                    'max_features': [2, 3, 4, 'auto', 'sqrt'],
                                    'n_estimators': [10, 100, 500, 1000],
                                    'class_weight': ['balanced'],
                                    'random_state': [0],
       
        'KNN':
                                    'n_neighbors': [5, 10, 15, 20],
                                    'weights': ['uniform', 'distance']
                              
                              
    

对每个模型执行交叉验证

for model_name in models.keys():

  # Model selection
  clf    = models[model_name]
  params = hyper[model_name]

  # Pipeline (standarization + classifier)
  pipe = Pipeline([ ( 'scaler', StandardScaler() ), ( 'clf', clf ) ])
 
  # Gridsearch cross-validation
  grid = GridSearchCV(estimator = clf, param_grid = params, cv = 5, return_train_score = True)
  grid.fit(X_train_balanced, y_train_balanced)

  # Gridsearch cross-validation results
  best_param                  = grid.best_params_
  best_param_test_score_mean  = grid.cv_results_['mean_test_score'][grid.best_index_]
  best_param_test_score_std   = grid.cv_results_['std_test_score'][grid.best_index_]
  best_param_train_score_mean = grid.cv_results_['mean_train_score'][grid.best_index_]
  best_param_train_score_std  = grid.cv_results_['std_train_score'][grid.best_index_]

【问题讨论】:

【参考方案1】:

只要您有所需的导入,您的代码就可以工作:

from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline

我会说这也是有道理的。

在代码的末尾,您可以添加行

print(best_param)
print(grid.best_estimator_)

以获得最佳参数和最佳性能估算器。我使用这些更改运行了您的代码,例如,我测试它的数据集的输出是:

'n_neighbors': 15, 'weights': 'uniform'
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=15, p=2,
                     weights='uniform')

【讨论】:

嗨,Kim,感谢您的回答。关于你的最后一句话,如果我没记错的话,我应该运行代码然后使用grid.best_estimator_ 模型,但是,这个模型对我来说将与你得到的不同,因为我们考虑了不同的数据集。对吗? 哦,是的,您可能会有不同的型号。我只是使用了一些数据集来测试 sklearn 的代码。你是对的。

以上是关于使用 Sklearn 进行蛮力模型选择的主要内容,如果未能解决你的问题,请参考以下文章

sklearn特征选择和分类模型

sklearn中的模型选择和分层抽样

如何使用 sklearn Pipeline 和 FeatureUnion 选择多个(数字和文本)列进行文本分类?

python进行机器学习之模型选择与构建

详解数据预处理和特征工程-特征选择-Embedded嵌入法菜菜的sklearn课堂笔记

sklearn出现错误(LogisticRegression模型选择)