Stata手动:各类匹配方法大全 A——理论篇
温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。
作者:黄俊凯 (中国人民大学)
E-Mail: kopanswer@126.com
目录
匹配是研究处理效应的常见工具,本文总结了常见的匹配方法,并在第三部分给出 Stata 模拟以比较不同的匹配方法的优劣。
单变量匹配的方法有精确匹配、粗糙精确匹配,k-近邻匹配和半径 (卡尺) 匹配。
顾名思义,当且仅当两个观测值的匹配变量相等时匹配成功。
粗糙精确匹配用途广泛,通常要求匹配变量是分类变量。比如公司金融中同行业的公司,又比如教育经济学中在同一个班的同学。粗糙精确匹配可以轻松的推广到多变量匹配的情形,如同行业同年度的公司,同班同性别的同学。
k-近邻匹配要求匹配变量是距离,它选取距离最近的 k 个观测值作为对照组。
k-近邻匹配要求匹配变量也是距离,它事先设定半径 (上下半径可以不同),找出设定范围内的全部观测值作为对照组。显然,随着半径的降低,匹配要求也更趋严格。
多变量匹配的核心思路是降维 (dimension reduction),将多变量降维为距离或得分,然后再运用单变量匹配的方法。多变量匹配的方法有欧氏距离、百分等级、马氏距离和倾向得分匹配等。
为能直观的图示,下文全部示例仅考虑双变量 (平面) 的情形。
最简单的测度空间就是欧氏距离空间。你可以轻松的用尺子直接量出点到原点、或任意两点之间的距离。
平面上任意点
平面上任意两点
在欧式距离空间中,坐标轴之间是相互垂直的,也就意味着随机变量之间的相关系数为零。这是一个非常强的假设,而实际研究中该假设往往不能成立。比如研究一个人的健康时,作为影响因素的身高和体重之间往往是正相关的。
在欧式距离空间中,坐标轴上的量纲也是默认相同的,也就意味着随机变量必须有相同的量纲。这同样是一个过于严苛的假设。同样是研究一个人的健康,身高的单位是厘米,体重的单位是公斤,无论如何长度单位和重量单位是不可比的。
为了克服匹配时欧氏距离空间的上述两个缺陷,印度数学家 Mahalanobis 提出了著名的马氏距离空间。马氏距离对多匹配变量的联合分布的位置、形状做了标准化调整,也对多匹配变量之间的相关性做了正交化调整,从而将多匹配变量的联合分布转变为可以用欧氏距离计算的情形。
马氏距离实现上述功能的关键在于用协方差矩阵的逆矩阵做了调整。我们将在第三部分用 Stata 代码逐步展示它。任意点
任意两点
其中
马氏距离测量相对于质心的距离,质心是一个基准点或中心点,可以认为是多元数据的总体平均值。质心是多元空间中所有变量的均值相交的点。马氏距离越大,数据点离质心越远。
在多随机变量的联合分布中,距离近的点在概率分布函数 (PDF) 上往往不一定靠近。我们以如下标准正态分布 (钟形曲线) 为例,说明距离相近并不必然等于概率分布上的靠近。
不妨设样本容量为
百分等级是一个相对位置量数。它是指将距离按照从小到大的顺序排列,小于某观测值距离的观测值个数与样本数的百分比,即为该观测值的百分等级。
不同于百分数 (percentile),有相同距离的观测值总是有相同的百分等级 (percentile rank),以消除指定百分等级时的武断性 (arbitrariness)。因此,百分等级的公式如下:
其中,PR 是百分等级,L 是距离小于该观测值距离的观测值数,E 是距离等于该观测值距离的观测值数,N 是样本数。例如,样本有
百分等级匹配就是选择百分等级最接近的观测值作为反事实观测值,显然它是一种非参数方法。基于距离的百分等级不仅克服了距离不能体现随机变量分布函数的特点 (比如距离很远的点也可能有相似的百分等级),而且将匹配变量之间的差异限制在
倾向得分匹配不是基于距离而是基于得分。倾向得分 (propensity score) 是指个体 i 在给定可观测变量
对倾向得分的估计可使用参数估计或非参数估计,最流行的方法是 logit。Rosenbaum and Rubin (1983) 证明,如果可忽略性假定成立,则在给定倾向得分的情况下,结果变量在事前和事后的取值独立于是否个体进入处理组。
使用倾向得分匹配需要满足两个假定:1.共同支撑假设;2.平衡性假定。
共同支撑集是指这样一个集合,不妨设备择组观测值的倾向得分的取值范围为
其中
在匹配时,为提供匹配质量,可仅保留倾向得分重叠部分的个体。共同支撑假设要求共同支撑集的取值范围不能太小,则匹配成功的样本可能不具有代表性。
再说平衡性假定,如果倾向得分估计是准确的,那么协变量
多接近是接近?均值之间的差异与计量单位有关,你当然可以做组建军之差异或中位数差异检验,也可以使用标准化偏差 (standarized bias) 进行比较,公式如下:
经验法则告诉我们,标准化差距不得超过 10%。如果超过,则应重新估计倾向得分,或改变具体的匹配方法。
尽管倾向得分匹配体现了选择过程,但它仍有一些缺陷,比如它只能依可测变量选择,对共同支撑集有要求等。
我们用简单的二维模拟数据来展示不同多变量匹配方法之间的差异。
clear
set obs 200
gen id = _n
set seed 10000
gen r0 = rnormal()
set seed 12345
gen r1 = rnormal()
set seed 65432
gen r2 = rnormal()
set seed 10101
gen re = rnormal()
*-选择变量
gen x1 = 2 * (r0 + r1)
gen x2 = 3 + (r0 + r2)
*-选择机制
gen group = 2 * x1 - 3 * x2 + 10 * re > 0
label def group 0 "非对照组" 1 "处理组"
label val group group
*-数据分布
keep id x1 x2 group
tab group
correlate x1 x2
twoway (scatter x1 x2 if group == 0, mcolor(black)) ///
(scatter x1 x2 if group == 1, mcolor(red)), ///
title("数据分布") xlabel(-10(5)10) ///
ylabel(-10(5)10, nogrid) ///
aspect(1) legend(off)
下图种,红色的点为处理组观测值,黑色的点为对照组观测值
变量 ec 记录欧氏距离匹配得到的匹配值
gen ec = .
gen ed = .
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = sqrt((x1[`i'] - x1[`j'])^2 + (x2[`i'] - x2[`j'])^2)
if `d' < ed[`i'] {
qui replace ec = `j' in `i'
qui replace ed = `d' in `i'
}
}
}
}
}
tab group
misstable sum ec ed
欧氏距离匹配的结果:
变量 mc 记录马氏距离匹配得到的匹配值
corr x1 x2, cov
mat cov = r(C)
mat cov = inv(cov)
mat list cov
scalar a_11 = cov[1, 1]
scalar a_22 = cov[2, 2]
scalar a_21 = cov[2, 1]
gen mc = .
gen md = .
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = sqrt(a_11*(x1[`i'] - x1[`j'])^2 + a_22*(x2[`i'] - x2[`j'])^2 + 2 * a_21 * (x1[`i'] - x1[`j']))
if `d' < md[`i'] {
qui replace mc = `j' in `i'
qui replace md = `d' in `i'
}
}
}
}
}
马氏距离匹配的结果:
变量 pc 记录倾向得分匹配得到的匹配值
gen pc = .
gen pd = .
probit group x1 x2
predict score, xb
replace score = normal(score)
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = abs(score[`i'] - score[`j'])
if `d' < pd[`i'] {
qui replace pc = `j' in `i'
qui replace pd = `d' in `i'
}
}
}
}
}
倾向得分匹配的结果:
*-3.1 数据生成过程
clear
set obs 200
gen id = _n
set seed 10000
gen r0 = rnormal()
set seed 12345
gen r1 = rnormal()
set seed 65432
gen r2 = rnormal()
set seed 10101
gen re = rnormal()
*-选择变量
gen x1 = 2 * (r0 + r1)
gen x2 = 3 + (r0 + r2)
*-选择机制
gen group = 2 * x1 - 3 * x2 + 10 * re > 0
label def group 0 "非对照组" 1 "处理组"
label val group group
*-数据分布
keep id x1 x2 group
tab group
correlate x1 x2
twoway (scatter x1 x2 if group == 0, mcolor(black)) ///
(scatter x1 x2 if group == 1, mcolor(red)), ///
title("数据分布") xlabel(-10(5)10) ///
ylabel(-10(5)10, nogrid) ///
aspect(1) legend(off)
*-3.2 欧氏距离匹配的结果
gen ec = .
gen ed = .
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = sqrt((x1[`i'] - x1[`j'])^2 + (x2[`i'] - x2[`j'])^2)
if `d' < ed[`i'] {
qui replace ec = `j' in `i'
qui replace ed = `d' in `i'
}
}
}
}
}
tab group
misstable sum ec ed
*-3.3 马氏距离匹配的结果
corr x1 x2, cov
mat cov = r(C)
mat cov = inv(cov)
mat list cov
scalar a_11 = cov[1, 1]
scalar a_22 = cov[2, 2]
scalar a_21 = cov[2, 1]
gen mc = .
gen md = .
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = sqrt(a_11*(x1[`i'] - x1[`j'])^2 + a_22*(x2[`i'] - x2[`j'])^2 + 2 * a_21 * (x1[`i'] - x1[`j']))
if `d' < md[`i'] {
qui replace mc = `j' in `i'
qui replace md = `d' in `i'
}
}
}
}
}
*-3.4 倾向得分匹配的结果
gen pc = .
gen pd = .
probit group x1 x2
predict score, xb
replace score = normal(score)
forvalues i = 1(1)200 {
if group[`i'] == 1 {
forvalues j = 1(1)200 {
if group[`j'] == 0 {
local d = abs(score[`i'] - score[`j'])
if `d' < pd[`i'] {
qui replace pc = `j' in `i'
qui replace pd = `d' in `i'
}
}
}
}
}
连享会-直播课 上线了!
http://lianxh.duanshu.com
免费公开课:
直击面板数据模型 - 连玉君,时长:1小时40分钟 Stata 33 讲 - 连玉君, 每讲 15 分钟. 部分直播课 课程资料下载 (PPT,dofiles等)
支持回看,所有课程可以随时购买观看。
专题 | 嘉宾 | 直播/回看视频 |
---|---|---|
⭐ 最新专题 ⭐ | DSGE, 因果推断, 空间计量等 | |
⭕ Stata数据清洗 | 游万海 | 直播, 2 小时,已上线 |
研究设计 | 连玉君 | 我的特斯拉-实证研究设计,-幻灯片- |
面板模型 | 连玉君 | 动态面板模型,-幻灯片- |
面板模型 | 连玉君 | 直击面板数据模型 [免费公开课,2小时] |
Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。
关于我们
课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法
等
连享会小程序:扫一扫,看推文,看视频……
扫码加入连享会微信群,提问交流更方便
✏ 连享会学习群-常见问题解答汇总:
✨ https://gitee.com/arlionn/WD