use*_*212 7 python r pandas statsmodels
计量经济学背景
Fama Macbeth回归指的是针对面板数据运行回归的过程(其中存在N个不同的个体并且每个个体对应于多个周期T,例如日,月,年).所以总共有N x T obs.请注意,如果面板数据不平衡,则可以.
Fama Macbeth回归是首先对每个时期进行跨部门的回归,即在给定的时间段内将N个人聚集在一起.为t = 1,...做这个.因此总共运行T回归.然后我们有每个自变量的时间序列系数.然后我们可以使用系数的时间序列进行假设检验.通常我们将平均值作为每个自变量的最终系数.我们使用t-stats来测试重要性.
我的问题
我的问题是在熊猫中实现这一点.从大熊猫的源代码中,我注意到有一个名为的过程fama_macbeth.但我找不到任何关于此的文件.
操作也可以轻松完成groupby.目前我这样做:
def fmreg(data,formula):
return smf.ols(formula,data=data).fit().params[1]
res=df.groupby('date').apply(fmreg,'ret~var1')
Run Code Online (Sandbox Code Playgroud)
这是有效的,res是一个由系数索引date的系列和系列的值params[1],它是系数var1.但现在我想拥有更多自变量,我需要提取所有这些自变量的系数,但我无法弄清楚.我试过这个
def fmreg(data,formula):
return smf.ols(formula,data=data).fit().params
res=df.groupby('date').apply(fmreg,'ret~var1+var2+var3')
Run Code Online (Sandbox Code Playgroud)
这不行.期望的结果是,res是由索引的数据帧date,以及数据帧的每列应包含各变量的系数intercept,var1,var2和var3.
我也检查过statsmodels,他们也没有这样的内置程序.
是否有任何包可以产生出版品质的回归表?就像outreg2在Stata和texregR?谢谢你的帮助!
更新以反映Fama-MacBeth截至2018年秋季的图书馆情况.该fama_macbeth功能现已删除pandas了一段时间.那么你有什么选择呢?
如果你正在使用python 3,那么您可以使用LinearModels法玛-麦克白方法: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 smf
In [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 r36to13
18432 Aero 1995-07-01 6.26 0.9696 0.2755 0.3466
18433 Agric 1995-07-01 3.37 1.0412 0.1260 0.0581
18434 Autos 1995-07-01 2.42 1.0274 0.0293 0.2902
18435 Banks 1995-07-01 4.82 1.4985 0.1659 0.2951
Run Code Online (Sandbox Code Playgroud)
Fama-MacBeth主要涉及逐月计算相同的横截面回归模型,因此您可以使用a来实现它groupby.你可以创建一个函数,它接受dataframe(它将来自groupby)和一个patsy公式; 然后它适合模型并返回参数估计值.这里是你如何能够实现它(注意这是一个准系统版本是什么原来的提问试着做了几年前......不知道为什么它没有工作,虽然它可能当时statsmodels导致对象的方法params没有一个返回pandas Series所以返回需要转换为Series显式...它在当前版本的pandas0.23.4 中工作正常:
def ols_coef(x,formula):
return smf.ols(formula,data=x).fit().params
In [9]: gamma = (df.groupby('caldt')
.apply(ols_coef,'ret ~ 1 + beta + r12to2 + r36to13'))
gamma.head()
In [10]: Out[10]:
Intercept beta r12to2 r36to13
caldt
1963-07-01 -1.497012 -0.765721 4.379128 -1.918083
1963-08-01 11.144169 -6.506291 5.961584 -2.598048
1963-09-01 -2.330966 -0.741550 10.508617 -4.377293
1963-10-01 0.441941 1.127567 5.478114 -2.057173
1963-11-01 3.380485 -4.792643 3.660940 -1.210426
Run Code Online (Sandbox Code Playgroud)
然后计算平均值,平均值的标准误差和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 tstat
Intercept 0.754904 0.177291 4.258000
beta -0.012176 0.202629 -0.060092
r12to2 1.794548 0.356069 5.039896
r36to13 0.237873 0.186680 1.274230
Run Code Online (Sandbox Code Playgroud)
提高速度
使用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)
Run Code Online (Sandbox Code Playgroud)
如果您仍在使用旧版本pandas,则以下内容将起作用:
以下是使用该fama_macbeth函数的示例pandas:
>>> df
y x
date id
2012-01-01 1 0.1 0.4
2 0.3 0.6
3 0.4 0.2
4 0.0 1.2
2012-02-01 1 0.2 0.7
2 0.4 0.5
3 0.2 0.1
4 0.1 0.0
2012-03-01 1 0.4 0.8
2 0.6 0.1
3 0.7 0.6
4 0.4 -0.1
Run Code Online (Sandbox Code Playgroud)
注意,结构.该fama_macbeth函数期望y-var和x-vars具有多索引,其中date作为第一个变量,stock/firm/entity 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---------------------------------
Run Code Online (Sandbox Code Playgroud)
请注意,只需打印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---------------------------------
Run Code Online (Sandbox Code Playgroud)
另外,请注意该fama_macbeth函数会自动添加一个截距(与statsmodels例程相对).x-var也必须dataframe如此,如果只传递一列,则需要传递它df[['x']].
如果你不想要拦截,你必须这样做:
>>> fm = pd.fama_macbeth(y=df['y'],x=df[['x']],intercept=False)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8370 次 |
| 最近记录: |