【问题标题】:Why does LinearRegression with polynomial features with degree = 1 gives different results?为什么具有度数 = 1 的多项式特征的 LinearRegression 会给出不同的结果?
【发布时间】:2021-07-25 23:52:00
【问题描述】:

我有一个回归数据集:(X_train_scaled, y_train) 和 (X_val_scaled, y_val) 分别用于训练和验证。使用 StandardScaler 对输入进行缩放。

我使用 sklearn.linear_model.LinearRegression 创建一个线性回归模型,如下所示:

from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

linear_reg = LinearRegression()

linear_reg.fit(X_train_scaled, y_train)
y_pred_train = linear_reg.predict(X_train_scaled)
y_pred_val = linear_reg.predict(X_val_scaled)

r2_train = r2_score(y_train, y_pred_train)
r2_val = r2_score(y_val, y_pred_val)

print('r2_train', r2_train)
print('r2_val', r2_val)

之后我做同样的事情,但使用度数 = 1 的多项式特征(这与原始特征相同,但有一个附加特征,即 x^0,我忽略了它)。

from sklearn.preprocessing import PolynomialFeatures

pf = PolynomialFeatures(1)
X_train_poly = pf.fit_transform(X_train_scaled)[:, 1:] # ignore first col
X_val_poly = pf.transform(X_val_scaled)[:, 1:] # ignore first col

linear_reg = LinearRegression()

linear_reg.fit(X_train_poly, y_train)
y_pred_train = linear_reg.predict(X_train_poly)
y_pred_val = linear_reg.predict(X_val_poly)

r2_train = r2_score(y_train, y_pred_train)
r2_val = r2_score(y_val, y_pred_val)

print('r2_train', r2_train)
print('r2_val', r2_val)

但是,我得到了不同的结果。第一个代码给了我以下输出:

r2_train 0.7409525513417043
r2_val 0.7239859358973735

而第二个代码给出了这个输出:

r2_train 0.7410093370149977
r2_val 0.7241725658840452

为什么数据集和模型相同,但输出却不同?

为了证明数据集相同,我尝试了以下代码:

print(X_train_scaled.shape, X_train_poly.shape)
print(X_val_scaled.shape, X_val_poly.shape)
print((X_train_poly != X_train_scaled).sum())
print((X_val_poly != X_val_scaled).sum())

有输出:

(802, 9) (802, 9)
(268, 9) (268, 9)
0
0

表示这两个数据集是相同的。

另外,我在两种使用 OLS 算法并且根本没有随机操作的情况下使用 LinearRegression。因此,它应该对相同的数据进行相同的计算。但是,我得到了不同的结果。

有人知道原因吗?

【问题讨论】:

  • 欢迎来到 StackOverflow! R2 分数看起来非常接近(足够接近以至于结果可能是由于方差造成的),它们是在完全相同的数据上训练的,还是在某个地方有 train_test_split 可能会以不同的方式划分事物?
  • @AlexanderL.Hayes,谢谢。这两个模型是相同的,并且是在相同的数据集上训练的。我希望结果也相同。但是,代码输出略有不同。我的目标是找出造成这种差异的原因。
  • 我无法使用sklearn.datasets.load_boston 数据集重新创建它。
  • @BenReiniger 是的,我尝试了 load_boston,它按预期工作。听起来很奇怪。也许问题特定于我的数据集?我使用来自 Kaggle 的US-Health-Insurance-Dataset。我使用 0 和 1 将性别和吸烟者编码为二进制特征,并使用 one-hot 编码对区域特征进行编码。之后,我将数据集拆分为(60% 训练、20% 验证、20% 测试)并使用 StandardScaler 缩放数据。然后我编写了包含在这个问题中的代码。
  • 如果您可以将数据缩减为可以在此处发布的内容,同时保持行为,那将是理想的。如果没有,我可以稍后用 kaggle 数据尝试一下。两个型号的coef_intercept_是一样的吗?

标签: python machine-learning scikit-learn linear-regression


【解决方案1】:

Sklearn LinearRegression 使用普通的最小二乘优化将训练数据拟合到线性模型中,而目前尚不清楚 Sklearn PolynomialFeatures 使用什么。但是基于它的 transform() 函数:

对于稀疏输入(为了速度),首选 CSR 而不是 CSC,但需要 CSC 如果学位是 4 或更高。如果学位小于 4 并且 输入格式是CSC,会被转换成CSR,有它的多项式 生成的特征,然后转换回 CSC。 (见:https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html

假设 PolynomialFeatures 使用普通的最小二乘优化,您仍然会得到相同的结果,但略有不同(就像您的一样),因为压缩稀疏行 (CSR) 方法会影响浮点值(换句话说,截断/近似错误)。

【讨论】:

  • 但是如果 PolynomialFeatures 修改了我的数据,(X_train_poly != X_train_scaled).sum()(X_val_poly != X_val_scaled).sum() 如何都返回 0(这表明两个数据集是相同的)?我认为 PolynomialFeatures 根本不会修改 degree=1 的数据。
  • 你好,阿卜杜勒瓦哈布。我明白你的意思了。它肯定会归零。在您获得模型后,在您的情况下,线性和多项式 (n=1) 的模型相同,如您最后的结果所示,评估会有所不同,这意味着您有不同的 r2 分数,而不是因为有两个不同的 r2 分数公式,但由于评估过程中的计算差异,其中,前者使用普通最小二乘,而另一个使用其他方法(CSC),通常用于n>2多项式。然而不同的是,它们都产生了相似且显着的结果。
猜你喜欢
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 2014-02-01
  • 2021-08-26
  • 1970-01-01
  • 2015-11-16
  • 2010-10-29
  • 1970-01-01
相关资源
最近更新 更多