应该对原始数据还是拆分数据执行交叉验证分数?

Posted

技术标签:

【中文标题】应该对原始数据还是拆分数据执行交叉验证分数?【英文标题】:Should Cross Validation Score be performed on original or split data? 【发布时间】:2020-06-30 20:37:40 【问题描述】:

当我想通过交叉验证评估我的模型时,我应该对原始数据(在训练和测试中未拆分的数据)还是训练/测试数据执行交叉验证?

我知道训练数据用于拟合模型,测试用于评估。如果我使用交叉验证,我是否仍应将数据拆分为训练和测试?

features = df.iloc[:,4:-1]
results = df.iloc[:,-1]

x_train, x_test, y_train, y_test = train_test_split(features, results, test_size=0.3, random_state=0)

clf = LogisticRegression()
model = clf.fit(x_train, y_train)

accuracy_test = cross_val_score(clf, x_test, y_test, cv = 5)

或者我应该这样做:

features = df.iloc[:,4:-1]
results = df.iloc[:,-1]

clf = LogisticRegression()
model = clf.fit(features, results)

accuracy_test = cross_val_score(clf, features, results, cv = 5)), 2)

或者可能有什么不同?

【问题讨论】:

test 部分不应用于除最终评估之外的任何内容。顺便说一句,您的代码中有错误(在第一个块中)。您使用训练数据拟合clf,然后使用测试数据应用交叉验证。 这就是我的问题?哪个代码块更准确?我知道训练数据用于拟合模型,测试用于评估。如果我使用交叉验证,我是否仍应将数据拆分为训练和测试? 我已阅读此内容,但我的问题没有答案 不清楚你想做什么。无论如何,评估您的模型有两种通用方法,交叉验证和测试部分。你可以使用它们中的任何一个。在第一块中,您将两种方式混合在一起。 【参考方案1】:

我将在这里尝试总结“最佳实践”:

1) 如果您想训练模型、微调参数并进行最终评估,我建议您将数据拆分为training|val|test

您使用training 零件拟合您的模型,然后检查val 零件上的不同参数组合。最后,当您确定哪个分类器/参数在 val 部分上获得最佳结果时,您可以在 test 上进行评估以获得最后的其余部分。

一旦对test 部分进行评估,就不应再更改参数。

2) 另一方面,有些人采用另一种方式,他们将数据拆分为trainingtest,并在训练部分使用交叉验证对模型进行微调,最后对其进行评估test 部分。

如果你的数据比较大,我推荐你使用第一种方式,但是如果你的数据很小,那么2.

【讨论】:

能否给我分割数据为training|val|test的示例代码? training 部分使用相同的函数train_test_split 两次。【参考方案2】:

你的两种方法都是错误的。

在第一个中,您将交叉验证应用于 test 集,这是没有意义的

在第二个中,您首先使用整个数据拟合模型,然后执行交叉验证,这再次毫无意义。此外,该方法是多余的(cross_val_score 方法不使用您拟合的 clf,它自己进行拟合)

由于您没有进行任何超参数调整(即您似乎只对性能评估感兴趣),因此有两种方法:

或者带有单独的测试集 交叉验证

第一种方式(测试集):

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

x_train, x_test, y_train, y_test = train_test_split(features, results, test_size=0.3, random_state=0)

clf = LogisticRegression()
model = clf.fit(x_train, y_train)

y_pred = clf.predict(x_test)

accuracy_test = accuracy_score(y_test, y_pred)

第二种方式(交叉验证):

from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.utils import shuffle

clf = LogisticRegression()

# shuffle data first:
features_s, results_s = shuffle(features, results)
accuracy_cv = cross_val_score(clf, features_s, results_s, cv = 5, scoring='accuracy')

# fit the model afterwards with the whole data, if satisfied with the performance:
model = clf.fit(features, results)

【讨论】:

因此,例如,如果我想测试多个分类器,我可以将它们添加到 for 循环中,然后检查每个分类器的 accuracy_cv(使用您发布的“第二种方式”),并且然后,我将数据与给出最佳accuracy_cv的模型进行拟合? @taga 是正确的,您可以使用任何一种方式(测试集或 CV)来做到这一点。如果使用 CV,请注意,cross_val_score 本身并不能保证您的每个分类器都适合并在 same 数据子集中进行评估;如果您想确定这一点,最好使用KFold。您可以轻松地修改来自this answer 的代码(虽然这有点矫枉过正,您可以坚持使用上面显示的内容)。 我应该通过培训或测试进行 coss 验证。我在看你的“第二条路”,我应该在你的 accuracy_cv 中加入训练还是测试? @taga 请仔细阅读;之前有一个非此即彼的声明,并且在第二种方法中没有任何测试集。每当存在测试集时,它仅用于 test(没有训练,没有 CV,没有其他任何东西)

以上是关于应该对原始数据还是拆分数据执行交叉验证分数?的主要内容,如果未能解决你的问题,请参考以下文章

如何对数据应用交叉验证?

使用 sklearn 进行交叉验证的高级特征提取

我是不是需要同时执行网格搜索(使用交叉验证)和交叉验证方法?

如何拆分数据进行训练和测试?交叉验证可能吗? M估计还是OLS?

sklearn 交叉验证 R^2 分数与使用训练模型对训练和验证数据进行的手动检查不匹配

在使用 5 折交叉验证时,在高度不平衡的数据中混淆 F1 分数和 AUC 分数