No dudes en divulgar nuestro espacio y códigos con tus amigos, danos de tu ayuda para hacer crecer esta comunidad.
Solución:
Como se señaló en los comentarios, PanelOLS se ha eliminado de Pandas a partir de la versión 0.20.0. Entonces realmente tienes tres opciones:
-
Si usa Python 3, puede usar
linearmodels
como se especifica en la respuesta más reciente: https://stackoverflow.com/a/44836199/3435183 -
Simplemente especifique varios maniquíes en su
statsmodels
especificación, por ejemplo, usandopd.get_dummies
. Puede que no sea factible si el número de efectos fijos es grande. -
O haz algo de degradación grupal y luego usa
statsmodels
(esto funcionaría si está estimando muchos efectos fijos). Aquí hay una versión básica de lo que podría hacer para efectos fijos unidireccionales:import statsmodels.api as sm import statsmodels.formula.api as smf import patsy def areg(formula,data=None,absorb=None,cluster=None): y,X = patsy.dmatrices(formula,data,return_type='dataframe') ybar = y.mean() y = y - y.groupby(data[absorb]).transform('mean') + ybar Xbar = X.mean() X = X - X.groupby(data[absorb]).transform('mean') + Xbar reg = sm.OLS(y,X) # Account for df loss from FE transform reg.df_resid -= (data[absorb].nunique() - 1) return reg.fit(cov_type='cluster',cov_kwds='groups':data[cluster].values)
Por ejemplo, suponga que tiene un panel de datos de acciones: rendimientos de acciones y otros datos de acciones para todas las acciones, todos los meses durante varios meses y desea hacer una regresión de los rendimientos sobre rendimientos rezagados con efectos fijos del mes calendario (donde la variable del mes calendario es llamado caldt
) y también desea agrupar los errores estándar por mes calendario. Puede estimar un modelo de efectos fijos de este tipo con lo siguiente:
reg0 = areg('ret~retlag',data=df,absorb='caldt',cluster='caldt')
Y esto es lo que puede hacer si usa una versión anterior de Pandas
:
Un ejemplo con efectos fijos de tiempo usando pandas ‘ PanelOLS
(que está en el módulo plm). Aviso, la importancia de PanelOLS
:
>>> from pandas.stats.plm import PanelOLS
>>> df
y x
date id
2012-01-01 1 0.1 0.2
2 0.3 0.5
3 0.4 0.8
4 0.0 0.2
2012-02-01 1 0.2 0.7
2 0.4 0.5
3 0.2 0.3
4 0.1 0.1
2012-03-01 1 0.6 0.9
2 0.7 0.5
3 0.9 0.6
4 0.4 0.5
Tenga en cuenta que el marco de datos debe tener un conjunto de índices múltiples; panelOLS
determina el time
y entity
efectos basados en el índice:
>>> reg = PanelOLS(y=df['y'],x=df[['x']],time_effects=True)
>>> reg
-------------------------Summary of Regression Analysis-------------------------
Formula: Y ~
Number of Observations: 12
Number of Degrees of Freedom: 4
R-squared: 0.2729
Adj R-squared: 0.0002
Rmse: 0.1588
F-stat (1, 8): 1.0007, p-value: 0.3464
Degrees of Freedom: model 3, resid 8
-----------------------Summary of Estimated Coefficients------------------------
Variable Coef Std Err t-stat p-value CI 2.5% CI 97.5%
--------------------------------------------------------------------------------
x 0.3694 0.2132 1.73 0.1214 -0.0485 0.7872
---------------------------------End of Summary---------------------------------
Docstring:
PanelOLS(self, y, x, weights = None, intercept = True, nw_lags = None,
entity_effects = False, time_effects = False, x_effects = None,
cluster = None, dropped_dummies = None, verbose = False,
nw_overlap = False)
Implements panel OLS.
See ols function docs
Esta es otra función (como fama_macbeth
) donde creo que el plan es mover esta funcionalidad a statsmodels
.
Hay un paquete llamado linearmodels
(https://pypi.org/project/linearmodels/) que tiene una implementación de efectos fijos y efectos aleatorios bastante completa que incluye errores estándar agrupados. No utiliza OLS de alta dimensión para eliminar efectos, por lo que se puede utilizar con grandes conjuntos de datos.
# Outer is entity, inner is time
entity = list(map(chr,range(65,91)))
time = list(pd.date_range('1-1-2014',freq='A', periods=4))
index = pd.MultiIndex.from_product([entity, time])
df = pd.DataFrame(np.random.randn(26*4, 2),index=index, columns=['y','x'])
from linearmodels.panel import PanelOLS
mod = PanelOLS(df.y, df.x, entity_effects=True)
res = mod.fit(cov_type='clustered', cluster_entity=True)
print(res)
Esto produce la siguiente salida:
PanelOLS Estimation Summary
================================================================================
Dep. Variable: y R-squared: 0.0029
Estimator: PanelOLS R-squared (Between): -0.0109
No. Observations: 104 R-squared (Within): 0.0029
Date: Thu, Jun 29 2017 R-squared (Overall): -0.0007
Time: 23:52:28 Log-likelihood -125.69
Cov. Estimator: Clustered
F-statistic: 0.2256
Entities: 26 P-value 0.6362
Avg Obs: 4.0000 Distribution: F(1,77)
Min Obs: 4.0000
Max Obs: 4.0000 F-statistic (robust): 0.1784
P-value 0.6739
Time periods: 4 Distribution: F(1,77)
Avg Obs: 26.000
Min Obs: 26.000
Max Obs: 26.000
Parameter Estimates
==============================================================================
Parameter Std. Err. T-stat P-value Lower CI Upper CI
------------------------------------------------------------------------------
x 0.0573 0.1356 0.4224 0.6739 -0.2127 0.3273
==============================================================================
F-test for Poolability: 1.0903
P-value: 0.3739
Distribution: F(25,77)
Included effects: Entity
También tiene una interfaz de fórmulas que es similar a los modelos de estadísticas,
mod = PanelOLS.from_formula('y ~ x + EntityEffects', df)
Recuerda que puedes optar por la opción de decir si encontraste tu problema en el momento justo.