为什么cross_val_predict不适合用于度量泛化误差?

时间:2019-03-05 18:56:11

标签: python scikit-learn svm cross-validation

当我通过交叉验证训练SVC时,

y_pred = cross_val_predict(svc, X, y, cv=5, method='predict')

cross_val_predict为X中的每个元素返回一个类预测,因此y_pred.shape = (1000,)m=1000时。 这是有道理的,因为cv=5并因此在X的不同部分上对SVC进行了5次训练和验证。在这五个验证中的每个验证中,对五分之一的实例(m/5 = 200)进行了预测。随后,将每个包含200个预测的5个向量合并到y_pred中。

考虑到所有这些,对于我来说,使用y_pred和y来计算SVC的整体精度是合理的。

score = accuracy_score(y, y_pred)

但是(!)cross_val_predict的文档指出:

  

cross_val_predict的结果可能与获得的结果不同   使用cross_val_score,因为元素以不同的方式分组。   函数cross_val_score对交叉验证取平均值   折叠,而cross_val_predict只是返回标签(或   概率)来自几个不同的模型。从而,   cross_val_predict不是一般化的适当度量   错误。

请问有人可以解释一下为什么cross_val_predict不适合测量泛化误差,例如通过accuracy_score(y, y_pred)吗?


编辑:

我首先假设在5个验证中的每一个中都使用cv=5对X的所有实例进行谓词。但这是错误的,每次验证仅对X实例的1/5进行预测。

1 个答案:

答案 0 :(得分:2)

cross_val_score与cross_val_predict

here清楚地描述了cross_val_predictcross_val_score之间的区别,并且其中还有另一个链接,因此您可以关注兔子。

本质上:

  • cross_val_score返回每折得分
  • cross_val_predict对每个数据点进行不精确的预测。

现在,您无法知道cross_val_predict中的哪些预测来自哪个折叠,因此您无法像cross_val_score那样计算每折叠的平均值。您可以平均cross_val_score中的accuracy_scorecross_val_predict,但是average of averages is not equal to average,因此结果会有所不同。

如果一折的准确性非常低,则对整体平均值的影响比对平均值cross_val_predict的影响更大。

此外,您可以对这七个数据点进行不同的分组,并获得不同的结果。这就是为什么有关分组的信息有所不同的原因。

cross_val_score和cross_val_predict之间的差异示例

让我们想象一下cross_val_predict对7个数据点使用3折,不折边预测为[0,1,1,0,1,0,1],而真实目标为[0,1,1,0,1,1,0]。准确性得分将被计算为5/7(只有最后两个被错误预测)。

现在采用相同的预测,并将其分为以下三折:

  • [0, 1, 1]-预测和[0, 1, 1]目标->第一折的准确性为1
  • [0, 1]-预测和[0, 1]目标->再次达到完美的准确性
  • [0, 1]-预测和[1, 0]目标-> 0精度

这就是cross_val_score的工作,并且会返回一个精度为[1, 1, 0]的元组。现在,您可以对该元组取平均,总精度为2/3

看到了吗?使用相同的数据,您将获得两种不同准确性度量(一种是5/7,另一种是2/3)。

在两种情况下,分组都会改变您获得的总精度。使用cross_val_score的分类器错误更为严重,因为每个错误对组的准确性的影响大于对所有预测的平均准确性的影响(您可以自行检查)。

尽管这两种方法都可以用来评估模型在验证集上的性能,但我认为没有禁忌症,只是行为不同(折叠错误并不严重)。

为什么都不是概括性度量

如果根据交叉验证方案拟合算法,则说明正在执行数据泄漏(针对训练和验证数据进行微调)。为了了解泛化错误,您必须将部分数据留给交叉验证和培训

您可能要执行两次交叉验证,或者只是进行测试以获取模型实际推广的效果。