我正在尝试一下 scikit-learn,并希望为所执行的网格搜索的一个特定超参数组合重现交叉验证分数。
对于网格搜索,我使用了 GridSearchCV
类,并为一个特定的超参数组合重现结果,我使用了 cross_validate
函数,该函数具有完全相同的分割和分类器设置。
我的问题是我没有得到预期的分数结果,据我了解,这应该与在两种方法中执行相同的计算以获得分数完全相同。
我通过修复训练数据上使用的分割来确保从脚本中排除任何随机源。
在下面的代码片段中,给出了所述问题的示例。
import numpy as np
from sklearn.model_selection import cross_validate, StratifiedKFold, GridSearchCV
from sklearn.svm import NuSVC
np.random.seed(2018)
# generate random training features
X = np.random.random((100, 10))
# class labels
y = np.random.randint(2, size=100)
clf = NuSVC(nu=0.4, gamma='auto')
# Compute score for one parameter combination
grid = GridSearchCV(clf,
cv=StratifiedKFold(n_splits=10, random_state=2018),
param_grid={'nu': [0.4]},
scoring=['f1_macro'],
refit=False)
grid.fit(X, y)
print(grid.cv_results_['mean_test_f1_macro'][0])
# Recompute score for exact same input
result = cross_validate(clf,
X,
y,
cv=StratifiedKFold(n_splits=10, random_state=2018),
scoring=['f1_macro'])
print(result['test_f1_macro'].mean())
执行给定的代码片段会产生输出:
0.38414468864468865
0.3848840048840049
我本以为这些分数是完全相同的,因为它们是在同一分割上计算的,使用相同的训练数据和相同的分类器。
最佳答案
这是因为mean_test_f1_macro
不是所有折叠组合的简单平均值,它是一个权重平均值,权重是测试折叠的大小。要了解更多实际执行情况请引用this回答。
现在,要复制 GridSearchCV
结果,请尝试此操作!
print('grid search cv result',grid.cv_results_['mean_test_f1_macro'][0])
# grid search cv result 0.38414468864468865
print('simple mean: ', result['test_f1_macro'].mean())
# simple mean: 0.3848840048840049
weights= [len(test) for (_, test) in StratifiedKFold(n_splits=10, random_state=2018).split(X,y)]
print('weighted mean: {}'.format(np.average(result['test_f1_macro'], axis=0, weights=weights)))
# weighted mean: 0.38414468864468865
关于python - GridSearchCV 分数结果是否应该等于使用相同输入的 cross_validate 分数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56877358/