Statsmodels: Calcular valores ajustados y R al cuadrado

Estoy ejecutando una regresión de la siguiente manera ( df es un dataframe de pandas ):

 import statsmodels.api as sm est = sm.OLS(df['p'], df[['e', 'varA', 'meanM', 'varM', 'covAM']]).fit() est.summary() 

Lo que me dio, entre otros, un R cuadrado de 0.942 . Entonces quise trazar los y-values y originales y-values ajustados. Para esto, ordené los valores originales:

 orig = df['p'].values fitted = est.fittedvalues.values args = np.argsort(orig) import matplotlib.pyplot as plt plt.plot(orig[args], 'bo') plt.plot(orig[args]-resid[args], 'ro') plt.show() 

Esto, sin embargo, me dio un gráfico donde los valores estaban completamente fuera de lugar. Nada que sugiera un R cuadrado de 0.9 . Por lo tanto, traté de calcularlo manualmente yo mismo:

 yBar = df['p'].mean() SSTot = df['p'].apply(lambda x: (x-yBar)**2).sum() SSReg = ((est.fittedvalues - yBar)**2).sum() 1 - SSReg/SSTot Out[79]: 0.2618159806908984 

¿Estoy haciendo algo mal? ¿O hay una razón por la que mi cálculo está tan lejos de lo que están obteniendo los modelos de estadísticas? SSTot , SSReg tienen valores de 48084 , 35495 .

Si no incluye una intercepción (variable explicativa constante) en su modelo, statsmodels calcula R cuadrado basado en la sum total de cuadrados descentrada , es decir.

 tss = (ys ** 2).sum() # un-centred total sum of squares 

Opuesto a

 tss = ((ys - ys.mean())**2).sum() # centred total sum of squares 

como resultado, R-cuadrado sería mucho mayor.

Esto es matemáticamente correcto . Debido a que R-cuadrado debe indicar qué parte de la variación se explica por el modelo completo en comparación con el modelo reducido. Si define su modelo como:

 ys = beta1 . xs + beta0 + noise 

entonces el modelo reducido puede ser: ys = beta0 + noise , donde la estimación para beta0 es el promedio de la muestra, por lo tanto tenemos: noise = ys - ys.mean() . Ahí es de donde viene el des-significado en un modelo con intercepción.

Pero a partir de un modelo como:

 ys = beta . xs + noise 

solo puede reducir a: ys = noise . Dado que el noise se asume como media cero, no puede des-significar ys . Por lo tanto, la variación no explicada en el modelo reducido es la sum total de cuadrados descentrada .

Esto se documenta aquí en el artículo rsquared . Establece yBar igual a cero, y espero que obtengas el mismo número.