第 7 章 · 02 Fama-MacBeth


文档摘要

第 7 章 · 02 Fama-MacBeth 本节摘要:本节讲金融面板数据专用的回归方法——Fama-MacBeth 两阶段横截面回归。普通 OLS 假设误差独立,但金融面板(很多资产 × 很多期)的残差在同一期跨资产高度相关,直接 OLS 标准误偏小、t 值虚高。Fama 和 MacBeth 在 1973 年提出两阶段法:第一阶段对每个资产做时间序列回归估「因子暴露 β」;第二阶段对每个时间点做横截面回归,把收益对 β 回归估「风险溢价 λ」。最后把所有期的 λ 取平均、用各期 λ 的标准差算 t 值,自然处理了横截面相关。本节用 Fama-French 五因子 + 17 行业组合演示完整流程,并对照 linearmodels 库的一行实现。 内容来源:原项目 ,汉化并套用体系化模板。

第 7 章 · 02 Fama-MacBeth

本节摘要:本节讲金融面板数据专用的回归方法——Fama-MacBeth 两阶段横截面回归。普通 OLS 假设误差独立,但金融面板(很多资产 × 很多期)的残差在同一期跨资产高度相关,直接 OLS 标准误偏小、t 值虚高。Fama 和 MacBeth 在 1973 年提出两阶段法:第一阶段对每个资产做时间序列回归估「因子暴露 β」;第二阶段对每个时间点做横截面回归,把收益对 β 回归估「风险溢价 λ」。最后把所有期的 λ 取平均、用各期 λ 的标准差算 t 值,自然处理了横截面相关。本节用 Fama-French 五因子 + 17 行业组合演示完整流程,并对照 linearmodels 库的一行实现。

内容来源:原项目 ch07/02_fama_macbeth.ipynb,汉化并套用体系化模板。

⚠️ 风险提示:风险溢价估计对样本期高度敏感,某段历史的正溢价可能在下一段消失。t 值显著不代表稳健,要做子样本稳定性分析。

学习目标

阅读完本节,你应当能够:

  1. 说清金融面板残差横截面相关为何让普通 OLS 失效。
  2. 描述 Fama-MacBeth 两阶段:时间序列回归估 β,横截面回归估 λ。
  3. 用循环手动实现两阶段回归并算 t 值。
  4. 解读 Fama-French 五因子(SMB/HML/RMW/CMA/Rm-Rf)。
  5. linearmodels.LinearFactorModel 一行跑 Fama-MacBeth。

一、为什么需要 Fama-MacBeth

线性因子模型假设资产超额收益是因子暴露 × 因子溢价:

E[R_i - R_f] = \beta_i^\top \lambda

要估的是 β(暴露)和 λ(溢价)。最朴素的做法是把这个面板数据(资产 × 时间)直接丢进 OLS。问题是:

同一时期所有股票受共同的宏观冲击(如加息、衰退),残差跨资产相关。OLS 假设残差独立,会严重低估标准误,把不显著的因子误判为显著。Fama-MacBeth 通过「先时间序列后横截面」的两阶段设计,自然处理这种横截面相关。

💡 核心心法:Fama-MacBeth 的精髓是用横截面回归系数的时间序列标准差来估标准误——这天然吸收了横截面相关,不需要显式建模协方差。

二、Fama-French 五因子

notebook 用 Fama-French 五因子做演示,这是学术界最常用的多因子模型:

因子 全称 含义
SMB Small Minus Big 小盘股减大盘股(规模因子)
HML High Minus Low 高账面市值比减低(价值因子)
RMW Robust Minus Weak 强盈利减弱盈利(盈利因子)
CMA Conservative Minus Aggressive 保守投资减激进投资(投资因子)
Rm-Rf 市场超额 全市场收益减无风险利率(市场因子)

通过 pandas_datareader 直接从 Ken French 数据库取:

import pandas_datareader.data as web ff_factor = 'F-F_Research_Data_5_Factors_2x3' ff_factor_data = web.DataReader(ff_factor, 'famafrench', start='2010', end='2017-12')[0]

测试资产用 17 行业组合,减去无风险利率得到超额收益:

ff_portfolio_data = web.DataReader('17_Industry_Portfolios', 'famafrench', start='2010', end='2017-12')[0] ff_portfolio_data = ff_portfolio_data.sub(ff_factor_data.RF, axis=0)

三、两阶段实现

第一阶段:时间序列回归估 β

对每个资产(行业组合),把它的时间序列收益对因子时间序列回归,得到该资产对各因子的暴露 β:

from statsmodels.api import OLS, add_constant betas = [] for industry in ff_portfolio_data: step1 = OLS(endog=ff_portfolio_data.loc[ff_factor_data.index, industry], exog=add_constant(ff_factor_data)).fit() betas.append(step1.params.drop('const')) betas = pd.DataFrame(betas, columns=ff_factor_data.columns, index=ff_portfolio_data.columns)

得到一个 17(资产)× 5(因子)的 β 矩阵——每个行业对各因子的暴露。

第二阶段:横截面回归估 λ

对每个时间点,把当期 17 个资产的收益对它们的 β 做横截面回归,得到该期的因子溢价 λ:

lambdas = [] for period in ff_portfolio_data.index: step2 = OLS(endog=ff_portfolio_data.loc[period, betas.index], exog=betas).fit() lambdas.append(step2.params) lambdas = pd.DataFrame(lambdas, index=ff_portfolio_data.index, columns=betas.columns.tolist())

得到一个 96(月份数)× 5(因子)的 λ 矩阵——每个时期各因子的瞬时溢价。

平均溢价与 t 值

lambdas.mean().sort_values().plot.barh(figsize=(12, 4)) # 平均风险溢价 t = lambdas.mean().div(lambdas.std()) # t 统计量

💡 t 值的计算:Fama-MacBeth 的标准误 = 各期 λ 的时间序列标准差 / √T。这等价于 mean / std * sqrt(T),但 notebook 用简化形式 mean / std 做相对比较。t > 2(粗略)视为显著。

四、两阶段的几何直觉

五、用 linearmodels 一行实现

手动循环有助于理解,但实务用 linearmodels.LinearFactorModel,一行就跑完两阶段并给出完整推断:

from linearmodels.asset_pricing import LinearFactorModel mod = LinearFactorModel(portfolios=ff_portfolio_data, factors=ff_factor_data) res = mod.fit() print(res) print(res.full_summary)

输出含每个因子的风险溢价估计、t 值、各组合的 α(无法被因子解释的超额),以及 J 检验(模型整体显著性)。结果与手动实现一致,但统计推断更严谨(用了 Newey-West 等稳健标准误)。

六、实务考量

问题 应对
β 时变性 β 不是常数,可用滚动窗口估,或用 conditionally linear model
样本期敏感 拆子样本分别跑,画 lambdas.rolling(24).mean() 看稳定性
测试资产选择 行业/规模/价值组合是经典选择,自建因子要确保足够分散
多重共线 因子间相关性高时,β 估计不稳,可先做因子正交化

notebook 用 24 个月滚动平均画 λ 的时变曲线,常发现某个溢价在某段显著正、另一段反转——这正是金融「显著性」的脆弱性。

本节要点回顾

  1. 横截面残差相关:同一期所有资产共受宏观冲击,普通 OLS 标准误偏小、t 虚高。
  2. 两阶段:第一阶段对每资产做时间序列回归估 β;第二阶段对每期做横截面回归估 λ。
  3. 标准误:用各期 λ 的时间序列标准差,天然吸收横截面相关。
  4. Fama-French 五因子:SMB/HML/RMW/CMA/Rm-Rf,学术标准多因子模型。
  5. linearmodels.LinearFactorModel 一行实现,带稳健标准误和 J 检验,实务首选。

下一节,我们实战用线性模型(Ridge/Lasso)预测股票横截面收益,并用 MultipleTimeSeriesCV 做严格评估。


发布者: 作者: 灏天文库 转发
评论区 (0)
U