Python中的Fama Macbeth回归(pandas或Statsmodels)

Python中的Fama Macbeth回归(pandas或Statsmodels),第1张

Python中的Fama Macbeth回归(pandas或Statsmodels)

更新以反映截至2018年秋季的Fama-MacBeth的库状况。此

fama_macbeth
功能已删除
pandas
了一段时间。那么您有什么选择呢?

  1. 如果您使用的是python 3,则可以在LinearModels中使用Fama-MacBeth方法:https : //github.com/bashtage/linearmodels/blob/master/linearmodels/panel/model.py

  2. 如果您使用的是python 2或只是不想使用LinearModels,那么最好的选择就是自己动手。

例如,假设您在类似以下的面板中拥有Fama-French行业投资组合(您还计算了一些变量,例如过往的beta或过往的收益用作x变量):

In [1]: import pandas as pd        import numpy as np        import statsmodels.formula.api as smfIn [4]: df = pd.read_csv('industry.csv',parse_dates=['caldt'])        df.query("caldt == '1995-07-01'")In [5]: Out[5]:       industry      caldt    ret    beta  r12to2  r36to1318432     Aero 1995-07-01   6.26  0.9696  0.2755   0.346618433    Agric 1995-07-01   3.37  1.0412  0.1260   0.058118434    Autos 1995-07-01   2.42  1.0274  0.0293   0.290218435    Banks 1995-07-01   4.82  1.4985  0.1659   0.2951

Fama-
MacBeth主要涉及逐月计算相同的横截面回归模型,因此您可以使用来实现

groupby
。您可以创建一个函数
dataframe
(该函数来自
groupby
)和
patsy
公式;然后拟合模型并返回参数估计值。这是如何实现它的准系统版本(请注意,这是几年前原始提问者试图做的事情……不确定为什么它不起作用,尽管可能那时
statsmodels
结果对象方法
params
未返回
pandas

Series
因此需要将返回值
Series
显式转换为…在当前版本的
pandas
0.23.4中确实可以正常工作):

def ols_coef(x,formula):    return smf.ols(formula,data=x).fit().paramsIn [9]: gamma = (df.groupby('caldt')     .apply(ols_coef,'ret ~ 1 + beta + r12to2 + r36to13'))        gamma.head()In [10]: Out[10]:  Intercept      beta     r12to2   r36to13caldt   1963-07-01  -1.497012 -0.765721   4.379128 -1.9180831963-08-01  11.144169 -6.506291   5.961584 -2.5980481963-09-01  -2.330966 -0.741550  10.508617 -4.3772931963-10-01   0.441941  1.127567   5.478114 -2.0571731963-11-01   3.380485 -4.792643   3.660940 -1.210426

然后只需计算均值,均值的标准误和t检验(或所需的任何统计数据)即可。类似于以下内容:

def fm_summary(p):    s = p.describe().T    s['std_error'] = s['std']/np.sqrt(s['count'])    s['tstat'] = s['mean']/s['std_error']    return s[['mean','std_error','tstat']]In [12]: fm_summary(gamma)Out[12]:     mean  std_error     tstatIntercept  0.754904   0.177291  4.258000beta      -0.012176   0.202629 -0.060092r12to2     1.794548   0.356069  5.039896r36to13    0.237873   0.186680  1.274230

提高速度

使用

statsmodels
的回归有显著的开销(特别是考虑到你只需要估计系数)。如果您想提高效率,则可以从切换
statsmodels
numpy.linalg.lstsq
。编写一个执行ols估计的新函数…类似以下内容(注意,我没有做类似检查这些矩阵的等级的 *** 作…):

def ols_np(data,yvar,xvar):    gamma,_,_,_ = np.linalg.lstsq(data[xvar],data[yvar],rcond=None)    return pd.Series(gamma)

如果您仍在使用旧版本的

pandas
,则可以使用以下功能:

这是在中使用

fama_macbeth
函数的示例
pandas

>>> df     y    xdate       id2012-01-01 1   0.1  0.42   0.3  0.63   0.4  0.24   0.0  1.22012-02-01 1   0.2  0.72   0.4  0.53   0.2  0.14   0.1  0.02012-03-01 1   0.4  0.82   0.6  0.13   0.7  0.64   0.4 -0.1

注意,结构。该

fama_macbeth
函数期望y-var和x-vars具有一个以日期为第一个变量,以股票/公司/实体id为第二个变量的多重索引:

>>> fm  = pd.fama_macbeth(y=df['y'],x=df[['x']])>>> fm----------------------Summary of Fama-MacBeth Analysis-------------------------Formula: Y ~ x + intercept# betas :   3----------------------Summary of Estimated Coefficients------------------------     Variable          Beta       Std Err        t-stat       CI 2.5%      CI 97.5%          (x)       -0.0227        0.1276         -0.18       -0.2728        0.2273  (intercept)        0.3531        0.0842          4.19        0.1881        0.5181--------------------------------End of Summary---------------------------------

请注意,仅打印

fm
调用fm.summary

>>> fm.summary----------------------Summary of Fama-MacBeth Analysis-------------------------Formula: Y ~ x + intercept# betas :   3----------------------Summary of Estimated Coefficients------------------------     Variable          Beta       Std Err        t-stat       CI 2.5%      CI 97.5%          (x)       -0.0227        0.1276         -0.18       -0.2728        0.2273  (intercept)        0.3531        0.0842          4.19        0.1881        0.5181--------------------------------End of Summary---------------------------------

另外,请注意,该

fama_macbeth
函数会自动添加一个拦截器(与
statsmodels
例程相反)。而且x-
var必须是a,
dataframe
因此,如果您仅传递一列,则需要将其传递为
df[['x']]

如果您不想拦截,则必须执行以下 *** 作:

>>> fm  = pd.fama_macbeth(y=df['y'],x=df[['x']],intercept=False)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5508027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存