OLS使用statsmodel.formula.api与statsmodel.api

Che*_*bhu 8 python linear-regression

任何人都可以向我解释statsmodel.formula.api中的ols与statsmodel.api中的ols之间的区别吗?

使用来自ISLR文本的广告数据,我使用两者运行了ols,并得到了不同的结果.然后我与scikit-learn的LinearRegression进行了比较.

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression

df = pd.read_csv("C:\...\Advertising.csv")

x1 = df.loc[:,['TV']]
y1 = df.loc[:,['Sales']]

print "Statsmodel.Formula.Api Method"
model1 = smf.ols(formula='Sales ~ TV', data=df).fit()
print model1.params

print "\nStatsmodel.Api Method"
model2 = sm.OLS(y1, x1)
results = model2.fit()
print results.params

print "\nSci-Kit Learn Method"
model3 = LinearRegression()
model3.fit(x1, y1)
print model3.coef_
print model3.intercept_
Run Code Online (Sandbox Code Playgroud)

输出如下:

Statsmodel.Formula.Api Method
Intercept    7.032594
TV           0.047537
dtype: float64

Statsmodel.Api Method
TV    0.08325
dtype: float64

Sci-Kit Learn Method
[[ 0.04753664]]
[ 7.03259355]
Run Code Online (Sandbox Code Playgroud)

statsmodel.api方法从statsmodel.formula.api和scikit-learn方法返回TV的不同参数.

什么样的ols算法运行statsmodel.api会产生不同的结果?有没有人有文档链接可以帮助回答这个问题?

Bra*_*mon 15

今天遇到这个问题,并想详细说明@ stellasia的答案,因为statsmodels文档可能有点含糊不清.

除非在实例化时使用实际的R风格字符串公式,否则OLS需要在两者statsmodels.formulas.api和普通模式下添加一个常量(字面上为1的列)statsmodels.api.@Chetan在这里使用R风格的格式(formula='Sales ~ TV'),所以他不会遇到这种微妙的问题,但是对于那些具有一些Python知识但没有R背景的人来说,这可能会让人非常困惑.

此外,在构建模型时是否指定参数并不重要hasconst.(这有点傻.)换句话说,除非你使用R风格的字符串公式,否则hasconst即使它应该被忽略也会被忽略

[表示] RHS是否包含用户提供的常量

因为,在脚注中

除非使用公式,否则模型不会添加常量.

下面的例子示出了两个.formulas.api.api如果不使用R-风格串公式将需要1秒的用户添加的列向量.

# Generate some relational data
np.random.seed(123)
nobs = 25 
x = np.random.random((nobs, 2)) 
x_with_ones = sm.add_constant(x, prepend=False)
beta = [.1, .5, 1] 
e = np.random.random(nobs)
y = np.dot(x_with_ones, beta) + e
Run Code Online (Sandbox Code Playgroud)

现在抛出xy进入Excel并运行数据>数据分析>回归,确保未选中"常量为零".您将获得以下系数:

Intercept       1.497761024
X Variable 1    0.012073045
X Variable 2    0.623936056
Run Code Online (Sandbox Code Playgroud)

现在,尝试上运行该回归x,而不是x_with_ones在任一statsmodels.formula.apistatsmodels.apihasconst设置为None,TrueFalse.您将看到在这6个场景中的每个场景中都没有返回拦截.(只有2个参数.)

import statsmodels.formula.api as smf
import statsmodels.api as sm

print('smf models')
print('-' * 10)
for hc in [None, True, False]:
    model = smf.OLS(endog=y, exog=x, hasconst=hc).fit()
    print(model.params)

# smf models
# ----------
# [ 1.46852293  1.8558273 ]
# [ 1.46852293  1.8558273 ]
# [ 1.46852293  1.8558273 ]
Run Code Online (Sandbox Code Playgroud)

现在使用1.0添加的列向量正确运行x.你可以smf在这里使用,但如果你不使用公式,那就没有必要了.

print('sm models')
print('-' * 10)
for hc in [None, True, False]:
    model = sm.OLS(endog=y, exog=x_with_ones, hasconst=hc).fit()
    print(model.params)

# sm models
# ----------
# [ 0.01207304  0.62393606  1.49776102]
# [ 0.01207304  0.62393606  1.49776102]
# [ 0.01207304  0.62393606  1.49776102]
Run Code Online (Sandbox Code Playgroud)


ste*_*sia 14

差异是由于是否存在拦截: