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平方不同于


猜你喜欢
- 计算测试数量的Python单元测试 2022-01-01
- 我如何卸载 PyTorch? 2022-01-01
- 如何使用PYSPARK从Spark获得批次行 2022-01-01
- ";find_element_by_name(';name';)";和&QOOT;FIND_ELEMENT(BY NAME,';NAME';)";之间有什么区别? 2022-01-01
- 我如何透明地重定向一个Python导入? 2022-01-01
- 使用公司代理使Python3.x Slack(松弛客户端) 2022-01-01
- CTR 中的 AES 如何用于 Python 和 PyCrypto? 2022-01-01
- 检查具有纬度和经度的地理点是否在 shapefile 中 2022-01-01
- YouTube API v3 返回截断的观看记录 2022-01-01
- 使用 Cython 将 Python 链接到共享库 2022-01-01