Pandas 或 Statsmodels 中的固定效果

Posted

技术标签:

【中文标题】Pandas 或 Statsmodels 中的固定效果【英文标题】:Fixed effect in Pandas or Statsmodels 【发布时间】:2014-08-03 10:18:31 【问题描述】:

是否有现有函数可以从 Pandas 或 Statsmodels 估计固定效应(单向或双向)。

Statsmodels 中曾经有一个功能,但它似乎已停产。在 Pandas 中,有一个叫做 plm 的东西,但我无法导入它或使用 pd.plm() 运行它。

【问题讨论】:

请一题一题。另外,请解释一下“我不能”是什么意思。请包含完整回溯(如果存在)和小型可运行 独立的样本重现问题。 也不要避免告诉我们相关信息。 “曾经有一个函数”意味着你知道那个函数是什么,所以你为什么不告诉我们让我感到困惑。 既然固定效果完全等同于带有适当贬低目标变量的OLS,你为什么不先贬低然后运行OLS,like this set of examples?我希望这是一些任务或其他东西,因为作为贝叶斯主义者,每次有人使用固定效果时,天使都会失去翅膀。 @user3576212 很不幸。在社会科学的某些领域,尤其是心理学和经济学中,学生被告知使用固定效应等技术是很常见的,但他们从未学习过其背后的真正理论。这些方法在现实世界环境中使用时存在严重缺陷,不应该盲目地作为软件包的一部分使用,至少在你掌握了它背后的真实理论之前是这样。您可以通过Cross-Validated 寻求更多帮助。 您可以随意使用任何您想要的工具。我只是说在金融领域从事量化研究让我更加欣赏对这些方法的批评。它们不适合精确解决他们声称要解决的问题(例如横截面相关性)。它与其他非常糟糕的方法类似,例如 Fama-Macbeth 回归。我不是在谈论任何学术,只是应用经济学研究。 【参考方案1】:

如 cmets 中所述,PanelOLS 自 0.20.0 版起已从 Pandas 中删除。所以你真的有三个选择:

    如果您使用 Python 3,则可以使用 linearmodels,如更新的答案中所述:https://***.com/a/44836199/3435183

    只需在您的 statsmodels 规范中指定各种假人,例如使用pd.get_dummies。如果固定效应的数量很大,则可能不可行。

    或者做一些基于 groupby 的贬低,然后使用statsmodels(如果你估计有很多固定效果,这会起作用)。这是您可以为单向固定效果执行的操作的准系统版本:

    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)
    

例如,假设您有一个股票数据面板:所有股票的股票收益和其他股票数据,每个月在多个月内,并且您想要回归具有日历月固定效应的滞后收益的收益(其中日历月变量称为caldt),您还希望按日历月对标准误差进行聚类。您可以使用以下方法估计这样的固定效应模型:

reg0 = areg('ret~retlag',data=df,absorb='caldt',cluster='caldt')

如果使用旧版本的Pandas,您可以执行以下操作:

使用 pandas 的 PanelOLS(在 plm 模块中)的时间固定效果示例。注意,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

注意,数据框必须有一个多索引集; panelOLS根据索引确定timeentity效果:

>>> reg  = PanelOLS(y=df['y'],x=df[['x']],time_effects=True)
>>> reg

-------------------------Summary of Regression Analysis-------------------------

Formula: Y ~ <x>

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--------------------------------- 

文档字符串:

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

这是另一个功能(如fama_macbeth),我相信计划是将这个功能移至statsmodels

【讨论】:

如果您在 statsmodels ols 的公式中使用时间索引或组索引 id 作为分类变量,那么它会为您创建固定效应假人。但是,尚不支持通过贬低来消除固定效果。 @Karl D. 非常感谢,您的回答总是很有用! 我可以对 pandas 使用随机效果吗?我正在寻找类似于 stata 的xtreg, re 的东西。谢谢! Statsmodels 会产生随机效应。 time_effectsentity_effects有什么区别?【参考方案2】:

有一个名为linearmodels (https://pypi.org/project/linearmodels/) 的包具有相当完整的固定效应和随机效应实现,包括聚集标准错误。它不使用高维 OLS 来消除影响,因此可以用于大型数据集。

# 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)

这会产生以下输出:

                          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

它还有一个类似于statsmodels的公式接口,

mod = PanelOLS.from_formula('y ~ x + EntityEffects', df)

【讨论】:

正确的答案应该改成这个,因为 PanelOLS 在 0.20 中已经从 pandas 中删除了,我在 statsmodels 中也找不到它。 bashtage.github.io/linearmodels/doc/panel/pandas.html 买家注意:线性模型需要 Python 3。 此外,它不会做出样本预测。你必须自己编写代码。 linearmodels 目前也不适用于stargazer github.com/mwburke/stargazer/issues/26 如何声明entitytime?也就是说,这个函数怎么知道哪个变量是entity,哪个是time?对于那些遇到这种情况的人,请检查:bashtage.github.io/linearmodels/panel/examples/…

以上是关于Pandas 或 Statsmodels 中的固定效果的主要内容,如果未能解决你的问题,请参考以下文章

使用 statsmodels 忽略多个 OLS 回归中的缺失值

python使用statsmodels包中的robust.mad函数以及pandas的apply函数计算dataframe中所有数据列的中位数绝对偏差(MAD)

时间序列分析 - 不均匀间隔测量 - pandas + statsmodels

时间序列分析 - 不均匀间隔测量 - pandas + statsmodels

解析具有未知列数的 Pandas 数据框以在 statsmodels.api 中使用

Windows下Python安装numpy+mkl,Scipy和statsmodels