使用scikit learn和np.polyfit进行多项式回归的比较

4
我很惊讶没有人谈论这个:使用scikit learn和numpy中的polyfit进行多项式回归的差异。
首先,我们来看数据:
xdic={'X': {11: 300, 12: 170, 13: 288, 14: 360, 15: 319, 16: 330, 17: 520, 18: 345, 19: 399, 20: 479}}
ydic={'y': {11: 305000, 12: 270000, 13: 360000, 14: 370000, 15: 379000, 16: 405000, 17: 407500, 18: 450000, 19: 450000, 20: 485000}}

X=pd.DataFrame.from_dict(xdic)
y=pd.DataFrame.from_dict(ydic)
import numpy as np
X_seq = np.linspace(X.min(),X.max(),300).reshape(-1,1)

那么让我们使用scikit-learn创建模型

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LinearRegression

degree=9

polyreg=make_pipeline(PolynomialFeatures(degree),
                      LinearRegression())
polyreg.fit(X,y)

然后您可以创建一个图表。
plt.figure()
plt.scatter(X,y)
plt.plot(X_seq,polyreg.predict(X_seq),color="black")
plt.xlabel('X')
plt.ylabel('y')
plt.show()

这里是情节。

在此输入图片描述

使用numpy,情况就很不同了。

coefs = np.polyfit(X.values.flatten(), y.values.flatten(), 9)

X_seq = np.linspace(X.min(),X.max(),300)

plt.figure()
plt.plot(X_seq, np.polyval(coefs, X_seq), color="black")
plt.scatter(X,y)
plt.show()

通过这个图表,我们可以看到结果有很大的不同。

enter image description here

可能是由于浮点数精度问题导致的...

3个回答

3

我使用了两者,得到了相同的R2分数和相同的曲线。

regr = LinearRegression()
cubic = PolynomialFeatures(degree=3)
X_cubic = cubic.fit_transform(dfa3.home_realshow_cnt.values.reshape(-1, 1))
regr = regr.fit(X_cubic,dfa3.prop)

sklearn_r2=r2_score(dfa3.prop,regr.predict(X_cubic))
fit_r2=r2_score(dfa3.prop,yvalsa)
print("sklearn_r2: ",sklearn_r2,'; fit_r2: ',fit_r2)

def fit(x,y,n):
    z1 = np.polyfit(x,y, n)
    p1 = np.poly1d(z1)
    return p1(x)

0

我今天遇到了这个问题。确实,这似乎可能是由于浮点精度问题引起的。在我的情况下,我有大的x值(~60000),然后将其提升到了四次方的多项式特征中。通过首先将我的sklearn流水线通过标准缩放器进行处理,我能够获得与使用numpy的polyfit时相同的结果,否则它们的数值会有很大不同。


0

看代码,似乎两种方法都使用了最小二乘求解器来解方程Ax=y。求解器似乎是不同的:

虽然求解器的实现不同,但最大的区别似乎在于numpy.polyfit重新缩放了方程的左侧(包含x的幂的部分)。你可以在源代码中查看这里(从第667行到670行)。

在小维度下,两个系数集相匹配。当维度增加时,开始发生偏移。我进行了一些实验(计算系数之间距离的对数),对生成的一千个不同的(X,y)数据集取中位数,其中 X.shape = degree

|   degree |   log(coeff dist) (median) |
|---------:|---------------------------:|
|        1 |                    -inf    |
|        2 |                     -24.26 |
|        3 |                     -21.28 |
|        4 |                     -17.02 |
|        5 |                     -12.95 |
|        6 |                      -7.58 |
|        7 |                      -3.55 |
|        8 |                       0.76 |
|        9 |                       5.39 |
|       10 |                       9.32 |

请注意,这还取决于您的 (X, y) 的大小。对于此示例,我采用了与您相同的大小 (X ~ 10 和 y ~ 10**5)。由于 polyfit 产生了预期的解(即到达每个提供的坐标),我们应该尝试重新缩放 X。
将重新缩放的 X 提供给 LinearRegression(请注意,您应该使用 fit_intercept=False,因为 PolynomFeatures 返回 X**0 -> X**degree,因此 X**0 系数是截距),您会发现两种运算符使用的系数大致相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接