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很可能不平衡,即每個標籤的樣本數量不同。要計算平均驗證分數,您需要將每個分數乘以摺疊包含的總樣本的比例,然後將所有分數相加。