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
(National Longitudinal Survey of Young Women, 14-24 years old in 1968)

. tab race, sum(ln_wage) means freq

            | Summary of ln(wage/GNP
            |        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

            | Summary of ln(wage/GNP
            |        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 3
bysort id: gen year = 2010 + _n
xtset id year

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

       id   year    y  
  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 命令来实现分块抽样。

基本语法格式如下:

    gsample [#|varname] [if] [in] [weight] [, options]

options                Description
----------------------------------------
  percent              sample size is in percent
  wor                  sample without replacement
  alt                  use alternative (faster) SRSWOR algorithm
  nowarn               allow repetitions in case of UPSWOR
  strata(varlist)      variables identifying strata
  rround               use random rounding for sample sizes across strata
  cluster(varlist)     variables identifying resampling clusters (primary sampling units)
  idcluster(newvar)    create new cluster ID variable
  keep                 keep observations that do not meet if and in
  generate(newvar)     store sampling frequencies in newvar
  replace              overwrite existing variables
  noprreserve          do not restore original data on break or error
use "xtdata01.dta", clear

gsample 60, cluster(id) percent wor

. list, sepby(id)

       id   year    y  
  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 选项即可:

gsample 3, cluster(id) wor

若进一步去掉 wor 选项,则可以实现有放回抽样,即 Bootstrap 抽样:

gsample, cluster(id) idcluster(id_new) generate(freq)

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)
 xtset idnew year

附加选项 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:

    1. 90% 以上的 Stata 命令都支持 vce(bootstrap) 选项。
    1. 本部分的详细介绍见 R7-稳健型标准误

3. 扩展阅读

Note:产生如下推文列表的 Stata 命令为:
lianxh Bootstrap 随机抽样 随机数 种子值 抽样, nocat md0
安装最新版 lianxh 命令:
ssc install lianxh, replace