python - 评估 scikit-learn GridSearchCV 中交叉验证分数的平均值和标准差

标签 python machine-learning scikit-learn random-forest cross-validation

我正在使用 Python 2.7 和 scikit-learn 进行一些机器学习。我正在使用网格搜索来确定我的数据集和随机森林分类器的最佳超参数。我使用留一法交叉验证和 ROC 曲线下面积作为评估每组超参数的指标。我的代码运行了,但我对 clf.grid_scores_ 的输出有点困惑。据我了解,应在所有数据折叠中评估每组超参数,以了解使用在所有其他折叠上训练的模型预测遗漏折叠的效果如何。这将为您提供每次折叠的 AUROC。然后,Gridsearch 应报告每组超参数的所有折叠的平均值和标准差。然后,使用 .grid_scores_ 我们可以查看每组超参数的 auroc 平均值、stddev 和原始值。

我的问题是,为什么报告的交叉验证分数平均值和标准偏差并不等于实际在所有折叠中取报告的 auroc 值的 .mean() 和 .std() ?

代码:

from sklearn import cross_validation, grid_search
from sklearn.ensemble import RandomForestClassifier

lol = cross_validation.LeaveOneLabelOut(group_labels)
rf = RandomForestClassifier(random_state=42, n_jobs=96)

parameters = {'min_samples_leaf':[500,1000],
              'n_estimators': [100],
              'criterion': ['entropy',],
              'max_features': ['sqrt']
             }

clf = grid_search.GridSearchCV(rf, parameters, scoring='roc_auc', cv=lol)
clf.fit(train_features, train_labels)

for params, mean_score, scores in clf.grid_scores_:
    print("%0.3f (+/-%0.3f) for %r" % (scores.mean(), scores.std(), params))
print

for g in clf.grid_scores_: print g
print

print clf.best_score_
print clf.best_estimator_

输出:

0.603 (+/-0.108) for {'max_features': 'sqrt', 'n_estimators': 100, 'criterion': 'entropy', 'min_samples_leaf': 500}
0.601 (+/-0.108) for {'max_features': 'sqrt', 'n_estimators': 100, 'criterion': 'entropy', 'min_samples_leaf': 1000}

mean: 0.60004, std: 0.10774, params: {'max_features': 'sqrt', 'n_estimators': 100, 'criterion': 'entropy', 'min_samples_leaf': 500}
mean: 0.59705, std: 0.10821, params: {'max_features': 'sqrt', 'n_estimators': 100, 'criterion': 'entropy', 'min_samples_leaf': 1000}

0.600042993354
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='entropy',
            max_depth=None, max_features='sqrt', max_leaf_nodes=None,
            min_samples_leaf=500, min_samples_split=2,
            min_weight_fraction_leaf=0.0, n_estimators=100, n_jobs=96,
            oob_score=False, random_state=42, verbose=0, warm_start=False)

为什么我将第一个分类器的平均值计算为 0.603,而 gridsearch 报告为 0.60004? (对于第二个平均值也有类似的分歧?)我觉得要么我错过了一些重要的东西,可以帮助我找到最好的超参数集,要么 sklearn 中存在错误。

最佳答案

一开始我也很困惑,所以我看了看source code 。这两行将阐明如何计算交叉验证误差:

this_score *= this_n_test_samples 
n_test_samples += this_n_test_samples

当网格搜索计算平均值时,它是加权平均值。您的 LeaveOneLabelOut CV 很可能不平衡,即每个标签的样本数量不同。要计算平均验证分数,您需要将每个分数乘以该折叠包含的总样本的比例,然后将所有分数相加。

关于python - 评估 scikit-learn GridSearchCV 中交叉验证分数的平均值和标准差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35706433/

相关文章:

python - 在 python 中创建列表中项目频率图

python - 处理正则表达式组中的字符串后替换所有出现的正则表达式组

python - 如何将 tanh 添加到 keras 中的一个嵌入层

machine-learning - Keras 中 LSTM 输入维度的问题

algorithm - 监督机器学习,产生训练有素的估计器

python - NN 的 DNA 数据输入,一种热编码

python - 通过将不同数据帧中具有相同索引的两列相乘来添加新列

python - GNU Radio (Companion) 在变量替换时给出 Python 语法错误

python - train_test_split 在分层数据上无法按预期工作

python - scikit-learn GaussianProcessRegressor vs GaussianProcess?为什么 GaussianProcess 在 0.18 版本中被弃用?