应该根据训练数据还是测试数据计算?R2R2

机器算法验证 回归 机器学习 r平方
2022-02-26 03:18:19

在计算线性回归模型的时,应该在训练数据集、测试数据集还是两者上计算,为什么?R2

此外,当根据上面的维基百科文章计算时,两个总和是否应该在同一个数据集上?换句话说,如果在训练数据集上计算,是否需要在训练数据集(对于测试数据集也是如此。)SSresSStotSSresSStot

3个回答

测试数据向您展示了您的模型的泛化程度。当您通过模型运行测试数据时,正是您一直在等待的时刻:它是否足够好?

在机器学习领域,呈现所有训练、验证和测试指标是很常见的,但最重要的是测试准确性。

但是,如果您得分较低,而在另一个上却没有,那么就有问题了!例如,如果,则表明您的模型不能很好地泛化。也就是说,如果您的测试集仅包含“看不见的”数据点,那么您的模型似乎无法很好地推断(也就是协变量偏移的一种形式)。R2Rtest2Rtraining2

总之:你应该比较它们!但是,在许多情况下,您最感兴趣的是测试集结果。

在计算线性回归模型的时,应该在训练数据集、测试数据集还是两者上计算,为什么?R2

通常的是一个拟合度量,必须在训练集上计算。在某些回归分析中,样本中样本外没有拆分,并且“样本中=所有数据”。R2

此外,当根据上面的维基百科文章计算 时,两个总和是否应该在同一个数据集上?SSresSStot

是的,当然。你有三个对象:残差平方和总平方和解释平方和所有这些都是“在样本中”计算的。

如果您对预测准确性一样在样本测量中使用不是一个好主意(过去很常见的错误)。您需要所谓的样本在这里阅读:如何计算样本 R 的平方?R2 R2

上述答案的详细说明,为什么在测试数据上计算不是一个好主意,这与学习数据不同。R2

为了衡量模型的“预测能力”,它在学习数据集之外的数据上表现如何,应该使用而不是OOS 代表“样本外”。Roos2R2

分母的替换为Roos2Σ(yy¯test)2Σ(yy¯train)2

如果您想确切地知道如果忽略并在测试数据集上使用会发生什么,请阅读下文。Roos2R2

令我惊讶的是,当目标变量与“信号”(对特征的依赖性)相比具有高方差时,那么在测试数据集(不同于学习数据集)上保证。R2R2

下面我将 jupyter notebook 代码放在 Pyhton 中,这样任何人都可以复制它并自己查看它:

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns

x = np.linspace(-1, 1, num=1_000_000)
X = x.reshape(-1, 1)

# notice 0.05 << 1 (variance of y)
y = np.random.normal(x * 0.05)
df = pd.DataFrame({'X': pd.Series(x), 'y': pd.Series(y)})

ax = sns.histplot(data=df, x='X', y='y', bins=(200, 100))
ax.figure.set_figwidth(18)
ax.figure.set_figheight(9)
ax.grid()
plt.show()

依赖 y 与 X 的二维直方图

from sklearn import ensemble
from sklearn.model_selection import cross_val_score

fraction=0.0001
reg = ensemble.ExtraTreesRegressor(
  n_estimators=20, min_samples_split=fraction * 2, min_samples_leaf=fraction
)
_ = reg.fit(X, y)

print(f'r2 score on learn dataset: {reg.score(X, y)}')
print('Notice above, r2 calculated on learn dataset is positive')

X_pred = np.linspace(-1, 1, num=100)
y_pred = reg.predict(X_pred.reshape(-1, 1))
plt.plot(X_pred, y_pred)
plt.gca().grid()
plt.gca().set_title('Model has correctly captured the trend')
plt.show()

学习数据集的 r2 分数:0.0049158435364208275

注意上面,在学习数据集上计算的 r2 是正的

模型预测

scores = cross_val_score(reg, X, y, scoring='r2')
print(f'r2 {scores.mean():.4f} ± {scores.std():.4f}')

r2 -0.0023 ± 0.0028

尽管模型正确捕捉了趋势,但交叉验证始终在测试数据集上产生负 r2,这与学习数据集不同。

更新 2022-01-19

的实际原因是在交叉验证之前缺乏对 ,尽管如此,这一点是正确的,在洗牌后仍然可以可靠地得到负,这仍然可以通过使用来解决。请参阅github 上的更正示例R2XyR2Roos2