GridSearchCV分数结果是否应该等于使用相同输入的cross_validate分数?

时间:2019-07-03 20:16:03

标签: python machine-learning scikit-learn cross-validation grid-search

我正在玩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

我希望这些分数是完全相同的,因为它们是使用相同的分类器使用相同的训练数据在相同的划分上进行计算的。

1 个答案:

答案 0 :(得分:0)

这是因为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