GridSearchCV 不包含原始数据(如果包含,那将是荒谬的)。它包含的唯一数据是它自己的簿记,即每个 CV 折叠尝试的详细分数和参数。返回的best_estimator_ 是将模型应用于遇到的任何新数据所需的唯一内容,但如果如您所说,您想更深入地挖掘细节,完整的结果将在其cv_results_ 属性中返回。
用你自己的knn_parameters网格将documentation的例子改成knn分类器(但是去掉n_jobs,这只会影响拟合速度,并不是算法的真正超参数),并保持@ 987654326@ 为简单起见,我们有:
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV
import pandas as pd
iris = 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 会导致快得多 的CV 过程。不过,如果您想在最终模型中使用 n_jobs=-1,您可以轻松地操作 best_estimator_ 来实现:
clf.best_estimator_.n_jobs = -1
clf.best_estimator_
# result
KNeighborsClassifier(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 481
1 481
2 145
3 145
4 1
...
571 1
572 145
573 145
574 433
575 1
Name: rank_test_score, Length: 576, dtype: int32
这里1 表示最佳,您可以很容易地看到有多个组合被列为1 - 所以实际上这里我们有多个“最佳”模型(即参数组合)!虽然这很可能是由于使用的 iris 数据集相对简单,但原则上没有理由在真实案例中也不会发生这种情况。在这种情况下,返回的 best_estimator_ 只是这些事件中的第一个 - 这里是组合编号 4:
cv_results.iloc[4]
# result:
mean_fit_time 0.000669559
std_fit_time 1.55811e-05
mean_score_time 0.00474652
std_score_time 0.000488042
param_algorithm auto
param_leaf_size 5
param_n_neighbors 5
param_weights uniform
params {'algorithm': 'auto', 'leaf_size': 5, 'n_neigh...
split0_test_score 0.98
split1_test_score 0.98
split2_test_score 0.98
mean_test_score 0.98
std_test_score 0
rank_test_score 1
Name: 4, dtype: object
您可以很容易地看到它与我们上面的best_estimator_ 具有相同的参数。但现在您可以检查所有“最佳”模型,只需:
cv_results.loc[cv_results['rank_test_score']==1]
在我的情况下,产生不少于 144 个模型(在尝试的 6*12*4*2 = 576 个模型总数中)!因此,您实际上可以在更多选项中进行选择,甚至可以使用其他附加标准,例如返回分数的标准差(越小越好,尽管这里它的最小值为 0),而不是简单地依赖于最大平均分,这是自动程序将返回的值。
希望这些足以让你开始......