Why is Sklearn R-squared different from that of statsmodels when fit_intercept=False?(为什么当Fit_Intercept=FALSE时,SkLearning R平方不同于statsModel?)
本文介绍了为什么当Fit_Intercept=FALSE时,SkLearning R平方不同于statsModel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在使用SkLearning和statsModel执行线性回归。
我知道SkLearning和statsModel产生的结果是一样的。如下图所示,SkLearning和statsModels得出的结果是相同的,但在SkLearning中使用fit_intercept=False
截距为零时,即使系数相同,结果也不同。
你能解释一下原因吗?或者当我在SkLearning中使用fit_intercept=False
时给我任何方法。
import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
# dummy data:
y = np.array([1,3,4,5,2,3,4])
X = np.array(range(1,8)).reshape(-1,1) # reshape to column
# intercept is not zero : the result are the same
# scikit-learn:
lr = LinearRegression()
lr.fit(X,y)
print(lr.score(X,y))
# 0.16118421052631582
# statsmodels
X_ = sm.add_constant(X)
model = sm.OLS(y,X_)
results = model.fit()
print(results.rsquared)
# 0.16118421052631582
# intercept is zero : the result are different
# scikit-learn:
lr = LinearRegression(fit_intercept=False)
lr.fit(X,y)
print(lr.score(X,y))
# -0.4309210526315792
# statsmodels
model = sm.OLS(y,X)
results = model.fit()
print(results.rsquared)
# 0.8058035714285714
推荐答案
不一致是因为statsmodels
使用不同的公式来计算R平方,具体取决于模型是否包括截取。如果包括截距,statsmodels
将残差平方和除以居中的平方和,而如果不包括截距,statsmodels
将残差平方和除以未输入的平方总和。这意味着statsmodels
使用以下公式来计算R平方,可以在documentation中找到:
import numpy as np
def rsquared(y_true, y_pred, fit_intercept=True):
'''
Statsmodels R-squared, see https://www.statsmodels.org/dev/generated/statsmodels.regression.linear_model.RegressionResults.rsquared.html.
'''
if fit_intercept:
return 1 - np.sum((y_true - y_pred) ** 2) / np.sum((y_true - np.mean(y_true)) ** 2)
else:
return 1 - np.sum((y_true - y_pred) ** 2) / np.sum(y_true ** 2)
另一方面,sklearn
始终使用分母的居中平方和,而不管截取是否实际包含在模型中(即,无论fit_intercept=True
还是fit_intercept=False
)。另请参阅this answer。
import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
def rsquared(y_true, y_pred, fit_intercept=True):
'''
Statsmodels R-squared, see https://www.statsmodels.org/dev/generated/statsmodels.regression.linear_model.RegressionResults.rsquared.html.
'''
if fit_intercept:
return 1 - np.sum((y_true - y_pred) ** 2) / np.sum((y_true - np.mean(y_true)) ** 2)
else:
return 1 - np.sum((y_true - y_pred) ** 2) / np.sum(y_true ** 2)
# dummy data:
y = np.array([1, 3, 4, 5, 2, 3, 4])
X = np.array(range(1, 8)).reshape(-1, 1) # reshape to column
# intercept is not zero: the result are the same
# scikit-learn:
lr = LinearRegression(fit_intercept=True)
lr.fit(X, y)
print(lr.score(X, y))
# 0.16118421052631582
print(rsquared(y, lr.predict(X), fit_intercept=True))
# 0.16118421052631582
# statsmodels
X_ = sm.add_constant(X)
model = sm.OLS(y, X_)
results = model.fit()
print(results.rsquared)
# 0.16118421052631582
print(rsquared(y, results.fittedvalues, fit_intercept=True))
# 0.16118421052631593
# intercept is zero: the result are different
# scikit-learn:
lr = LinearRegression(fit_intercept=False)
lr.fit(X, y)
print(lr.score(X, y))
# -0.4309210526315792
print(rsquared(y, lr.predict(X), fit_intercept=True))
# -0.4309210526315792
print(rsquared(y, lr.predict(X), fit_intercept=False))
# 0.8058035714285714
# statsmodels
model = sm.OLS(y, X)
results = model.fit()
print(results.rsquared)
# 0.8058035714285714
print(rsquared(y, results.fittedvalues, fit_intercept=False))
# 0.8058035714285714
这篇关于为什么当Fit_Intercept=FALSE时,SkLearning R平方不同于statsModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:为什么当Fit_Intercept=FALSE时,SkLearning R平方不同于
基础教程推荐
猜你喜欢
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 筛选NumPy数组 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01