为什么选择较大的 K 会降低我的交叉验证分数?

机器算法验证 机器学习 交叉验证 随机森林 样本量 scikit-学习
2022-02-28 04:28:39

在 scikit-learn 中使用Boston Housing DatasetRandomForestRegressor(带有默认参数)时,我注意到一些奇怪的事情:当我将折叠数增加到 10 次以上时,平均交叉验证分数下降。我的交叉验证策略如下:

cv_met = ShuffleSplit(n_splits=k, test_size=1/k)
scores = cross_val_score(est, X, y, cv=cv_met)

...num_cvs变化多端。我设置test_size1/num_cvs反映 k-fold CV 的训练/测试拆分大小行为。基本上,我想要像 k-fold CV 这样的东西,但我也需要随机性(因此是 ShuffleSplit)。

该试验重复了几次,然后绘制了平均分数和标准差。

K折交叉验证中的圆面积~K

(请注意,k圆圈的面积表示 的大小;标准偏差在 Y 轴上。)

始终如一地,增加k(从 2 到 44)将导致分数的短暂增加,然后k随着进一步增加(超过约 10 倍)而稳步下降!如果有的话,我希望更多的训练数据会导致分数小幅增加!

更新

将评分标准更改为平均绝对误差会导致我期望的行为:评分会随着 K-fold CV 中折叠数量的增加而提高,而不是接近 0(与默认值一样,' r2 ')。问题仍然是为什么默认评分指标会导致在平均数和 STD 指标上表现不佳,因为折叠次数越来越多。

1个回答

当应用于单个样本(例如留一法CV)时,r^2 分数未定义。

r^2 不适合评估小型测试集:当它用于评估足够小的测试集时,尽管预测良好,但得分可能会远远超过负数。

给定单个样本,对给定域的良好预测可能看起来很糟糕:

from sklearn.metrics import r2_score
true = [1]
predicted = [1.01] # prediction of a single value, off by 1%
print(r2_score(true, predicted))
# 0.0

增加测试集的大小(保持预测的准确性相同),突然 r^2 分数看起来接近完美:

true = [1, 2, 3]
predicted = [1.01, 2.02, 3.03]
print(r2_score(true, predicted))
# 0.9993

另一个极端,如果测试大小是 2 个样本,而我们碰巧评估了 2 个彼此接近的样本,这将对 r^2 分数产生重大影响,即使预测非常好:

true = [20.2, 20.1] # actual target values from the Boston Housing dataset
predicted = [19, 21]
print(r2_score(true, predicted))
# -449.0