2

我使用Python 2.7和scikit-learn来做一些机器学习。我正在使用gridsearch来确定我的数据集和随机森林分类器的最佳超参数。我使用ROC曲线下的留一交叉验证和面积作为评估每个超参数集的度量。我的代码运行,但我有点困惑clf.grid_scores_的输出。根据我的理解,应该在所有数据折叠中对每组超参数进行评估,以查看使用在所有其他折叠上训练过的模型预测剩余折叠的效果。这会给你一个AUROC的每一个折叠。然后,Gridsearch应报告每组超参数的所有折叠的均值和标准差。使用.grid_scores_,我们可以查看每组超参数的auroc的均值,stddev和原始值。在scikit-learn中交叉验证评分的平均值,stddev GridSearchCV

我的问题是为什么交叉验证分数的报告平均值和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? (第二种意思是类似的分歧?)我觉得我错过了一些重要的东西,这会帮助我找到最好的hyperparams集或sklearn中的一个bug。

回答

3

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

this_score *= this_n_test_samples 
n_test_samples += this_n_test_samples 

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