具有PredefinedSplit评分的Sklearn GridSearch与独立分类器不匹配

时间:2019-03-27 07:43:12

标签: python validation scikit-learn grid-search scoring

我正在使用sklearn GridSearch使用预定义的验证集为随机森林分类找到最佳参数。 GridSearch返回的最佳估计器得出的分数与通过训练具有相同参数的单独分类器获得的分数不匹配。

数据拆分定义

X = pd.concat([X_train, X_devel])
y = pd.concat([y_train, y_devel])
test_fold = -X.index.str.contains('train').astype(int)
ps = PredefinedSplit(test_fold)

GridSearch定义

n_estimators = [10]
max_depth = [4]
grid = {'n_estimators': n_estimators, 'max_depth': max_depth}

rf = RandomForestClassifier(random_state=0)
rf_grid = GridSearchCV(estimator = rf, param_grid = grid, cv = ps, scoring='recall_macro')
rf_grid.fit(X, y)

分类器定义

clf = RandomForestClassifier(n_estimators=10, max_depth=4, random_state=0)
clf.fit(X_train, y_train)

召回是使用sklearn.metrics.recall_score明确计算的

y_pred_train = clf.predict(X_train)
y_pred_devel = clf.predict(X_devel)

uar_train = recall_score(y_pred_train, y_train, average='macro')
uar_devel = recall_score(y_pred_devel, y_devel, average='macro')

GridSearch

uar train:  0.32189884516029466
uar devel:  0.3328299259976279

随机森林:

uar train:  0.483040291148839
uar devel:  0.40706644557392435

这种不匹配的原因是什么?

2 个答案:

答案 0 :(得分:2)

这里有多个问题:

  1. 您对recall_score的输入自变量被反转。实际正确的顺序是:

    recall_score(y_true, y_test)
    

    但是您正在这样做:

    recall_score(y_pred_train, y_train, average='macro')
    

    将其更正为:

    recall_score(y_train, y_pred_train, average='macro')
    
  2. 您正在rf_grid.fit(X, y)进行网格搜索。这意味着在找到最佳参数组合之后,GridSearchCV将适合整个数据(整个X,忽略PredefinedSplit,因为它仅在交叉验证中用于搜索最佳参数时使用)。因此,从本质上讲,GridSearchCV的估算器将看到整个数据,因此分数与您进行clf.fit(X_train, y_train)

  3. 时得到的分数不同

答案 1 :(得分:0)

这是因为在您的GridSearchCV中,您使用的得分函数为recall-macro,该函数基本上会返回recall score的平均值。参见this link

但是,当您从macro返回默认分数时,它将返回RandomForestClassifier。因此,这就是分数不同的原因。有关详情,请参见this link。 (因为一个是召回,另一个是准确性)。