机器学习与因果推断 - 第五讲:工具变量法
处理未观测混淆变量的识别策略:完整讲义
1 引言:当匹配法失效时
1.1 匹配法的局限
匹配法的核心假设是条件可忽略性:
这要求所有混淆变量都被观测到。但在实践中,许多重要因素无法观测:
- 能力:认知能力、非认知能力
- 动机:求职动机、学习动机
- 偏好:风险偏好、时间偏好
- 信息:信息获取渠道、网络资源
当存在未观测混淆变量时,匹配法无法消除选择偏差。
1.2 内生性问题的来源
在回归框架下,内生性意味着处理变量与误差项相关:
造成内生性的三个主要原因:
- 遗漏变量:未观测的混淆因素同时影响 和
- 双向因果: 和 互相影响( simultaneity)
- 测量误差: 被错误测量,导致衰减偏误
1.3 工具变量的启示
核心问题:当 与 相关时,OLS 估计有偏且不一致。我们需要一种方法,能够利用 中与 无关的变异部分。
工具变量法的洞察:
找到一个变量 ,它:
- 与 相关(提供变异)
- 与 不相关(外生性)
- 只通过 影响 (排他性)
这样的 提供了 中”干净”的变异,使我们能够识别因果效应。
2 工具变量的两个条件
2.1 条件一:相关性(Relevance)
定义:工具变量 必须与处理变量 相关。
这保证了 能够产生足够的变异来”撬动” 。
2.1.1 第一阶段回归
相关性条件可以通过第一阶段回归来检验:
其中 是第一阶段系数。我们需要 。
2.1.2 F统计量检验
Stock & Yogo (2005) 提出使用第一阶段F统计量检验工具变量强度:
经验法则: 表示工具变量足够强。
2.2 条件二:排他性(Exclusion Restriction)
定义:工具变量 必须满足:
这意味着 只通过 影响 ,没有其他直接或间接路径。
2.2.1 排他性的直观理解
排他性约束要求 是一个”奇怪”的变量——它与结果 相关,但仅仅是因为它影响了处理 。
例子:
- 出生季度影响教育年数(通过义务教育法),但不直接影响收入
- 到大学的距离影响上学决策,但不直接影响收入能力
- 抽签号码影响是否入伍,但不直接影响未来收入
2.2.2 排他性无法直接检验
重要警告
排他性是一个基于理论和领域知识的假设,无法直接用数据检验。研究者需要论证为什么 满足排他性。
可能的威胁: - 通过其他变量影响 (违反排他性) - 与未观测混淆变量相关(违反外生性)
2.3 工具变量的因果图
Z ──→ D ──→ Y
↑ ↑
└─────┘
U (未观测混淆)
在这个图中:
- 是未观测混淆变量,造成 和 的内生关联
- 提供了一个外生变异,绕过 的影响
- 只影响 通过 (没有其他路径)
关键洞察:工具变量 提供的变异与 无关,因此使用 诱导的变异可以消除选择偏差。
3 两阶段最小二乘法(2SLS)
3.1 2SLS的直观理解
基本思想:
- 第一阶段:用 预测 ,得到 中由 解释的部分
- 第二阶段:用预测的 代替 估计对 的效应
为什么这样可行?
- 只包含 中与 相关的变异
- 由于 是外生的, 也是外生的
- 用 估计的效应没有内生性偏误
3.2 2SLS的数学推导
3.2.1 第一阶段
得到拟合值:
3.2.2 第二阶段
3.2.3 IV估计量的等价形式
可以证明,2SLS估计量等价于Wald估计量:
这个公式揭示了IV估计的直观含义:
- 分子 (): 对 的总效应(简约式)
- 分母 (): 对 的效应(第一阶段)
- 比值: 对 的因果效应
3.3 2SLS估计量的一致性
在工具变量相关性和排他性条件下:
证明概要:
由于 (排他性),第二项趋于零,因此 。
3.4 2SLS与OLS的关系
重要性质:当 (正的选择偏差)时:
- OLS 估计:
- 2SLS 估计:(一致)
这意味着在有正选择偏差的情况下,OLS 会高估处理效应,而2SLS提供了一致的估计。
4 弱工具变量问题
4.1 什么是弱工具变量?
定义:当工具变量 与处理变量 的相关性很弱时,即:
或第一阶段F统计量很小()。
4.2 弱工具变量的后果
4.2.1 1. 方差增大
IV估计量的方差为:
当 时,。
4.2.2 2. 偏差严重
Bound, Jaeger & Baker (1995) 证明:
当 时,偏差趋近于 OLS 偏差!
4.2.3 3. 分布非正态
弱工具变量下,2SLS估计量的抽样分布不再是正态分布,基于正态分布的假设检验失效。
4.3 弱工具变量的识别与应对
4.3.1 识别弱工具变量
经验法则 (Stock & Yogo, 2005):
| F统计量 | 解释 |
|---|---|
| 弱工具变量警告 | |
| 工具变量强度可接受 | |
| 最大相对偏差 ≤ 10%(1个工具变量) |
4.3.2 应对策略
- 寻找更强的工具变量
- 使用弱工具变量稳健方法:
- Anderson-Rubin 检验
- Kleibergen-Paap 统计量
- 条件似然比(CLR)检验
- 使用LIML(Limited Information Maximum Likelihood):比2SLS更稳健
- 增加样本量:提高统计功效
5 局部平均处理效应(LATE)
5.1 异质性处理效应框架
当处理效应在不同个体间存在异质性时,我们需要扩展潜在结果框架。
定义潜在处理变量:
- :当 时个体 的处理状态
- :当 时个体 的处理状态
四种个体类型 (Imbens & Angrist, 1994):
| 类型 | 定义 | 描述 | ||
|---|---|---|---|---|
| Always-takers | 总是接受处理 | 1 | 1 | 无论工具变量如何都接受处理 |
| Never-takers | 从不接受处理 | 0 | 0 | 无论工具变量如何都不接受处理 |
| Compliers | 依从者 | 1 | 0 | 工具变量=1时接受,工具变量=0时不接受 |
| Defiers | 违背者 | 0 | 1 | 工具变量=1时不接受,工具变量=0时接受 |
5.2 LATE的定义
局部平均处理效应 (LATE)
IV估计量识别的是依从者(Compliers)的平均处理效应:
关键洞察:
- IV估计的不是总体的ATE,而是特定子群体(Compliers)的效应
- 对于Always-takers和Never-takers,我们无法识别其处理效应
- 如果存在Defiers,LATE的解释更复杂(需要单调性假设)
5.3 LATE识别的五个假设
- SUTVA:没有溢出效应,潜在结果定义良好
- 随机分配: 与潜在结果独立
- 排他性: 只通过 影响
- 第一阶段:
- 单调性:(没有Defiers)
单调性的重要性:
- 确保Compliers的定义明确
- 排除Defiers的存在(否则LATE公式失效)
- 在大多数应用中,单调性是合理的
5.4 LATE的直观例子
Angrist & Krueger (1991):出生季度对教育的影响
- 工具变量:出生季度(由于义务教育法,不同季度出生的人上学年数不同)
- Compliers:那些因为出生季度而多上一年学的人
- LATE:这些Compliers的教育回报
重要局限
“IV估计的是那些因为出生季度而多上一年学的人的效应”——不是对所有人的效应。
Compliers可能是教育回报最高或最低的人,我们无法确定。
6 经典案例与应用
6.1 案例一:Angrist & Krueger (1991)
研究问题:教育的因果回报是多少?
工具变量:出生季度
- 美国义务教育法要求学生在特定年龄入学
- 不同季度出生的孩子在入学时年龄不同
- 这导致不同季度出生的人平均教育年数略有差异
- 出生季度与能力、动机等无关(排他性)
主要发现:
- OLS估计:约7.1%
- 2SLS估计:约8.9%
解读:教育回报略高于OLS估计,可能说明OLS低估了教育回报(能力偏差为负),或者Compliers的教育回报确实更高。
6.2 案例二:Card (1995) - 到大学的距离
研究设计:
- 工具变量:到最近大学的距离
- 结果:大学毕业生收入更高
- 发现:2SLS估计约12.4%,高于OLS的7.1%
为什么距离是好的工具变量?
- 相关性:地理距离影响上学成本(时间、金钱)
- 排他性:距离本身不直接影响收入(只通过教育)
LATE解释:估计的是那些因为离家近而上大学的人的效应。
6.3 案例三:Angrist (1990) - 越南战争抽签
研究设计:
- 背景:越南战争期间,美国通过抽签决定谁入伍
- 工具变量:抽签号码(随机分配)
- 处理变量:是否服兵役
- 结果变量:后来的收入
为什么抽签是好的工具变量?
- 相关性:低号码更可能被征召入伍
- 排他性:抽签号码完全随机,与能力、健康等无关
发现:服兵役导致收入下降约15%。
6.4 案例四:Cunningham & Finlay (2012)
研究问题:甲基苯丙胺(冰毒)使用对寄养儿童数量的影响
工具变量:甲基苯丙胺前体化学品的价格冲击
发现:
- 冰毒入院率增加10% → 寄养儿童数量增加约15%
- 说明药物滥用对家庭破裂有显著因果效应
7 Python实现:2SLS估计
7.1 基础模拟:工具变量有效性
import numpy as np
import pandas as pd
import statsmodels.api as sm
from linearmodels.iv import IV2SLS
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['Source Han Sans SC', 'Noto Sans CJK SC',
'WenQuanYi Micro Hei', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置随机种子
np.random.seed(42)
n = 1000
# 生成数据:D是内生的,Z是工具变量
Z = np.random.normal(0, 1, n) # 工具变量(外生)
U = np.random.normal(0, 1, n) # 未观测混淆变量
# 第一阶段:D受Z和U影响
D = 0.5 * Z + 0.8 * U + np.random.normal(0, 0.5, n)
# 真实因果效应
true_effect = 2.0
# 结果变量:Y受D和U影响(U造成内生性)
Y = true_effect * D + 1.5 * U + np.random.normal(0, 0.5, n)
# 创建数据框
data = pd.DataFrame({
'Y': Y,
'D': D,
'Z': Z,
'U': U # 现实中不可观测
})
print(f"样本量: {n}")
print(f"真实处理效应: {true_effect}")7.2 OLS vs 2SLS比较
# OLS估计(有偏,因为忽略了U)
X_ols = sm.add_constant(data['D'])
model_ols = sm.OLS(data['Y'], X_ols).fit()
ols_est = model_ols.params['D']
# 2SLS估计(使用Z作为工具变量)
# 注意:linearmodels需要显式添加常数项
iv_model = IV2SLS(
dependent=data['Y'],
exog=pd.DataFrame({'const': np.ones(n)}),
endog=data['D'],
instruments=data['Z']
).fit()
iv_est = iv_model.params['D']
# 手动计算2SLS(验证)
# 第一阶段
X_first = sm.add_constant(data['Z'])
model_first = sm.OLS(data['D'], X_first).fit()
data['D_hat'] = model_first.predict(X_first)
# 第二阶段
X_second = sm.add_constant(data['D_hat'])
model_second = sm.OLS(data['Y'], X_second).fit()
iv_est_manual = model_second.params['D_hat']
print("\n估计结果对比:")
print("=" * 50)
print(f"真实效应: {true_effect:.3f}")
print(f"OLS估计: {ols_est:.3f} (偏差: {ols_est - true_effect:.3f})")
print(f"2SLS估计: {iv_est:.3f} (偏差: {iv_est - true_effect:.3f})")
print(f"手动2SLS: {iv_est_manual:.3f} (偏差: {iv_est_manual - true_effect:.3f})")
print("=" * 50)7.3 第一阶段诊断
# 第一阶段回归结果
print("\n第一阶段回归结果:")
print("=" * 50)
print(f"Z的系数: {model_first.params['Z']:.4f}")
print(f"标准误: {model_first.bse['Z']:.4f}")
print(f"t统计量: {model_first.tvalues['Z']:.4f}")
print(f"R-squared: {model_first.rsquared:.4f}")
# 计算F统计量
f_stat = (model_first.params['Z'] / model_first.bse['Z']) ** 2
print(f"F统计量: {f_stat:.2f}")
if f_stat > 10:
print("✓ 工具变量强度足够 (F > 10)")
else:
print("⚠ 弱工具变量警告 (F ≤ 10)")7.4 弱工具变量模拟
# 模拟不同工具变量强度下的表现
np.random.seed(42)
n = 500
results = []
for pi1 in [0.05, 0.1, 0.3, 0.5, 1.0]: # 不同的第一阶段系数
temp_results = {'pi1': pi1, 'f_stats': [], 'iv_biases': [], 'ols_biases': []}
for _ in range(200): # 200次模拟
Z = np.random.normal(0, 1, n)
U = np.random.normal(0, 1, n)
D = pi1 * Z + 0.8 * U + np.random.normal(0, 0.5, n)
Y = 2.0 * D + 1.5 * U + np.random.normal(0, 0.5, n)
# OLS
X_ols = sm.add_constant(D)
ols_est = sm.OLS(Y, X_ols).fit().params[1]
# IV
X_first = sm.add_constant(Z)
first_stage = sm.OLS(D, X_first).fit()
f_stat = (first_stage.params[1] / first_stage.bse[1]) ** 2
D_hat = first_stage.predict(X_first)
X_second = sm.add_constant(D_hat)
iv_est = sm.OLS(Y, X_second).fit().params[1]
temp_results['f_stats'].append(f_stat)
temp_results['iv_biases'].append(iv_est - 2.0)
temp_results['ols_biases'].append(ols_est - 2.0)
results.append({
'第一阶段系数': pi1,
'平均F统计量': np.mean(temp_results['f_stats']),
'IV平均偏差': np.mean(temp_results['iv_biases']),
'OLS平均偏差': np.mean(temp_results['ols_biases'])
})
results_df = pd.DataFrame(results)
print("\n弱工具变量模拟结果:")
print("=" * 70)
print(results_df.to_string(index=False, float_format='%.3f'))7.5 Angrist & Krueger (1991)模拟
# 改进的Angrist & Krueger (1991)模拟
np.random.seed(42)
n = 5000
# 出生季度(1-4,均匀分布)
quarter = np.random.choice([1, 2, 3, 4], n)
# 能力(不可观测,与教育相关)
ability = np.random.normal(0, 1, n)
# 教育年数:受出生季度和能力影响
# 义务教育法导致不同季度出生的人教育年数有系统性差异
# 第四季度出生的人入学时年龄较小,被迫多上一年学
# 第一季度出生的人入学时年龄较大,可以早一年退学
quarter_effect = np.where(quarter == 1, -0.3,
np.where(quarter == 4, 0.3, 0))
education = 12 + quarter_effect + 0.4 * ability + np.random.normal(0, 1.0, n)
# 真实教育回报(对数收入)
true_return = 0.08
# 对数收入(周收入)
log_earnings = 5 + true_return * education + 0.15 * ability + np.random.normal(0, 0.35, n)
# 创建数据
ak_data = pd.DataFrame({
'log_earnings': log_earnings,
'education': education,
'quarter': quarter,
'ability': ability # 现实中不可观测
})
print("Angrist & Krueger (1991)模拟数据:")
print("=" * 50)
print(f"样本量: {n}")
print(f"各季度样本量:")
print(ak_data['quarter'].value_counts().sort_index())
print(f"\n平均教育年数(按季度):")
print(ak_data.groupby('quarter')['education'].mean().round(3))
# OLS估计
X_ols = sm.add_constant(ak_data['education'])
ols_model = sm.OLS(ak_data['log_earnings'], X_ols).fit()
ols_return = ols_model.params['education']
# 2SLS估计(使用出生季度作为工具变量)
# 创建季度虚拟变量
quarter_dummies = pd.get_dummies(ak_data['quarter'], prefix='q', drop_first=True)
ak_data = pd.concat([ak_data, quarter_dummies], axis=1)
# 使用linearmodels(显式添加常数项)
iv_model = IV2SLS(
dependent=ak_data['log_earnings'],
exog=pd.DataFrame({'const': np.ones(n)}),
endog=ak_data['education'],
instruments=ak_data[['q_2', 'q_3', 'q_4']]
).fit()
# 第一阶段结果
X_first = sm.add_constant(ak_data[['q_2', 'q_3', 'q_4']])
first_model = sm.OLS(ak_data['education'], X_first).fit()
print("\n教育回报估计结果对比:")
print("=" * 60)
print(f"真实回报: {true_return:.2%}")
print(f"OLS估计: {ols_return:.2%} (偏差: {ols_return - true_return:+.3f})")
print(f"2SLS估计: {iv_model.params['education']:.2%} (偏差: {iv_model.params['education'] - true_return:+.3f})")
print("=" * 60)
print(f"\n第一阶段回归系数:")
print(f" q_2: {first_model.params['q_2']:.3f} (vs Q1)")
print(f" q_3: {first_model.params['q_3']:.3f} (vs Q1)")
print(f" q_4: {first_model.params['q_4']:.3f} (vs Q1)")
print(f"\n第一阶段F统计量: {first_model.fvalue:.2f}")
print(f"第一阶段R²: {first_model.rsquared:.4f}")
if first_model.fvalue > 10:
print("✓ 工具变量强度足够 (F > 10)")
else:
print("⚠ 弱工具变量警告 (F ≤ 10)")8 工具变量法的局限与拓展
8.1 主要局限
8.1.1 1. 排他性无法检验
工具变量的排他性是一个基于理论的假设,无法直接用数据检验。需要依赖领域知识和定性论证。
8.1.2 2. LATE的外推问题
IV只识别Compliers的效应,Compliers可能只是总体的一小部分。效应能否推广到其他人存在疑问。
8.1.3 3. 弱工具变量风险
如果工具变量太弱,2SLS估计可能有严重偏差,甚至不如OLS。
8.2 多重工具变量
过度识别(Over-identification)
如果有多个工具变量 (),可以进行过度识别检验。
Sargan-Hansen检验:
- 原假设:所有工具变量都满足排他性
- 如果拒绝原假设:至少有一个工具变量无效
- 局限:只能检验过度识别的情况()
好处:
- 提高第一阶段强度
- 可以进行过度识别检验
- 估计更精确
8.3 控制变量的使用
在2SLS中加入外生控制变量:
- 第一阶段:
- 第二阶段:
为什么加入控制变量?
- 提高估计精度(控制无关变异)
- 放松排他性假设( 可以通过 影响 )
- 处理异质性(条件LATE)
控制变量的选择
只加入外生控制变量(不受 影响)。不要加入可能的中介变量或碰撞变量。
9 总结
9.1 本讲要点
- 工具变量法原理
- 处理未观测混淆变量的问题
- 利用外生变异识别因果效应
- 两个关键条件:相关性和排他性
- 2SLS估计
- 第一阶段:
- 第二阶段:
- IV估计量 = 简约式效应 / 第一阶段效应
- 弱工具变量
- F统计量 < 10时估计不可靠
- 偏差可能接近OLS
- 需要寻找更强的工具变量或使用稳健方法
- LATE框架
- 识别Compliers的处理效应
- 单调性假设排除Defiers
- 外推到总体需谨慎
9.2 实践建议
使用工具变量法的检查清单:
推荐工具:
- linearmodels (Python):IV2SLS, IVGMM
- statsmodels (Python):基础回归
- econml (Python):更高级的因果推断方法
- ivreg (R):2SLS估计
- fixest (R):快速固定效应和IV
9.3 下一步学习
下一讲将介绍双重差分法(Difference-in-Differences):
- 利用面板数据识别因果效应
- 平行趋势假设
- 事件研究法
- 交错DID的新进展
核心思想:
比较处理组和对照组在处理前后的变化:
这种方法能够控制不随时间变化的混淆因素。