【问题标题】: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 开始计算的相同指标有何不同?
【发布时间】:2016-05-21 00:02:16
【问题描述】:

使用 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 计算的结果):

请注意,此计算的结果可能会略有不同 从使用 cross_val_score 获得的那些元素被分组 以不同的方式。

【问题讨论】:

  • 请添加一个最小的例子来说明这一点。没有这样的例子,恐怕无法回答这个问题。
  • @AmiTavory 完成。感谢您的评论。
  • 没问题。但是,您已经回答了自己的问题,不是吗?文档说分组可能不同。也许您应该参加这部分并将其移至答案(在 SO 中回答您自己的问题很好)。
  • @AmiTavory 这是我没有掌握的部分。我已经多次查看该行以及源代码,但我希望看到一个实际示例,其中相同度量的计算会导致不同的结果。例如,我在不同的数据集上计算准确度,这次结果不一致。我想有一个比那行更详尽的解释,也就是说,有一个实际的例子。也许解释会非常简单,但我只是想确保我使用了正确的工具来验证分类器。
  • 是的,我也查看了源代码,但看不出它们有何不同。 (FWIW,承诺事情可能会有所不同,与承诺会有所不同。)

标签: python machine-learning scikit-learn metrics cross-validation


【解决方案1】:

想象以下标签和拆分

[010|101|10]

因此,您有 8 个数据点,每个类 4 个,然后将其拆分为 3 折,导致 2 折包含 3 个元素,1 折包含 2 个元素。现在让我们假设在交叉验证期间您得到以下预测

[010|100|00]

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

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

【讨论】:

  • 我已经尝试过我在问题中给出的相同示例,但这次要求进行 7 折交叉验证。实际上,结果略有不同,因为 150(iris 数据集中的实例总数)不能完全除以 7。结果如下:accuracy cvp: 0.95333333 Accuracy cvs: 0.95408163。谢谢。
【解决方案2】:

除了 lejlot 的回答之外,您可能会在 cross_val_score 和 cross_val_predict 之间得到稍有不同的结果的另一种方式是,目标类的分布方式不允许它们在折叠之间均匀分布。

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

例如,如果您有 100 个数据点,其中 33 个是目标类,那么 KFoldn_splits=5 会将其分成 20 个观察值的 5 折,但 StratifiedKFold 不一定会给您同等的大小的折叠。

【讨论】:

    猜你喜欢
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2020-09-23
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 2019-11-22
    相关资源
    最近更新 更多