Solución:
Encontré este problema hoy y quería ampliar la respuesta de @ stellasia porque la documentación de statsmodels es quizás un poco ambigua.
A menos que esté utilizando fórmulas de cadena de estilo R reales al instanciar OLS
, debe agregar una constante (literalmente una columna de 1) debajo de ambos statsmodels.formulas.api
y llano statsmodels.api
. @Chetan está usando formato de estilo R aquí (formula="Sales ~ TV"
), por lo que no se encontrará con esta sutileza, pero para las personas con algún conocimiento de Python pero sin experiencia en R, esto podría ser muy confuso.
Además es no importa si especifica el hasconst
parámetro al construir el modelo. (Lo cual es un poco tonto). En otras palabras, a menos que esté utilizando fórmulas de cadena de estilo R, hasconst
se ignora a pesar de que se supone que
[Indicate] si el RHS incluye una constante proporcionada por el usuario
porque, en las notas a pie de página
El modelo no agrega ninguna constante a menos que esté usando fórmulas.
El siguiente ejemplo muestra que ambos .formulas.api
y .api
requerirá un vector de columna de 1s agregado por el usuario si no se utilizan fórmulas de cadena de estilo R.
# 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
Ahora lanza x
y y
en Excel y ejecute Datos> Análisis de datos> Regresión, asegurándose de que “Constante es cero” no esté marcado. Obtendrá los siguientes coeficientes:
Intercept 1.497761024
X Variable 1 0.012073045
X Variable 2 0.623936056
Ahora, intente ejecutar esta regresión en x
, no x_with_ones
, en cualquiera statsmodels.formula.api
o statsmodels.api
con hasconst
ajustado a None
, True
, o False
. Verá que en cada uno de esos 6 escenarios, no se devuelve ninguna intercepción. (Solo hay 2 parámetros).
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 ]
Ahora ejecutando las cosas correctamente con un vector de columna de 1.0
s agregado a x
. Puedes usar smf
aquí, pero realmente no es necesario si no está utilizando fórmulas.
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]
La diferencia se debe a la presencia de interceptar o no:
- en
statsmodels.formula.api
, de manera similar al enfoque R, una constante se agrega automáticamente a sus datos y una intersección en ajustada -
en
statsmodels.api
, debe agregar una constante usted mismo (consulte la documentación aquí). Intente usar add_constant de statsmodels.apix1 = sm.add_constant(x1)