P5. 随机抽样
随机抽样是一种从总体中以随机方式抽取样本的统计方法,广泛应用于各种统计推断和实证分析中。进行随机抽样的主要目的是确保样本的代表性,从而使得研究结果能够有效推广到整个总体。随机抽样方法可以有效避免选择偏差,并提供更加稳健的统计推断。
在实际研究中,随机抽样不仅用于样本的抽取,还广泛应用于各类检验中,如安慰剂检验(placebo test)、稳健性检验(robustness check)等。这些检验通过随机化方法验证模型结果的稳健性,确保结论在不同条件下的一致性和可靠性。例如,在因果推断中,通过随机抽样可以设计对照组和实验组,模拟自然实验中的随机化过程,从而提高模型的内生性识别能力。
此外,统计推断的有效性通常依赖于随机抽样,只有通过合适的随机抽样方法才能保证估计结果具有一致性和无偏性。使用如 Bootstrap 等方法,通过从样本数据中进行反复抽取样本进行估计,可以在没有强假设的条件下进行稳健性分析和置信区间估计,从而提升结果的可靠性。
例如,如下代码采用 Bootstrap 获取系数的稳健型标准误:
sysuse "auto.dta", clear
regress mpg wei turn, vce(bootstrap, reps(1000))
本讲将主要介绍两种随机抽样方法:无放回抽样和有放回抽样。无放回抽样在每次抽取后不将样本放回,总体中的每个元素只有一次被抽中的机会;而有放回抽样则允许同一元素多次出现在样本中,这种方法通常用于某些特定的分析,如Bootstrap方法,用于评估样本估计的分布特性和置信区间。
1. 无放回抽样
在 Stata 中,通过 sample
命令实现无放回抽样。为了便于演示,我们先生成一组数据:
clear
set obs 10
gen x = _n
save "iddata01.dta", replace
执行上述命令,我们可以得到一列 1 到 10 的整数,列示如下:
list x
.
x
1. 1
2. 2
……
9. 9 10. 10
1.1 按比例抽取
抽取 30% 的观察值
use "iddata01.dta", clear
sample 30
list
.
x
1. 4
2. 7 3. 3
细心的读者会发现,你每次执行 sample 30
命令后得到的结果都不同。事实上,sample
命令抽取的结果具有随机性,这也是所谓“随机”抽样的含义。在 Stata 内部,通过人为设定的「随机数发生器」来实现随机抽样,所以这样的“随机”抽样虽然名义上是“随机”抽样,但实质上是伪随机的,其中存在一个函数的发生器。详情参见 [FN] random number functions (p.8-10),以及 Stata:随机数生成原理与实现。
1.2 按具体数量抽取
若在 sample
命令后附加 count(#
) 选项,则表示从现有样本中随机抽取 #
个观察值。
use "iddata01.dta", clear
sample 5, count
list
.
x
1. 7
2. 3
3. 4
4. 2 5. 9
1.3 分层抽样 (Stratified Sampling)
分层/分组抽样 (Stratified Sampling) 是一种更为复杂的抽样方法。在这种抽样方法中,我们将总体按照某种特征(通常是一个分类变量)划分为若干个子群体(或称为“组”)。然后在每个组内独立地进行抽样,以确保各组在样本中得到适当的代表。
那么,什么时候需要采用分组抽样呢?当我们认为总体中某些组在特定特征上差异显著,而这种差异可能对研究结果产生重要影响时,采用分组抽样可以确保每个组在样本中的充分代表。特别是当某些组的人数较少时,简单随机抽样可能无法得到足够的样本量,而分组抽样则可以确保每个组都有足够的样本进行分析。
例如,如果研究中涉及性别、种族、年龄等分类变量,而这些变量在总体中存在较大差异,分组抽样可以确保每个类别的样本都有足够的代表性,从而使分析结果更加准确。
范例:随机抽取不同种族女性的样本
基于 1968 年妇女工资资料数据 nlswork.dta。该样本中包含一个分类变量 race,其取值为 1, 2, 3,分别对应 White、Black 和 Other 三种肤色。
首先,我们查看原始样本中三类妇女的分布情况:
webuse "nlswork.dta", clear
. of Young Women, 14-24 years old in 1968)
(National Longitudinal Survey
tab race, sum(ln_wage) means freq
.
of ln(wage/GNP
| Summary
| deflator)
Race | Mean Freq.
------------+------------------------
White | 1.7143383 20,180
Black | 1.5715521 8,051
Other | 1.7950093 303
------------+------------------------ Total | 1.6749071 28,534
从输出结果可以看出,样本中白人 (White) 最多,而其他人种 (Other) 的数量却非常少。因此,如果我们希望抽样样本中每个组(如各族群)的分布与总体更为接近,简单随机抽样可能无法确保少数群体的充分代表。
为了解决这个问题,我们可以使用分组抽样。接下来,我们使用 sample
命令,从每个子样本中随机抽取 50% 的观察值:
set seed 123
.
sample 50, by(race)
.
(14,266 observations deleted)
tab race, sum(ln_wage) means freq
.
of ln(wage/GNP
| Summary
| deflator)
Race | Mean Freq.
------------+------------------------
White | 1.7096145 10,090
Black | 1.5650935 4,026
Other | 1.7836591 152
------------+------------------------ Total | 1.6696238 14,268
可以看出,通过附加 by(race)
选项,我们可以确保从每个子样本组中随机抽取了约 50% 的观察值。这种方法使得每个子组在样本中的比例保持与原始样本的比例一致。通过分组抽样,我们能够确保每个群体在样本中都有适当的代表性。
1.4 分块抽样 (Block Sampling)
分块抽样(Block Sampling)是一种适用于处理数据内部存在特定结构或相关性的抽样方法。在这种抽样方法中,我们将总体按照某种逻辑或数据特征划分成若干个“块”(Block),每个块包含多个观测值,然后「以块为单位」进行抽样,而不是对单个观测值进行抽取 。这样做的目的是为了保留数据中存在的特定关系或结构,避免因随机抽取单个观测值破坏这种关系,从而提高样本对总体特征的代表性。
当数据存在明显的聚集性、序列相关性或空间相关性时,分块抽样能发挥重要作用。例如在面板数据中,同一观测对象在不同时间点的数据往往存在较强的序列相关;在空间数据中,地理位置相近的观测值通常具有相似特征。简单随机抽样可能会割裂这些内在联系,导致样本无法准确反映总体特性,而分块抽样则通过将相关联的数据作为一个整体抽取,确保了样本中保留数据原有的结构特征。
为了演示分块抽样的具体操作,我们先产生一个随机样本。
clear
set obs 5
gen id = _n
expand 3bysort id: gen year = 2010 + _n
year
xtset id
set seed 1234
gen y = rnormal(20, 10) if year==2011
replace y = 0.9*L.y if year>2011
format y %4.0f
save "xtdata01.dta", replace // 保存数据
数据呈现如下:
list, clean
.
year y
id
1. 1 2011 15
2. 1 2012 14
3. 1 2013 12 --- Firm 1
4. 2 2011 5
5. 2 2012 5
6. 2 2013 4 --- Firm 2
7. 3 2011 20
8. 3 2012 18
9. 3 2013 16 --- Firm 3
10. 4 2011 20
11. 4 2012 18
12. 4 2013 16 --- Firm 4
13. 5 2011 25
14. 5 2012 23 15. 5 2013 20 --- Firm 5
这是一个典型的面板数据,包含 \(N = 5\) 个个体 (公司或消费者),每个个体有 \(T = 3\) 年的追踪资料。最重要的特征是,\(y_{it} = \rho y_{it - 1}\) (本例中,\(\rho = 0.9\)),即数据存在显著的序列相关。因此,同一家公司在不同年度的观察值不再是彼此独立的,因此,抽样时我们要尽可能地保留这种时序特征。此时,采用「分块抽样」能够确保抽取的样本依然维持原有的序列相关关系,使基于样本的分析结果更贴近总体实际情况。
Stata 官方命令 sample
不支持以块为单位进行抽样。不过,我们可以使用外部命令 gsample
命令来实现分块抽样。
基本语法格式如下:
if] [in] [weight] [, options]
gsample [#|varname] [
options Description
----------------------------------------percent sample size is in percent
sample without replacement
wor use alternative (faster) SRSWOR algorithm
alt in case of UPSWOR
nowarn allow repetitions strata(varlist) variables identifying strata
use random rounding for sample sizes across strata
rround cluster(varlist) variables identifying resampling clusters (primary sampling units)
new cluster ID variable
idcluster(newvar) create keep keep observations that do not meet if and in
generate(newvar) store sampling frequencies in newvar
replace overwrite existing variables
do not restore original data on break or error noprreserve
use "xtdata01.dta", clear
cluster(id) percent wor
gsample 60,
list, sepby(id)
.
year y
id
1. 2 2011 5
2. 2 2012 5
3. 2 2013 4
4. 3 2011 20
5. 3 2012 18
6. 3 2013 16
7. 1 2011 15
8. 1 2012 14 9. 1 2013 12
上述代码中,选项 cluster(id)
指定了以个体 id
作为分块的依据,即每个 id
对应的所有年度观测值构成一个块,抽样时以整个块为单位进行抽取;而 percent
选项则表明我们抽取的样本量是原样本量的 60%。
上述抽样过程具有随机性,大家可以尝试多执行几次上述三行代码,你会发现每次的结果都会有差异。
此外,选项 wor
(sample without replacement) 的作用是无放回抽样,即每个块在一次抽样过程中最多只会被抽取一次,确保样本中不会出现重复的块。如果不附加该选项,则默认进行有放回抽样,可能会导致同一个块在样本中多次出现。此时,为了保证新样本中有唯一的截面标识符,需要附加 idcluster(newvar)
选项,以便产生新的唯一标识每个块的变量,避免数据混淆,同时也便于后续的数据分析与处理。
若想执行按数量抽样 (比如,随机抽取 3 家公司),只需去掉 percent
选项即可:
cluster(id) wor gsample 3,
若进一步去掉 wor
选项,则可以实现有放回抽样,即 Bootstrap 抽样:
cluster(id) idcluster(id_new) generate(freq) gsample,
2. 有放回抽样
在 Stata 中,通过 bsample
命令来实现有放回抽样,b 是 bootstrap(自抽样)的简写。
2.1 实例: 截面数据
同样使用 1 到 10 的 10 个整数作为总体,代码如下:
use "iddata01.dta".dta, clear
bsample
sort x
抽样结果如下图所示,其中命令 sort
表示对观察值进行排序,观察值 4 被抽取了四次,6 被抽取了两次。
x
1. 2
2. 4
3. 4
4. 4
5. 4
6. 6
7. 6
8. 8
9. 9
10. 10
2.2 实例:面板数据
面板数据同样可以进行有放回的抽样,设置选项 cluster(id)
表示抽样是以公司为单位进行的,或者理解为每次抽取的是公司的编号而不是行(观察值),代码如下:
use P4_xtdata, clear
browse
bsample, cluster(id) idcluster(idnew)
year xtset idnew
附加选项 idcluster(idnew)
重新确定了抽样样本出现的先后顺序,如下图所示:
1. 1 2001 .1 1
2. 1 2002 .2 1
3. 1 2003 .3 1
4. 1 2004 .4 1
5. 1 2001 .1 2
6. 1 2002 .2 2
7. 1 2003 .3 2
8. 1 2004 .4 2
9. 1 2001 .1 3
10. 1 2002 .2 3
11. 1 2003 .3 3
12. 1 2004 .4 3
13. 3 2001 .9 4
14. 3 2002 1 4
15. 3 2003 1.1 4
16. 3 2004 1.2 4
17. 4 2001 1.3 5
18. 4 2002 1.4 5
19. 4 2003 1.5 5
20. 4 2004 1.6 5
id 为 1 的公司被抽取了 3 次,分别被 idnew 标记为 1、2、3,如果多次重复运行代码,抽取的结果会发生变化。
近年中,bootstrap 方法的应用非常广泛。在 Stata 学术论文专题中介绍的面板门限模型中,主要是运用 bootstrap
来进行假设检验。
Note:
gsample
可以完全替代bsample
的功能,且有扩展。
2.3 应用:bootstrap 标准误
可重复的抽样主要应用在 bootstrap
中,我们可以使用 bootstrap
去获取系数的标准误。在 Stata 中做线性回归,想要采用 bootstrap
去获得标准误,只需要在前面附加前缀bootstrap, reps(300):
,代表我们进行 300 次可重复抽样,每一次可重复抽样的样本称为经验样本,用经验样本可以估计出变量的系数。 示例代码如下:
sysuse auto, clear
bootstrap, reps(300): ///
reg price weight mpg foreign, noheader
对于 300 次重复抽样的系数,比如 weight 变量,我们可以计算出一个标准差,它可以作为 weight 变量对应系数的标准误。
-等价写法:
reg price weight mpg foreign, ///
vce(bootstrap, reps(300) seed(1357))
等价写法是把 bootstrap
参数写在 vce()
选项中。
Notes:
- 90% 以上的 Stata 命令都支持
vce(bootstrap)
选项。
- 90% 以上的 Stata 命令都支持
- 本部分的详细介绍见 R7-稳健型标准误
3. 扩展阅读
Note:产生如下推文列表的 Stata 命令为:
lianxh Bootstrap 随机抽样 随机数 种子值 抽样, nocat md0
安装最新版lianxh
命令:
ssc install lianxh, replace
- 吴雄, 童天天, 2020, Stata:Bootstrap-自抽样-自举法, 连享会 No.43.
- 周圆, 2023, Stata:Bayes Bootstrap介绍-exbsample, 连享会 No.1188.
- 周瑾, 2024, 论文推介:包含343位作者的JF论文:NSE-非标准误差, 连享会 No.1510.
- 李烨阳, 2023, Stata:自己动手做组间系数差异检验-bootstrap-bdiff, 连享会 No.1286.
- 杨凡佳, 2024, Stata+R:你了解什么是抽样吗?Sampling, 连享会 No.1359.
- 滕泽鹏, 2023, Stata:随机抽样命令介绍-gsample, 连享会 No.1140.
- 王乔, 2021, Stata:原始聚类自助法(wild cluster bootstrap)-boottest, 连享会 No.825.
- 王琳茗, 2022, Stata:随机数生成原理与实现, 连享会 No.865.
- 祖丽胡玛尔·热合曼, 2023, Stata:排序、种子值和随机数——为何每次的结果都不同?, 连享会 No.1314.
- 郑裕璇, 2022, Stata:手动实现置换检验(permutation)和自抽样(bootstrap), 连享会 No.1091.
- 陈勇吏, 2020, Stata程序:Monte-Carlo-模拟之产生符合特定分布的随机数, 连享会 No.343.
- 雷诺, 2024, 控制函数法:Bootstrap标准误的获取, 连享会 No.1328.