从GridSearchCV中检索特定分类器和数据

我在服务器上运行了一个Python 3分类脚本,使用以下代码:

# define knn classifier for transformed dataknn_classifier = neighbors.KNeighborsClassifier()# define KNN parametersknn_parameters = [{    'n_neighbors': [1,3,5,7, 9, 11],    'leaf_size': [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],    'n_jobs': [-1],    'weights': ['uniform', 'distance']}]# Stratified k-fold (default for classifier)# n = 5 folds is defaultknn_models = GridSearchCV(estimator = knn_classifier, param_grid = knn_parameters, scoring = 'accuracy')# fit grid search models to transformed training dataknn_models.fit(X_train_transformed, y_train)

然后我使用pickle保存GridSearchCV对象:

# save modelwith open('knn_models.pickle', 'wb') as f:    pickle.dump(knn_models, f)

这样我就可以在本地机器上通过运行以下代码,在较小的数据集上测试分类器:

knn_models = pickle.load(open("knn_models.pickle", "rb"))validation_knn_model = knn_models.best_estimator_

如果我只想在验证集上评估最佳估计器,这很好。但我真正想做的是:

  • GridSearchCV对象中提取原始数据(我假设它存储在对象中的某个地方,因为要对新的验证集进行分类,这是必需的)
  • 尝试一些特定的分类器,使用网格搜索确定的几乎所有最佳参数,但更改一个特定的输入参数,即k = 3, 5, 7
  • 检索y_pred,即对上述测试的所有新分类器的每个验证集的预测

回答:

GridSearchCV不包括原始数据(如果包含的话,可能会显得荒谬)。它只包含自己的记录信息,即每个交叉验证折叠尝试的详细分数和参数。返回的best_estimator_是应用模型到任何新数据所需的唯一东西,但正如你所说,如果你想深入了解细节,其完整结果在cv_results_属性中返回。

根据文档中的示例,调整到knn分类器和你的knn_parameters网格(但移除n_jobs,它只影响拟合速度,不是算法的真正超参数),并保持cv=3以简化,我们有:

from sklearn.neighbors import KNeighborsClassifierfrom sklearn.datasets import load_irisfrom sklearn.model_selection import GridSearchCVimport pandas as pdiris = load_iris()knn_parameters = [{    'n_neighbors': [1,3,5,7, 9, 11],    'leaf_size': [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],    'weights': ['uniform', 'distance']}]knn_classifier = KNeighborsClassifier()clf = GridSearchCV(estimator = knn_classifier, param_grid = knn_parameters, scoring = 'accuracy', n_jobs=-1, cv=3)clf.fit(iris.data, iris.target)clf.best_estimator_# result:KNeighborsClassifier(algorithm='auto', leaf_size=5, metric='minkowski',                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,                     weights='uniform')

因此,正如所说,这个最后的结果告诉你所有你需要知道的,以便将算法应用到任何新数据(验证、测试、部署等)。此外,你可能会发现,实际上从knn_parameters网格中移除n_jobs条目,并在GridSearchCV对象中请求n_jobs=-1,会导致交叉验证过程快得多。尽管如此,如果你想在最终模型中使用n_jobs=-1,你可以轻松地操作best_estimator_来实现:

clf.best_estimator_.n_jobs = -1clf.best_estimator_# resultKNeighborsClassifier(algorithm='auto', leaf_size=5, metric='minkowski',                     metric_params=None, n_jobs=-1, n_neighbors=5, p=2,                     weights='uniform')

这实际上回答了你的第二个问题,因为你可以同样地操作best_estimator_来更改其他超参数。

所以,找到最佳模型是大多数人会停下来的地方。但如果出于任何原因,你想进一步深入了解整个网格搜索过程的细节,详细结果在cv_results_属性中返回,你甚至可以将其导入到pandas数据框中以便于检查:

cv_results = pd.DataFrame.from_dict(clf.cv_results_)

例如,cv_results数据框包括一个rank_test_score列,正如其名称明确暗示的,包含每个参数组合的排名:

cv_results['rank_test_score']# result:0      4811      4812      1453      1454        1      ... 571      1572    145573    145574    433575      1Name: rank_test_score, Length: 576, dtype: int32

这里1表示最佳,你可以清楚地看到有多个组合被排名为1 – 所以实际上我们有多个“最佳”模型(即参数组合)!虽然这里这很可能是由于使用的iris数据集相对简单,但在实际情况下没有理由不发生这种情况。在这种情况下,返回的best_estimator_只是这些情况中的第一个 – 这里是组合号4:

cv_results.iloc[4]# result:mean_fit_time                                              0.000669559std_fit_time                                               1.55811e-05mean_score_time                                             0.00474652std_score_time                                             0.000488042param_algorithm                                                   autoparam_leaf_size                                                      5param_n_neighbors                                                    5param_weights                                                  uniformparams               {'algorithm': 'auto', 'leaf_size': 5, 'n_neigh...split0_test_score                                                 0.98split1_test_score                                                 0.98split2_test_score                                                 0.98mean_test_score                                                   0.98std_test_score                                                       0rank_test_score                                                      1Name: 4, dtype: object

你可以轻易地看到它与我们上面的best_estimator_具有相同的参数。但现在你可以检查所有“最佳”模型,只需:

cv_results.loc[cv_results['rank_test_score']==1]

在我这里,结果至少有144个模型(在总共6*12*4*2 = 576个尝试的模型中)!所以,实际上你可以从更多选择中进行选择,或者甚至使用其他附加标准,比如返回分数的标准偏差(越小越好,尽管这里它是最小值0),而不是简单地依赖于最大平均分数,这是自动程序将返回的结果。

希望这些能让你开始…

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注