cross_val_score 和 StratifiedKFold 之间的 F-Score 差异

Posted

技术标签:

【中文标题】cross_val_score 和 StratifiedKFold 之间的 F-Score 差异【英文标题】:F-Score difference between cross_val_score and StratifiedKFold 【发布时间】:2020-06-01 22:03:27 【问题描述】:

我想对不平衡数据使用随机森林分类器,其中 X 是表示特征的 np.array,y 是表示标签的 np.array(标签具有 90% 的 0 值和 10% 的 1 值) .由于我不确定如何在交叉验证中进行分层,如果它有所作为,我还使用 StratifiedKFold 手动交叉验证。我希望得到不一样但有些相似的结果。由于情况并非如此,我想我错误地使用了一种方法,但我不明白是哪一种。这是代码

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.metrics import f1_score

rfc = RandomForestClassifier(n_estimators = 200,
                             criterion = "gini",
                             max_depth = None, 
                             min_samples_leaf = 1, 
                             max_features = "auto", 
                             random_state = 42,
                             class_weight = "balanced")

X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size = 0.20, random_state = 42, stratify=y)

我还尝试了没有 class_weight 参数的分类器。从这里我开始将这两种方法与 f1-score 进行比较

cv = cross_val_score(estimator=rfc,
                     X=X_train_val,
                     y=y_train_val,
                     cv=10,
                     scoring="f1")
print(cv)

交叉验证的 10 个 f1 分数都在 65% 左右。 现在是 StratifiedKFold:

skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=42) 
for train_index, test_index in skf.split(X_train_val, y_train_val):
    X_train, X_val = X_train_val[train_index], X_train_val[test_index]
    y_train, y_val = y_train_val[train_index], y_train_val[test_index]
    rfc.fit(X_train, y_train)
    rfc_predictions = rfc.predict(X_val)
    print("F1-Score: ", round(f1_score(y_val, rfc_predictions),3))

StratifiedKFold 的 10 个 f1 分数让我的值达到了 90% 左右。这是我感到困惑的地方,因为我不了解两种方法之间的巨大差异。如果我只是将分类器拟合到训练数据并将其应用于测试数据,我也会得到大约 90% 的 f1 分数,这让我相信我应用 cross_val_score 的方式是不正确的。

【问题讨论】:

【参考方案1】:

造成这种差异的一个可能原因是cross_val_score 使用StratifiedKFold 和默认的shuffle=False 参数,而在使用StratifiedKFold 的手动交叉验证中,您已经传递了shuffle=True。因此,没有改组的交叉验证会产生更差的 F1 分数,这可能只是您的数据排序方式的产物。

尝试在创建skf 实例时传递shuffle=False 以查看分数是否与cross_val_score 匹配,然后如果您想在使用cross_val_score 时使用洗牌,只需在应用cross_val_score 之前手动洗牌训练数据.

【讨论】:

以上是关于cross_val_score 和 StratifiedKFold 之间的 F-Score 差异的主要内容,如果未能解决你的问题,请参考以下文章

cross_val_score 和 gridsearchCV 是如何工作的?

使用 cross_val_score 和 StackingClassifier 或投票分类器获取“nan”

使用 cross_val_score 评估多项式回归

为啥 xgboost.cv 和 sklearn.cross_val_score 给出不同的结果?

使用 Cross_Val_score 的原因

评分='roc_auc' 的 cross_val_score 和 roc_auc_score 有啥区别?