更新以反映截至2018年秋季的Fama-MacBeth的库状况。此
fama_macbeth功能已删除
pandas了一段时间。那么您有什么选择呢?
如果您使用的是python 3,则可以在LinearModels中使用Fama-MacBeth方法:https : //github.com/bashtage/linearmodels/blob/master/linearmodels/panel/model.py
如果您使用的是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显式转换为…在当前版本的
pandas0.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)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)