使用 statsmodel.formula.api 与 statsmodel.api 的 OLS
OLS using statsmodel.formula.api versus statsmodel.api
谁能给我解释一下 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_
输出结果如下:
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]
statsmodel.api 方法 returns 与 statsmodel.formula.api 和 scikit-learn 方法不同的电视参数。
什么样的 ols 算法是 statsmodel.api 运行 会产生不同的结果?有没有人有 link 文档可以帮助回答这个问题?
区别在于是否存在拦截:
- 在
statsmodels.formula.api
中,与 R 方法类似,一个常量会自动添加到您的数据中,并在拟合 中添加一个截距
在statsmodels.api
中,你必须自己添加一个常量(参见statsmodels.api
中的the documentation here). Try using add_constant
x1 = sm.add_constant(x1)
今天遇到这个问题,想详细说明@stellasia 的回答,因为 statsmodels 文档可能有点含糊。
除非你在实例化OLS
时使用actual R-style string-formulas,否则你需要在[=15]下都添加一个常量(字面意思是一列1s) =] 和普通的 statsmodels.api
。 @Chetan 在这里使用 R 风格的格式 (formula='Sales ~ TV'
),所以他不会 运行 了解这种微妙之处,但是对于具有一些 Python 知识但没有 R 背景的人来说,这可能会非常混乱.
此外,在构建模型时是否指定hasconst
参数并不重要。 (这有点傻。)换句话说,除非您使用 R 风格的字符串公式,否则 hasconst
会被忽略,即使它应该是
[Indicate] whether the RHS includes a user-supplied constant
因为,在脚注中
No constant is added by the model unless you are using formulas.
下面的例子表明,如果不使用 R 风格的字符串公式,.formulas.api
和 .api
都需要用户添加的 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
现在将 x
和 y
放入 Excel 和 运行 Data>Data Analysis>Regression,确保未选中 "Constant is zero"。您将获得以下系数:
Intercept 1.497761024
X Variable 1 0.012073045
X Variable 2 0.623936056
现在,在 statsmodels.formula.api
或 statsmodels.api
中尝试 运行 在 x
上进行此回归,而不是 x_with_ones
,并设置 hasconst
None
、True
或 False
。您会看到,在这 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 ]
现在 运行 将 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]
我在使用 Logit 函数时遇到了类似的问题。
(我使用 patsy 创建了我的矩阵,所以截距就在那里。)
我的 sm.logit 没有收敛。
然而,我的 sm.formula.logit 正在收敛。
输入的数据完全一样。
我将求解器方法更改为 'newton' 并且 sm.logit 也收敛了。
有没有可能这两个版本有不同的默认求解器方法。
谁能给我解释一下 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_
输出结果如下:
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]
statsmodel.api 方法 returns 与 statsmodel.formula.api 和 scikit-learn 方法不同的电视参数。
什么样的 ols 算法是 statsmodel.api 运行 会产生不同的结果?有没有人有 link 文档可以帮助回答这个问题?
区别在于是否存在拦截:
- 在
statsmodels.formula.api
中,与 R 方法类似,一个常量会自动添加到您的数据中,并在拟合 中添加一个截距
在
中的the documentation here). Try using add_constantstatsmodels.api
中,你必须自己添加一个常量(参见statsmodels.apix1 = sm.add_constant(x1)
今天遇到这个问题,想详细说明@stellasia 的回答,因为 statsmodels 文档可能有点含糊。
除非你在实例化OLS
时使用actual R-style string-formulas,否则你需要在[=15]下都添加一个常量(字面意思是一列1s) =] 和普通的 statsmodels.api
。 @Chetan 在这里使用 R 风格的格式 (formula='Sales ~ TV'
),所以他不会 运行 了解这种微妙之处,但是对于具有一些 Python 知识但没有 R 背景的人来说,这可能会非常混乱.
此外,在构建模型时是否指定hasconst
参数并不重要。 (这有点傻。)换句话说,除非您使用 R 风格的字符串公式,否则 hasconst
会被忽略,即使它应该是
[Indicate] whether the RHS includes a user-supplied constant
因为,在脚注中
No constant is added by the model unless you are using formulas.
下面的例子表明,如果不使用 R 风格的字符串公式,.formulas.api
和 .api
都需要用户添加的 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
现在将 x
和 y
放入 Excel 和 运行 Data>Data Analysis>Regression,确保未选中 "Constant is zero"。您将获得以下系数:
Intercept 1.497761024
X Variable 1 0.012073045
X Variable 2 0.623936056
现在,在 statsmodels.formula.api
或 statsmodels.api
中尝试 运行 在 x
上进行此回归,而不是 x_with_ones
,并设置 hasconst
None
、True
或 False
。您会看到,在这 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 ]
现在 运行 将 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]
我在使用 Logit 函数时遇到了类似的问题。 (我使用 patsy 创建了我的矩阵,所以截距就在那里。) 我的 sm.logit 没有收敛。 然而,我的 sm.formula.logit 正在收敛。
输入的数据完全一样。 我将求解器方法更改为 'newton' 并且 sm.logit 也收敛了。 有没有可能这两个版本有不同的默认求解器方法。