cv_result 中的“mean_test_score”是啥意思?

Posted

技术标签:

【中文标题】cv_result 中的“mean_test_score”是啥意思?【英文标题】:What is the meaning of 'mean_test_score' in cv_result?cv_result 中的“mean_test_score”是什么意思? 【发布时间】:2017-12-10 09:10:35 【问题描述】:

您好,我正在执行 GridSearchCV,我正在使用来自 scikit learn.cv_results_ 函数打印结果。

我的问题是,当我手动评估所有测试分数的平均值时,我得到的数字与'mean_test_score' 中写的数字不同。与标准的np.mean() 有什么不同?

我在这里附上结果代码:

n_estimators = [100]
max_depth = [3]
learning_rate = [0.1]

param_grid = dict(max_depth=max_depth, n_estimators=n_estimators, learning_rate=learning_rate)

gkf = GroupKFold(n_splits=7)


grid_search = GridSearchCV(model, param_grid, scoring=score_auc, cv=gkf)
grid_result = grid_search.fit(X, Y, groups=patients)

grid_result.cv_results_

这个操作的结果是:

'mean_fit_time': array([ 8.92773601]),
 'mean_score_time': array([ 0.04288721]),
 'mean_test_score': array([ 0.83490629]),
 'mean_train_score': array([ 0.95167036]),
 'param_learning_rate': masked_array(data = [0.1],
              mask = [False],
        fill_value = ?),
 'param_max_depth': masked_array(data = [3],
              mask = [False],
        fill_value = ?),
 'param_n_estimators': masked_array(data = [100],
              mask = [False],
        fill_value = ?),
 'params': ('learning_rate': 0.1, 'max_depth': 3, 'n_estimators': 100,),
 'rank_test_score': array([1]),
 'split0_test_score': array([ 0.74821666]),
 'split0_train_score': array([ 0.97564995]),
 'split1_test_score': array([ 0.80089016]),
 'split1_train_score': array([ 0.95361201]),
 'split2_test_score': array([ 0.92876979]),
 'split2_train_score': array([ 0.93935856]),
 'split3_test_score': array([ 0.95540287]),
 'split3_train_score': array([ 0.94718634]),
 'split4_test_score': array([ 0.89083901]),
 'split4_train_score': array([ 0.94787374]),
 'split5_test_score': array([ 0.90926355]),
 'split5_train_score': array([ 0.94829775]),
 'split6_test_score': array([ 0.82520379]),
 'split6_train_score': array([ 0.94971417]),
 'std_fit_time': array([ 1.79167576]),
 'std_score_time': array([ 0.02970254]),
 'std_test_score': array([ 0.0809713]),
 'std_train_score': array([ 0.0105566])

如您所见,对所有 test_score 执行 np.mean 后,您的值大约为 0.8655122606479532,而“mean_test_score”为 0.83490629

感谢您的帮助, 莱昂纳多。

【问题讨论】:

数组不都是'split0_test_score', 'split1_test_score'..等等吗? 我猜scoring=score_auc 是您提供的自定义评分函数,因为它不是允许的值之一。是否加权? 这是样本 score_auc 评估 def score_auc(estimator, X, y): probas = estimator.predict_proba(X) fpr, tpr, thresholds = roc_curve(y, probas[:, 0], pos_label= 1) 返回 auc(fpr, tpr) 你能打印出折叠的大小吗?运行print([(len(train), len(test)) for train, test in gkf.split(X, groups=patients)]) 当然可以! [(41835, 24377), (56229, 9983), (56581, 9631), (58759, 7453), (60893, 5319), (60919, 5293), (62056, 4156)] 【参考方案1】:

由于代码太多,我会将其作为新答案发布:

折叠的测试和训练分数是:(取自您在问题中发布的结果)

test_scores = [0.74821666,0.80089016,0.92876979,0.95540287,0.89083901,0.90926355,0.82520379]
train_scores = [0.97564995,0.95361201,0.93935856,0.94718634,0.94787374,0.94829775,0.94971417]

这些折叠中的训练样本数量为:(取自print([(len(train), len(test)) for train, test in gkf.split(X, groups=patients)])的输出)

train_len = [41835, 56229, 56581, 58759, 60893, 60919, 62056]
test_len = [24377, 9983, 9631, 7453, 5319, 5293, 4156]

那么以每倍训练样本量作为权重的测试和训练均值是:

train_avg = np.average(train_scores, weights=train_len)
-> 0.95064898361714389
test_avg = np.average(test_scores, weights=test_len)
-> 0.83490628649308296

这正是 sklearn 为您提供的价值。它也是您分类的正确平均准确度。折叠的平均值是不正确的,因为它取决于您选择的有些随意的分割/折叠。

所以在脑震荡中,两种解释确实是相同且正确的。

【讨论】:

【参考方案2】:

如果您在他们的 github 存储库中看到 GridSearchCV 的原始代码,他们不会使用 np.mean(),而是使用带有权重的 np.average()。因此差异。这是他们的代码:

n_splits = 3
test_sample_counts = np.array(test_sample_counts[:n_splits],
                                    dtype=np.int)
weights = test_sample_counts if self.iid else None
means = np.average(test_scores, axis=1, weights=weights)
stds = np.sqrt(np.average((test_scores - means[:, np.newaxis]) 
                               axis=1, weights=weights))

 cv_results = dict()
 for split_i in range(n_splits):
        cv_results["split%d_test_score" % split_i] = test_scores[:,
                                                              split_i]
 cv_results["mean_test_score"] = means        
 cv_results["std_test_score"] = stds

如果您想了解更多关于它们之间的区别,请查看 Difference between np.mean() and np.average()

【讨论】:

确实如此,但在提供的示例中 np.averagenp.mean 给出了相同的结果。 他们使用权重参数。 是的,这就是这里的区别。 据我了解,权重参数是特定折叠/拆分中的样本数。所以我想这和我的回答有相同的解释? @Johannes 我相信是这样的!也为您的答案+1。由于不同的原因,这两个答案实际上都有助于这个问题。【参考方案3】:

我认为不同均值的原因是均值计算中的加权因子不同。

sklearn 返回的mean_test_score 是在每个样本具有相同权重的所有样本上计算的平均值。

如果您通过取折叠(拆分)的平均值来计算平均值,那么只有当所有折叠的大小相同时,您才会得到相同的结果。如果不是,则所有较大折叠的样本对折叠均值的影响将自动小于较小折叠的影响,反之亦然。

小数字示例:

mean([2,3,5,8,9]) = 5.4 # mean over all samples ('mean_test_score')

mean([2,3,5]) = 3.333 # mean of fold 1
mean([8,9]) = 8.5 # mean of fold 2

mean(3.333, 8.5) = 5.91 # mean of means of folds

5.4 != 5.91

【讨论】:

以上是关于cv_result 中的“mean_test_score”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

什么是 Gridsearch.cv_results_ ,可以解释其中的所有内容,即 mean_test_score 等吗?

什么取代了 scikit 中的 GridSearchCV._grid_scores_?

GridSearchCV 如何计算训练分数?

GridSearchCV - 每次迭代保存结果

sklearn RandomizedSearchCV 提取不同折叠的混淆矩阵

如何使用GridSearchCV获取所有模型(每组参数一个)?