样本选择与 Heckman 模型:排除变量比两步法本身重要
“用 Heckman 两步法缓解样本选择偏误”大概是国内实证论文里最常见的一句稳健性说明。这篇记它到底在解决什么问题,什么时候能用,以及它靠什么才站得住。
什么情况才算样本选择问题
Heckman 模型处理的是结果变量只在一部分观测上可见,并且可见与否和不可观测的因素有关:
- 工资只对有工作的人可见,是否工作又取决于不可观测的能力、保留工资;
- 企业的研发投入、环境信息披露得分,只有选择披露的企业才有数;
- 企业只有活下来,才有后续几年的业绩。
下面两种情况看上去相似,其实不是:
- 处理分配不随机。 某项政策只在一部分城市试点,试点城市是挑出来的。这时每个城市的结果变量都有取值,缺的是“没试点会怎样”的反事实,这是内生性问题,要靠 PSM、DID、工具变量等方法,不是
heckman命令的用武之地。 - 结果变量是真实的零。 企业研发投入为零是一个真实的取值,不是缺失。把零当缺失去做 Heckman,改变了研究的总体;这类角点解更常见的处理是 Tobit、两部分模型或泊松伪极大似然(
ppmlhdfe)。
模型
结果方程和选择方程:
只有 时才能看到 。假设 联合正态,,。于是在可见的样本里:
叫逆米尔斯比。只用可见样本直接跑 OLS,相当于遗漏了 这一项: 时不需要纠正, 且 与 相关时 OLS 就有偏。
Heckman(1979)的两步法:先对全部观测做 probit,估计 并算出 ;再在可见样本里把 作为一个额外的回归元放进结果方程。heckman 命令的最大似然版本则同时估计两个方程,效率更高,但对联合正态更敏感。
两步法有两个实操细节:
- 第二步里的 是估计出来的,误差还有异方差,手工“probit 之后 OLS 加 IMR”得到的标准误不对。
heckman, twostep报告的标准误已经按 Heckman(1979)修正过。 - 逆米尔斯比的系数是 。它显著,说明选择方程和结果方程的误差相关,也就是样本选择确实存在(命令还会报告 和 ,最大似然版本附带一个 的似然比检验)。
一个模拟
2000 个个体, 和 的相关系数 0.5,选择方程 ,约 57% 的观测可见;结果方程 ,真实系数 1, 与 的相关系数 0.6。 影响是否可见,但不进入结果方程。重复 500 次:
| 估计方法 | 系数均值 | 抽样标准差 | 报告的标准误(均值) | 95% 区间覆盖率 |
|---|---|---|---|---|
| 只用可见样本做 OLS | 0.836 | 0.032 | 0.032 | 0% |
| 手工两步(标准误未修正) | 1.003 | 0.040 | 0.039 | 95.6% |
heckman, twostep |
1.003 | 0.040 | 0.041 | 96.4% |
heckman 最大似然 |
1.002 | 0.037 | 0.038 | 96.0% |
OLS 偏低 0.16,置信区间一次也没有盖住真值;两步法和最大似然都能把它拉回来。手工两步和修正后的标准误,在这个设计里差别很小(0.039 对 0.041),但它们在原理上就不是一回事,直接用命令更省事。
一份样本上的输出( 的有 1141 个):
| 估计方法 | 的系数 | 标准误 | 备注 |
|---|---|---|---|
| OLS | 0.824 | 0.032 | |
heckman, twostep |
1.027 | 0.042 | (标准误 0.093) |
heckman 最大似然 |
1.016 | 0.037 | , 的似然比检验 |
排除变量决定一切
上面那个设计里, 是一个又强又干净的排除变量:它显著影响选择,又不直接进入结果方程。没有这样一个变量时,两步法只能靠 对 的非线性来区分“ 的作用”和“ 的作用”,识别很脆弱。再看几组设定, 对选择的影响由强到弱,最后直接为零;还有一组是 其实直接影响 (系数 0.3),而我们仍然把它排除在结果方程之外:
| 的设定 | 方法 | 系数均值 | 抽样标准差 | 报告的标准误 | 覆盖率 |
|---|---|---|---|---|---|
| 对选择影响强(1.0) | 两步 | 1.003 | 0.040 | 0.041 | 96.4% |
| 对选择影响弱(0.3) | 两步 | 1.003 | 0.064 | 0.067 | 96.2% |
| 两步, 也放进结果方程 | 1.003 | 0.098 | 0.100 | 96.8% | |
| 对选择没有影响(0) | 两步 | 0.992 | 0.168 | 0.175 | 98.0% |
| 最大似然 | 0.953 | 0.107 | 0.054 | 81.0% | |
| 直接影响 (排除限制不成立) | OLS | 0.924 | 0.031 | 0.031 | 33.2% |
| 两步 | 0.919 | 0.040 | 0.040 | 48.0% |
几点读法:
- 排除变量越弱,估计越不准:抽样标准差从 0.040 涨到 0.168,四倍多。同一份“弱排除变量”的数据,如果不再承认 是排除变量、把它也放进结果方程,标准差从 0.064 再涨到 0.098。
- 完全没有排除变量时( 对选择没有影响),最大似然报告的标准误平均 0.054,真实的抽样标准差却有 0.107,均值也偏到 0.953,95% 区间只盖住真值 81% 的次数。靠分布假设来识别的时候,别信这个标准误。
- 排除限制不成立时,Heckman 并没有比 OLS 好:两步法均值 0.919,和 OLS 的 0.924 差不多远,覆盖率 48%。这里的偏误方向和大小取决于具体设定,不能一般地说“更差”或“更好”,但可以肯定的是:它不再是一个纠偏方法。
所以用 Heckman 之前,先要有一个能讲清楚的排除变量:影响“是否被观测到”,但不直接影响结果变量的水平。劳动经济学里常用家庭中的幼儿数量一类变量去解释是否工作,国内公司金融论文里常见的做法是拿同行业、同地区其他企业的披露比例当排除变量。后者同行业的企业往往也共同面对影响结果变量的冲击,要论证它只通过披露决策起作用,得花比跑命令多得多的篇幅。
常见的几个问题
- 结果变量对所有观测都有值,却用 Heckman。 上面说过,这不是样本选择问题,
heckman命令也要求结果变量对一部分观测缺失。 - 选择方程和结果方程的解释变量完全一样。 命令能跑,但识别只靠 的非线性,上表里“没有排除变量”的情形就是这样,标准误很大。好些论文因此出现 IMR 和主要解释变量高度共线、两个系数都不显著,这是模型本身的问题,不是代码的问题(Puhani, 2000 用蒙特卡洛比较过两步法、最大似然和只用可见样本的 OLS,专门讨论了这种共线性)。
- 把 IMR 是否显著当成结论。 IMR 的系数不显著,并不能说明“没有样本选择问题”,它也可能只是检验力不够;显著则只说明在这个模型设定下选择和结果的误差相关。
- 因变量不是连续变量。 0/1 结果用
heckprobit,计数用heckpoisson,不要把线性的heckman套上去。 - 选择机制不满足正态。 两步法和最大似然都依赖联合正态,偏离时估计可能不稳;没有排除变量时,这个问题更严重。
没有排除变量怎么办
如果选择的原因是随机试验里的样本流失(比如培训后只能追踪到一部分人的工资),Lee(2009)的界不需要排除变量,只要求处理对“是否被追踪到”的影响是单调的,给出的是处理效应的区间,不是点估计。Stata 里对应 leebounds(SSC)。得到的区间往往很宽,但至少没有借助一个无法检验的排除变量就给出点估计。
代码
* y 对没被选中的观测是缺失值;s 是 0/1 的选择指示变量
* z 只出现在选择方程里(排除变量)
heckman y x, select(s = x z) twostep // 两步法,报告修正后的标准误
heckman y x, select(s = x z) // 最大似然,附 rho = 0 的似然比检验
手工两步(只用来理解,标准误不要用):
probit s x z
predict double xb, xb
gen double imr = normalden(xb) / normal(xb)
reg y x imr // 只在 y 非缺失的样本里估计
第一张表的模拟代码如下(这里只保留了表里用到的几项估计;最大似然版本的 heckman 在个别样本上可能不收敛,我跑的 500 次都收敛了):
capture program drop onesim
program define onesim, rclass
clear
set obs 2000
gen x = rnormal()
gen z = 0.5*x + sqrt(0.75)*rnormal()
gen u = rnormal()
gen e = 0.6*u + 0.8*rnormal()
gen s = (0.3 + 0.5*x + 1.0*z + u > 0)
gen y = 1 + 1.0*x + e
replace y = . if s == 0
quietly reg y x
return scalar b_ols = _b[x]
quietly probit s x z
quietly predict double xb, xb
quietly gen double imr = normalden(xb)/normal(xb)
quietly reg y x imr
return scalar b_man = _b[x]
quietly heckman y x, select(s = x z) twostep
return scalar b_h2 = _b[y:x]
return scalar se_h2 = _se[y:x]
quietly heckman y x, select(s = x z)
return scalar b_ml = _b[y:x]
end
simulate b_ols=r(b_ols) b_man=r(b_man) b_h2=r(b_h2) se_h2=r(se_h2) b_ml=r(b_ml), ///
reps(500) seed(20261003) nodots: onesim
summarize
参考文献
- Heckman, J. J. (1979). Sample selection bias as a specification error. Econometrica, 47(1), 153–161.
- Lee, D. S. (2009). Training, wages, and sample selection: Estimating sharp bounds on treatment effects. Review of Economic Studies, 76(3), 1071–1102.
- Puhani, P. (2000). The Heckman correction for sample selection and its critique. Journal of Economic Surveys, 14(1), 53–68.