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-validating
比train_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-Learn GridSearchCV 与 PredefinedSplit 进行交叉验证 - 可疑的交叉验证结果
R语言构建xgboost模型:xgb.cv函数交叉验证确定模型的最优子树个数(可视化交叉验证对数损失函数与xgboost模型子树个数的关系)交叉验证获取最优子树之后构建最优xgboost模型