当心:这(几乎)是我在Statalist上开始的一个线程的交叉帖子,但到目前为止还没有受到太多关注。
介绍
我在对集群样本很少(<30)但集群内相关性相当大的集群样本进行假设检验时正在了解这些问题。到目前为止,我阅读了Cameron/Gelbach/Miller 的著作“Bootstrap-Based Improvements for Inference with Clustered Errors (Review of Economics and Statistics 90, 414–427) [ Working Paper here ] 以及Cameron 和 Miller 的“从业者指南Cluster-Robust Inference”(Journal of Human Resources 50, 317–370) [ Preprint here ]。据我所知,如果集群的数量很少,则会过于频繁地拒绝零假设,并且引导程序(可能带有渐近细化)可以有助于克服这个问题。在他们的模拟中Wild cluster bootstrap t 程序在拒绝率非常接近标称的 5% 时效果最佳。我的问题是将他们的想法转移到二元响应模型。为了提供讨论的基础,我在 Stata 中做了一些模拟,以了解零假设的拒绝率。
数据生成过程
我假设“潜在”变量的数据生成过程如下:
其中是任何组的标准随机正态变量常数,而是来自标准正态的独立随机抽取。为了诱导组相关误差以及异方差性,我假设是从逻辑分布中随机抽取的,参数定义如下:
如果,则二进制响应变量 y 取值为 1,否则为 0。
模拟
我试图了解模拟数据的问题。我根据上述数据生成过程模拟了 499 个数据集,估计了一个 logit 模型并计算了被拒绝的频率。我假设有 15 个组,每个组包含 30 个观察值。我估计了logit模型:
- 无需调整,
- 方差-协方差矩阵的聚类稳健估计,
- 方差-协方差矩阵的集群引导估计,
- wald 统计数据的集群引导程序。
这是我写的Stata程序:
program define mysimu, rclass
version 13.1
clear
syntax [, groups(integer 15) obspgroup(integer 30) alpha(real 0.05) bootstraprep(integer 499)]
tempname cmat vmat cmat2 vmat2 cmat3 vmat3 cmat4 vmat4 b se w rej se_clust w_clust rej_clust se_boot w_boot rej_boot
tempvar group newgroup helpvar helpvar2 z_g helpvar3 e_g parb u x ystar y
//Set the number of observations
set obs `groups'
gen `group' = _n
expand `obspgroup'
bysort `group': gen `helpvar' = _n
//Cluster-Level Regressor Correlation
gen `helpvar2' = rnormal() if `helpvar' == 1
bysort `group': egen `z_g' = min(`helpvar2')
//Cluster-Level Error Correlation
gen `helpvar3' = runiform() if `helpvar' == 1
bysort `group': egen `e_g' = min(`helpvar3')
//Data Generating Process
generate `parb' = sqrt(27*`z_g'^2/_pi^2)
generate `u' = -`parb'*log(1/uniform() - 1)
generate `x' = rnormal()+`z_g'
generate `ystar' = `x'+`u'
generate `y' = `ystar' > 0
//Simple Logit
logit `y' `x'
matrix `cmat' = e(b)
matrix `vmat' = e(V)
return scalar b = `cmat'[1,1]
return scalar se = sqrt(`vmat'[1,1])
return scalar w = (`cmat'[1,1]-1)^2/`vmat'[1,1]
return scalar rej = (`cmat'[1,1]-1)^2/`vmat'[1,1] > invchi2(1, 1-`alpha')
//Clustered SE
logit `y' `x', cluster(`group')
matrix `cmat2' = e(b)
matrix `vmat2' = e(V)
return scalar b_clust = `cmat2'[1,1]
return scalar se_clust = sqrt(`vmat2'[1,1])
return scalar w_clust = (`cmat2'[1,1]-1)^2/`vmat2'[1,1]
return scalar rej_clust = (`cmat2'[1,1]-1)^2/`vmat2'[1,1] > invchi2(1, 1-`alpha')
//Pairs clustered bootstrap se
logit `y' `x', vce(boot, reps(`bootstraprep') cluster(`group'))
matrix `cmat3' = e(b)
matrix `vmat3' = e(V)
return scalar b_boot = `cmat3'[1,1]
return scalar se_boot = sqrt(`vmat3'[1,1])
return scalar w_boot = (`cmat3'[1,1]-1)^2/`vmat3'[1,1]
return scalar rej_boot = (`cmat3'[1,1]-1)^2/`vmat3'[1,1] > invchi2(1, 1-`alpha')
//Pairs clustered bootstrap wald test
tempfile dataset
logit `y' `x', cluster(`group')
matrix `cmat4' = e(b)
local theta = `cmat4'[1,1]
matrix `vmat4' = e(V)
local w = (`cmat4'[1,1]-1)^2/`vmat4'[1,1]
bootstrap wstar=((_b[`x']-`theta')^2/(_se[`x'])^2), reps(`bootstraprep') cluster(`group') idcluster(`newgroup') saving(`dataset', replace): logit `y' `x', cluster(`newgroup')
use `dataset', clear
sum wstar, d
return scalar rej_boot2 = `w' > r(p95)
end
该程序一次模拟一个数据集,并估计上面提到的四个不同版本,并将是否被拒绝的信息保存在 r(rej*) 中,占 5%。为了获得 499 个数据集和 r(rej*) 信息的 499 倍,我运行:
simulate rej=r(rej) rej_clust=r(rej_clust) rej_boot=r(rej_boot) rej_boot2=r(rej_boot2) , reps(499) seed(1342): mysimu
结果
拒绝率是:
- 53%
- 24%
- 21%
- 19%
问题
- 根据 Cameron [ 3 ]中的结果,方法 4) 的拒绝率小于方法 2) 和 3) 。然而,与他们的发现相比,差异很小。有人知道为什么会这样吗?
- 正如我在Cameron/Trivedis “使用 Stata 的微观计量经济学”中所读到的,狂野的引导程序(此处未使用,但他们的论文 [ 2 ] 中的“最佳”方法)仅适用于线性模型(“对于线性回归,狂野的引导程序可容纳更多现实的假设……”)。在这种情况下,是否有非线性对应物可能有助于接近 5% 的拒绝率?
- 一般来说,在对二元响应建模时,是否有一种“最先进的”方法来处理少数集群的问题?如果是这样,(引导程序?)程序会是什么样子?
编辑
Cameron 和 Miller 在他们的从业者指南中指出:
“如果存在特定于集群的影响,则必须调整对集群引导程序以解决以下复杂情况。假设集群 3 在引导程序重新采样中出现两次。然后,如果引导程序重新采样中的群集是从原始群集标识符中识别出来的,则两次出现的集群 3 将被错误地视为一个大型集群,而不是两个不同的集群。在 Stata 中,引导选项 idcluster 确保在每个引导重新采样中使用不同的标识符。例如 regress yx i.id_clu, vce(boot, cluster (id_clu) idcluster(newid) reps(400) seed(10101)) 以及更简单的 xtreg yx, vce(boot, reps(400) seed(10101)) ,因为在后一种情况下,Stata 会自动考虑这种并发症。 "
因此,我更改了代码,以便使用 idcluster 选项将引导程序中的每个集群绘制都标识为单独的集群。此外,我决定从程序中删除初始种子值,因为它也在模拟命令中定义。我相应地修改了上面的拒绝率。