Skip to content

8.4 随机效应模型(Random Effects Model)

效率与一致性的权衡:何时随机效应优于固定效应?

难度重要性


本节目标

  • 理解随机效应(RE)模型的数学原理
  • 掌握 GLS 估计方法
  • 区分 FE 和 RE 的核心假设差异
  • 实施 Hausman 检验选择 FE vs RE
  • 理解 RE 的效率优势和一致性风险
  • 使用 linearmodels.RandomEffects 实现 RE 回归
  • 完整案例:公司资本结构决定

随机效应的核心思想

FE vs RE:关键区别

固定效应(FE)

  • 固定参数(每个个体有自己的参数)
  • 允许 相关:
  • 估计方法:差分消除

随机效应(RE)

  • 随机变量
  • 假设 不相关
  • 估计方法:广义最小二乘(GLS)

为什么叫"随机"效应?

直觉

  • FE: 是个体 固有特征(固定的)
  • RE: 是从总体分布中随机抽取的(随机的)

统计含义

  • FE: 是待估计的 个参数
  • RE: 不需要估计,只需估计其方差

类比

  • FE:像"固定截距"模型,每个个体有自己的截距
  • RE:像"分层模型",个体截距服从某个分布

随机效应模型的数学表达

标准 RE 模型

符号定义

  • :个体随机效应(不可观测)
  • :随机误差项
  • :两者独立
  • 关键假设(外生性)

复合误差项

因此,模型可以写成:


复合误差的方差-协方差结构

方差

协方差(同一个体不同时间):

组内相关系数(Intra-class Correlation):

解释

  • :同一个体不同时间观测值的相关性
  • :无个体效应,退化为混合 OLS
  • :误差完全由个体效应决定

随机效应的估计:GLS

为什么不能用 OLS?

问题:复合误差 存在序列相关

  • 同一个体不同时间的误差相关:
  • 违反了 OLS 的独立性假设

后果

  • OLS 系数仍然无偏(如果
  • 标准误有偏(低估)→ 统计量虚高

广义最小二乘(GLS)

核心思想:对数据进行变换,使得变换后的误差满足 OLS 假设

步骤 1:构造变换

准去均值变换(Quasi-Demeaning):

其中:

特殊情况

  • 如果 (无个体效应): → 混合 OLS
  • 如果 (个体效应主导): → 固定效应(组内变换)

直觉

  • RE 是 FE 和混合 OLS 的加权平均
  • 权重 取决于个体效应的相对重要性

步骤 2:OLS 估计变换后的数据

这就是随机效应估计量(RE Estimator)


可行 GLS(FGLS)

问题 依赖于未知参数

解决方案:两步估计

  1. 步骤 1:估计方差分量

    • 运行混合 OLS 或 FE,得到残差
    • 计算
  2. 步骤 2:用估计的方差计算 ,进行 GLS

Python 实现:linearmodels 自动进行 FGLS


FE vs RE:深入对比

对比表

维度固定效应(FE)随机效应(RE)
个体效应(固定参数)(随机变量)
核心假设允许 相关要求
估计方法组内变换(Within)GLS
利用的变异仅组内(Within)组内 + 组间(Both)
效率相对低(只用组内变异)相对高(用全部变异)
一致性一致(即使 相关)仅当 时一致
时不变变量无法估计可以估计
适用场景 相关(内生性) 不相关(外生性)

核心权衡:效率 vs 一致性

一致性(Consistency)

  • 样本量增大时,估计量收敛到真实参数

效率(Efficiency)

  • 估计量的方差更小(标准误更小)

权衡

  • FE:一致(即使内生),但效率低(只用组内变异)
  • RE:效率高(用全部变异),但如果 相关则不一致

决策规则

  • 如果 :RE 更优(更有效)
  • 如果 相关:FE 更优(一致)
  • 关键:如何判断?→ Hausman 检验

Hausman 检验:FE vs RE 的决策工具

Hausman 检验的逻辑

核心问题 是否相关?

原假设

对立假设

检验统计量

其中 是自变量数量

直觉

  • 如果 成立(),FE 和 RE 都一致,估计应该接近
  • 如果 成立( 相关),FE 一致但 RE 不一致,估计会有显著差异

决策规则

  • :拒绝 → 使用 FE
  • :接受 → 使用 RE

Python 实现:Hausman 检验

python
import numpy as np
import pandas as pd
from linearmodels.panel import PanelOLS, RandomEffects, compare
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']

# 模拟数据:$u_i$ 与 $X$ 相关(FE 应该胜出)
np.random.seed(123)

N = 200
T = 5

data = []
for i in range(N):
    # 个体效应
    u_i = np.random.normal(0, 1)

    for t in range(T):
        # X 与 u_i 相关(违反 RE 假设!)
        x = 10 + 0.5 * u_i + np.random.normal(0, 2)

        # Y
        y = 5 + 2 * x + u_i + np.random.normal(0, 1)

        data.append({'id': i, 'year': 2015 + t, 'y': y, 'x': x})

df = pd.DataFrame(data)
df_panel = df.set_index(['id', 'year'])

# 估计 FE 和 RE
model_fe = PanelOLS(df_panel['y'], df_panel[['x']],
                    entity_effects=True).fit(cov_type='clustered',
                                             cluster_entity=True)

model_re = RandomEffects(df_panel['y'], df_panel[['x']]).fit()

print("=" * 70)
print("FE vs RE 估计结果")
print("=" * 70)
print(f"真实参数:  2.0000")
print(f"FE 估计:   {model_fe.params['x']:.4f}")
print(f"RE 估计:   {model_re.params['x']:.4f}")

# Hausman 检验(手动实现)
beta_diff = model_fe.params['x'] - model_re.params['x']
var_diff = model_fe.cov['x']['x'] - model_re.cov['x']['x']
hausman_stat = (beta_diff ** 2) / var_diff

from scipy.stats import chi2
p_value = 1 - chi2.cdf(hausman_stat, df=1)

print("\n" + "=" * 70)
print("Hausman 检验")
print("=" * 70)
print(f"H 统计量:  {hausman_stat:.3f}")
print(f"p 值:      {p_value:.4f}")

if p_value < 0.05:
    print("结论:      拒绝 H0,应使用 FE(RE 不一致)")
else:
    print("结论:      接受 H0,应使用 RE(RE 一致且更有效)")

# 使用 linearmodels 内置的对比功能
print("\n" + "=" * 70)
print("linearmodels 内置对比")
print("=" * 70)
comparison = compare({'FE': model_fe, 'RE': model_re})
print(comparison)

输出解读

  • 如果 :FE 和 RE 差异显著 → 使用 FE
  • 如果 :FE 和 RE 差异不显著 → 使用 RE(更有效)

实践中的建议

保守策略(推荐):

  1. 同时报告 FE 和 RE
  2. 进行 Hausman 检验
  3. 以 FE 为主要结果(因为内生性很常见)

例外情况(可优先用 RE)

  • 教育研究:学生随机分配到学校
  • 医学研究:患者随机分配到医院
  • 抽样调查:个体从总体中随机抽取

经济学研究

  • 通常使用 FE(因为内生性几乎总是存在)
  • RE 常用于稳健性检验

️ linearmodels.RandomEffects

基本语法

python
from linearmodels.panel import RandomEffects

# 设置面板索引
df_panel = df.set_index(['id', 'year'])

# 随机效应回归
model_re = RandomEffects(
    dependent=df_panel['y'],
    exog=df_panel[['x1', 'x2']]
).fit()

print(model_re)

完整示例:公司资本结构

python
import numpy as np
import pandas as pd
from linearmodels.panel import PanelOLS, RandomEffects
from statsmodels.iolib.summary2 import summary_col

# 模拟公司面板数据
np.random.seed(2024)

N = 300  # 300 家公司
T = 10   # 10 年

data = []
for i in range(N):
    # 公司固定效应(管理风格、行业特征等)
    company_effect = np.random.normal(0, 0.1)

    # 行业(时不变)
    industry = np.random.choice(['制造业', '服务业', '科技'], p=[0.4, 0.3, 0.3])

    for t in range(T):
        year = 2010 + t

        # 盈利能力(ROA)
        roa = 0.05 + company_effect * 0.5 + np.random.normal(0, 0.02)

        # 公司规模(log(资产))
        log_assets = 10 + 0.1 * t + np.random.normal(0, 0.5)

        # 成长机会(Tobin's Q)
        tobins_q = 1.5 + np.random.normal(0, 0.3)

        # 杠杆率(因变量)
        # 真实参数:roa=-0.3, log_assets=0.05, tobins_q=-0.1
        leverage = (0.3 - 0.3 * roa + 0.05 * log_assets -
                    0.1 * tobins_q + company_effect + np.random.normal(0, 0.05))

        data.append({
            'company_id': i,
            'year': year,
            'leverage': leverage,
            'roa': roa,
            'log_assets': log_assets,
            'tobins_q': tobins_q,
            'industry': industry
        })

df = pd.DataFrame(data)

# 行业虚拟变量
df = pd.get_dummies(df, columns=['industry'], drop_first=True)

print("=" * 70)
print("公司资本结构研究")
print("=" * 70)
print(f"样本量: {len(df):,}")
print(f"公司数: {df['company_id'].nunique()}")
print(f"时间跨度: {df['year'].min()} - {df['year'].max()}")

# 设置面板索引
df_panel = df.set_index(['company_id', 'year'])

# 模型 1:混合 OLS
import statsmodels.api as sm
X1 = sm.add_constant(df[['roa', 'log_assets', 'tobins_q']])
model_pooled = sm.OLS(df['leverage'], X1).fit()

# 模型 2:固定效应
model_fe = PanelOLS(df_panel['leverage'],
                    df_panel[['roa', 'log_assets', 'tobins_q']],
                    entity_effects=True).fit(cov_type='clustered',
                                             cluster_entity=True)

# 模型 3:随机效应
model_re = RandomEffects(df_panel['leverage'],
                         df_panel[['roa', 'log_assets', 'tobins_q']]).fit()

# 模型 4:RE + 行业虚拟变量(利用 RE 可以估计时不变变量的优势)
model_re_industry = RandomEffects(
    df_panel['leverage'],
    df_panel[['roa', 'log_assets', 'tobins_q', 'industry_服务业', 'industry_科技']]
).fit()

# Hausman 检验
from scipy.stats import chi2
beta_diff = model_fe.params - model_re.params
var_diff = model_fe.cov - model_re.cov
hausman_stat = float(beta_diff.T @ np.linalg.inv(var_diff) @ beta_diff)
p_value = 1 - chi2.cdf(hausman_stat, df=len(beta_diff))

print("\n" + "=" * 70)
print("Hausman 检验")
print("=" * 70)
print(f"H 统计量: {hausman_stat:.3f}")
print(f"p 值:     {p_value:.4f}")
print(f"结论:     {'使用 FE' if p_value < 0.05 else '使用 RE'}")

# 对比结果
print("\n" + "=" * 70)
print("回归结果对比")
print("=" * 70)

results = summary_col([model_pooled, model_fe, model_re],
                      stars=True,
                      float_format='%.4f',
                      model_names=['混合 OLS', 'FE', 'RE'],
                      info_dict={
                          'N': lambda x: f"{int(x.nobs):,}"
                      })
print(results)

print("\n" + "=" * 70)
print("RE + 行业虚拟变量(利用 RE 的优势)")
print("=" * 70)
print(model_re_industry.summary)

# 解释系数
print("\n" + "=" * 70)
print("经济学解释")
print("=" * 70)
print(f"ROA 系数(FE):    {model_fe.params['roa']:.4f}")
print("  → 盈利能力提高 1%,杠杆率降低 {:.2f} 个百分点".format(-model_fe.params['roa'] * 100))
print(f"\nlog(资产) 系数(FE): {model_fe.params['log_assets']:.4f}")
print("  → 公司规模翻倍(log 增加 0.693),杠杆率提高 {:.2f} 个百分点".format(
    model_fe.params['log_assets'] * 0.693 * 100))

输出解读

  1. Hausman 检验:如果拒绝,使用 FE;否则使用 RE
  2. RE 的优势:可以估计行业虚拟变量(时不变)
  3. 经济学含义
    • ROA 系数为负:高盈利公司减少负债(pecking order theory)
    • 规模系数为正:大公司更容易获得债务融资

RE 的优势场景

场景 1:估计时不变变量

例子:研究性别工资差距

python
# FE 无法估计性别(时不变)
# model_fe = PanelOLS(log_wage, education + gender, entity_effects=True).fit()
# → gender 系数无法估计(被差分消除)

# RE 可以估计性别
model_re = RandomEffects(log_wage, education + gender).fit()
# → gender 系数可以估计

注意:只有在性别与个体效应不相关时,RE 估计才一致


场景 2:组内变异很小

例子:研究教育对工资的影响(短面板)

如果面板时间跨度短(如 2-3 年),教育水平几乎不变:

  • FE 只利用组内变异(几乎为 0)→ 标准误很大
  • RE 利用组间变异(很大)→ 更精确

权衡

  • FE:一致但不精确
  • RE:精确但可能不一致(如果存在内生性)

场景 3:随机抽样

例子:从全国学校中随机抽取 100 所学校

如果学校是随机抽取的,学校效应 与学生特征 不太可能相关

  • RE 假设更合理
  • RE 估计更有效

对比

  • 如果研究特定的 100 所学校(非随机),FE 更合适

本节小结

核心要点

  1. RE 的本质

    • 个体效应是随机变量,从分布中抽取
    • 核心假设:(外生性)
  2. GLS 估计

    • 准去均值变换: 取决于方差比
    • RE 是 FE 和混合 OLS 的加权平均
  3. FE vs RE

    • 效率:RE > FE(利用全部变异)
    • 一致性:FE 总是一致,RE 仅当 时一致
    • 时不变变量:FE 无法估计,RE 可以
  4. Hausman 检验

    • 检验 是否相关
    • :使用 FE
    • :使用 RE
  5. 实践建议

    • 经济学研究:优先 FE(内生性常见)
    • 教育/医学研究:考虑 RE(随机抽样)
    • 稳健性检验:同时报告 FE 和 RE
  6. RE 的优势场景

    • 需要估计时不变变量
    • 组内变异很小
    • 个体随机抽样

决策树

开始

需要估计时不变变量?
  ↓ 是
  使用 RE(如果 Hausman 检验通过)
  ↓ 否
估计 FE 和 RE,进行 Hausman 检验

Hausman 检验 p < 0.05?
  ↓ 是
  使用 FE(RE 不一致)
  ↓ 否
  使用 RE(更有效)

下一步

第5节:面板数据高级专题 中,我们将学习:

  • 双向固定效应(Two-Way FE)详解
  • 聚类标准误的正确使用
  • 动态面板模型(Arellano-Bond)
  • 不平衡面板的处理

效率与一致性的智慧选择!

基于 MIT 许可证发布。内容版权归作者所有。