【发布时间】:2018-07-27 17:25:25
【问题描述】:
我偶然注意到,sklearn 和 statsmodels 实现的 OLS 模型在不拟合截距时会产生不同的 R^2 值。否则,它们似乎工作正常。以下代码产生:
import numpy as np
import sklearn
import statsmodels
import sklearn.linear_model as sl
import statsmodels.api as sm
np.random.seed(42)
N=1000
X = np.random.normal(loc=1, size=(N, 1))
Y = 2 * X.flatten() + 4 + np.random.normal(size=N)
sklernIntercept=sl.LinearRegression(fit_intercept=True).fit(X, Y)
sklernNoIntercept=sl.LinearRegression(fit_intercept=False).fit(X, Y)
statsmodelsIntercept = sm.OLS(Y, sm.add_constant(X))
statsmodelsNoIntercept = sm.OLS(Y, X)
print(sklernIntercept.score(X, Y), statsmodelsIntercept.fit().rsquared)
print(sklernNoIntercept.score(X, Y), statsmodelsNoIntercept.fit().rsquared)
print(sklearn.__version__, statsmodels.__version__)
打印:
0.78741906105 0.78741906105
-0.950825182861 0.783154483028
0.19.1 0.8.0
差异从何而来?
这个问题与Different Linear Regression Coefficients with statsmodels and sklearn 不同,因为sklearn.linear_model.LinearModel(带截距)适用于为statsmodels.api.OLS 准备的X。
问题不同于
Statsmodels: Calculate fitted values and R squared
因为它解决了两个 Python 包(statsmodels 和 scikit-learn)之间的差异,而链接的问题是关于 statsmodels 和常见的 R^2 定义。他们都得到了相同的答案,但是这个问题已经在这里讨论过:Does the same answer imply that the questions should be closed as duplicate?
【问题讨论】:
-
什么意思? -0.72... 与 0.78... 完全不同...
-
始终播种随机数据以获得可重复性:
np.random.seed(###). -
没有截距会改变 statsmodels 中 R2 的定义。见stackoverflow.com/questions/29664471/… 和stackoverflow.com/questions/24851787/…
-
@Parfait 同意了。在这种特殊情况下,我省略了种子,因为样本非常大,并且每次运行的结果都不同。但是为了正确起见,我更新了示例。
-
@user333700 你可以给出这个答案吗?我愿意接受。
标签: python python-3.x scikit-learn linear-regression statsmodels