KFolds 交叉验证与 train_test_split

Posted

技术标签:

【中文标题】KFolds 交叉验证与 train_test_split【英文标题】:KFolds Cross Validation vs train_test_split 【发布时间】:2018-08-14 12:25:32 【问题描述】:

我今天刚刚构建了我的第一个random forest classifier,我正在努力提高它的性能。我正在阅读cross-validation 对避免overfitting 数据的重要性,从而获得更好的结果。我使用sklearn 实现了StratifiedKFold,然而,令人惊讶的是,这种方法导致不太准确。我读过很多帖子表明cross-validatingtrain_test_split 效率更高。

估算器:

rf = RandomForestClassifier(n_estimators=100, random_state=42)

K 折:

ss = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
for train_index, test_index in ss.split(features, labels):
    train_features, test_features = features[train_index], features[test_index]
    train_labels, test_labels = labels[train_index], labels[test_index]

TTS:

train_feature, test_feature, train_label, test_label = \
    train_test_split(features, labels, train_size=0.8, test_size=0.2, random_state=42)

以下是结果:

简历:

AUROC:  0.74
Accuracy Score:  74.74 %.
Specificity:  0.69
Precision:  0.75
Sensitivity:  0.79
Matthews correlation coefficient (MCC):  0.49
F1 Score:  0.77

TTS:

AUROC:  0.76
Accuracy Score:  76.23 %.
Specificity:  0.77
Precision:  0.79
Sensitivity:  0.76
Matthews correlation coefficient (MCC):  0.52
F1 Score:  0.77

这真的可能吗?还是我错误地设置了模型?

另外,这是使用交叉验证的正确方法吗?

【问题讨论】:

【参考方案1】:

很高兴看到您记录了自己!

造成这种差异的原因是 TTS 方法引入了偏差(因为您没有使用所有观察结果进行测试)这解释了差异。

在验证方法中,只有观察的一个子集——那些 包含在训练集中而不是在验证中 set——用于拟合模型。由于统计方法倾向于执行 更糟糕的是,当对较少的观察进行训练时,这表明 验证集错误率可能倾向于高估测试错误率 模型适合整个数据集。

结果可能会有很大差异:

验证估计 的测试错误率可以是高度可变的,具体取决于 哪些观察包含在训练集中,哪些 观察结果包含在验证集中

交叉验证通过使用所有可用数据来解决这个问题,从而消除偏差。

在这里,您对 TTS 方法的结果存在更多偏差,在分析结果时应牢记这一点。也许您在抽样的测试/验证集上也很幸运

再次,通过一篇很棒的、适合初学者的文章了解更多关于该主题的信息: https://codesachin.wordpress.com/2015/08/30/cross-validation-and-the-bias-variance-tradeoff-for-dummies/

如需更深入的资料,请参阅“模型评估与选择” 此处的章节(引用内容的来源):

https://web.stanford.edu/~hastie/Papers/ESLII.pdf

【讨论】:

再次感谢您的帮助!所以基本上,在确保获得的结果中没有统计偏差(或较低偏差)的意义上,使用交叉验证更好?而且,这是使用交叉验证技术的正确方法吗? 也感谢您的参考。 通过使用 CV,您可以确保测试错误没有偏差,并降低结果的可变性。至于我使用 R 的代码,所以我不完全确定,但这似乎还不错 嗨,我刚刚读到,为了避免过度拟合,你应该减少方差并增加偏差。这是否意味着 TTS 会成为首选? 是的,您将数据拆分为 K 个等于集合,然后在 K-1 个集合上进行训练并在剩余集合上进行测试。您这样做 K 次,每次更改测试集,以便最终每组将成为测试集一次和训练集 K-1 次。然后对 K 个结果进行平均以获得 K-Fold CV 结果【参考方案2】:

交叉验证倾向于对数据中的选择偏差进行校正。所以,例如如果您专注于 AUC 指标并在 TTS 方法中获得较低的 AUC 分数,则意味着您的 TTS 存在偏差。

您可能需要进行分析以找出这种偏差(例如,您可以更多地关注日期特征(确保您不使用未来来预测过去)或尝试在与业务逻辑)

总的来说,在我看来,分数的差异并没有那么大而值得担心。所以,代码看起来还可以,这样的分数差异是可能的。

顺便说一句,您没有描述问题/数据,但是您使用了 Stratified KFold CV,所以我假设您有一个不平衡的数据集,但如果没有,序数 KFold CV 可能值得一试。在您的 TTS 中,您没有实现类平衡,但它是由 Stratified CV 完成的

【讨论】:

以上是关于KFolds 交叉验证与 train_test_split的主要内容,如果未能解决你的问题,请参考以下文章

Scikit - 结合规模和网格搜索

使用 Scikit-Learn GridSearchCV 与 PredefinedSplit 进行交叉验证 - 可疑的交叉验证结果

libsvm交叉验证与网格搜索(参数选择)

Sklearn 交叉验证产生与手动执行不同的结果

R语言构建xgboost模型:xgb.cv函数交叉验证确定模型的最优子树个数(可视化交叉验证对数损失函数与xgboost模型子树个数的关系)交叉验证获取最优子树之后构建最优xgboost模型

libsvm 交叉验证与 matlab 中的预计算内核