应该对原始数据还是拆分数据执行交叉验证分数?
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) 另一方面,有些人采用另一种方式,他们将数据拆分为training
和test
,并在训练部分使用交叉验证对模型进行微调,最后对其进行评估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,没有其他任何东西)以上是关于应该对原始数据还是拆分数据执行交叉验证分数?的主要内容,如果未能解决你的问题,请参考以下文章
我是不是需要同时执行网格搜索(使用交叉验证)和交叉验证方法?
如何拆分数据进行训练和测试?交叉验证可能吗? M估计还是OLS?