使用 cross_val_score 计算的指标与从 cross_val_predict 开始计算的相同指标有何不同?

How a metric computed with cross_val_score can differ from the same metric computed starting from cross_val_predict?

使用 cross_val_score 计算的指标与从 cross_val_predict 开始计算的相同指标有何不同(用于获取预测然后提供给指标函数)?

这是一个例子:

from sklearn import cross_validation
from sklearn import datasets
from sklearn import metrics
from sklearn.naive_bayes import GaussianNB


iris = datasets.load_iris()

gnb_clf = GaussianNB()
#  compute mean accuracy with cross_val_predict
predicted = cross_validation.cross_val_predict(gnb_clf, iris.data, iris.target, cv=5)
accuracy_cvp = metrics.accuracy_score(iris.target, predicted)
#  compute mean accuracy with cross_val_score
score_cvs = cross_validation.cross_val_score(gnb_clf, iris.data, iris.target, cv=5)
accuracy_cvs = score_cvs.mean()

print('Accuracy cvp: %0.8f\nAccuracy cvs: %0.8f' % (accuracy_cvp, accuracy_cvs))

在这种情况下,我们得到相同的结果:

Accuracy cvp: 0.95333333
Accuracy cvs: 0.95333333

然而,情况似乎并非总是如此,因为 on the official documentation 它是这样写的(关于使用 cross_val_predict 计算的结果):

Note that the result of this computation may be slightly different from those obtained using cross_val_score as the elements are grouped in different ways.

想象一下跟随标签和拆分

[010|101|10]

所以你有 8 个数据点,每个 class 有 4 个,你将它分成 3 折,导致 2 折有 3 个元素,一个有 2 个元素。现在让我们假设在交叉验证期间你得到以下预测值

[010|100|00]

因此,您的得分为 [100%, 67%, 50%],cross val 得分(平均)约为 72%。现在预测的准确性如何?你显然有 6/8 的事情是正确的,因此是 75%。正如您所看到的,分数是不同的,即使它们都依赖于交叉验证。在这里,差异的出现是因为拆分的大小不完全相同,因此最后的“50%”实际上降低了总分,因为它只是 2 个样本的平均值(其余基于 3 个样本)。

可能还有其他类似的现象,总的来说——应该归结为计算平均值的方式。因此 - cross val score 是平均值的平均值,不一定是交叉验证预测的平均值。

除了 lejlot 的回答之外,另一种可能在 cross_val_score 和 cross_val_predict 之间得到略微不同结果的方法是当目标 classes 未以允许的方式分布时它们在折叠之间平均分配。

根据 cross_val_predict 的文档,如果估计器是 class 器并且 y 是二进制或多 class,则默认使用 StratifiedKFold。这可能会导致这样一种情况,即即使数据集中的实例总数可以被折叠数整除,您最终也会得到大小略有不同的折叠,因为拆分器是根据目标的存在进行拆分的。这可能会导致平均值的平均值与总体平均值略有不同的问题。

例如,如果您有 100 个数据点,其中 33 个是目标 class,那么 KFoldn_splits=5 会将其分成 5 份,每份 20 个观测值,但是 StratifiedKFold 不一定会给你同样大小的褶皱。