5.1 数据生成过程

一种普遍理解科学的方式是:科学家们认为,宇宙的运行受规律性法则支配。

这些法则正是“数据生成过程”的实例。无论人类是否知晓,它们始终在幕后运行。我们无法直接观测这些法则,但能观察到它们产生的数据——譬如松手时球体坠向地面,这便是我们的观测数据。引力正是该球体数据生成过程的一部分,即潜在的自然定律。

我们对重力如何运作有一个相当不错的了解。基本上1,如果我们有两个物体,它们之间的距离为 r,一个质量为 m₁,另一个质量为 m₂,那么将它们拉在一起的力 F 为:

\[ F = G \cdot \frac{m_1 m_2}{r^2} \quad\quad {5.1} \]

其中\(G\)是‘引力常数’。该公式是一条物理定律。它描述了在幕后决定物体如何运动的过程,无论我们是否知晓。

除了认为存在这样的潜在定律之外,科学家还相信,我们可以通过经验观察来了解这些定律。我们并不是一开始就知道万有引力方程——艾萨克·牛顿必须去发现它。但在牛顿提出这个方程之前,我们已经有数据了。大量关于物体运动的数据,尤其是关于行星轨道运行的数据。

科学界认为:“我们能看到这些行星运动。我们知道必然存在某种规律解释它们为何以特定方式运行。我打赌我们可以用观测到的现象来推导出这个规律是什么。”而我们确实做到了!至少牛顿做到了。聪明人啊。基于行星轨道呈椭圆形的观测事实,牛顿证明了公式(5.1)能够推演出这些轨道2

我们可以从数据中推断世界运行的规律,因为像方程(5.1)这样的内容属于数据生成过程 (Data Generating Process, DGP)。如果有两颗行星在太空中飞行,它们的运动实际上就是由那个方程决定的 ,而我们只是将它们的运动作为数据观测到 。如果我们不知道这个方程,那么通过对实际运动的充分观测,以及对数据生成过程其他部分的足够理解(从而排除动量等因素的影响),我们或许能够推导出这个方程,并识别出引力的作用。

社会科学中的数据生成过程\(DGPs\)通常不像物理科学中的那样表现良好且精确。尽管如此,如果我们认为观测数据至少源自某种规律法则,那么我们就是在说存在一个数据生成过程3

数据生成过程的关键在于,它实际上包含两个部分——我们已知的部分和我们未知的部分。我们未知的部分正是我们希望通过研究去了解的内容。对引力的研究让我们能够填补关于运动数据是如何产生的数据生成过程中的一部分空白。

不过,我们已经了解的部分同样重要。数据生成过程\(DGP\)整合了我们关于某一主题及其底层规律的 所有 已知信息。然后,我们可以利用我们 确实 知道的内容去探索新事物。如果牛顿是从零开始,他根本不可能弄清楚万有引力。诚然,我们看到行星的运动就好像它们在相互靠近。但也许行星之所以那样运动是因为魔法?事实并非如此。但我们之所以能排除这种可能性,是因为我们已有的知识——数据本身并不能做到这一点。又或者,这只是动量起作用的方式?同样,仅靠动量本身是不够的,但我们需要对动量有相当多的了解,才能 判断出 仅靠它是不够的。我们了解力、动量和速度。有了这些知识,我们能对万有引力有哪些新的认识呢?

所以!我们可以利用我们已知的信息尽可能多地去了解数据生成过程。这将使我们能够找出我们看到这些数据的原因,这样我们就可以只专注于我们感兴趣的部分。如果我们想了解万有引力,我们需要确保我们的数据是在向我们揭示有关万有引力的信息,而不是有关动量、速度或魔法的信息。

让我们来生成一些数据 。思考数据生成过程\(DGPs\)如何助力研究的一个不错的方法是稍微取个巧,生成一些我们确切知晓其数据生成过程的数据。

在我们构建的世界中,这些将是规则:

  1. 收入呈对数正态分布(参见第 3 章)

  2. 拥有一头棕色头发会让你获得\(10\%\)的收入提升

  3. \(20\%\)的人天生是棕色头发

  4. 拥有大学学位会让你获得\(20\%\)的收入提升

  5. \(30\%\)的人拥有大学学位

  6. \(40\%\)没有棕色头发或大学学位的人会选择染发成棕色4

# Output file for Identification Chapter
library(Cairo)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(haven)
library(extrafont)
## Registering fonts with R
library(lubridate)
library(vtable)
## Loading required package: kableExtra
## 
## Attaching package: 'kableExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(ggrepel)
library(ggpubr)
library(conflicted)
library(dplyr)
library(pmdplyr)
library(showtext)
## Loading required package: sysfonts
## Loading required package: showtextdb
## 
## Attaching package: 'showtextdb'
## 
## The following object is masked from 'package:extrafont':
## 
##     font_install
font_add('TNR','C:/Windows/Fonts/times.ttf')
showtext_auto()

假设我们有一些依据这些规则生成的数据,但我们对这些规则一无所知。现在假设我们想了解拥有棕色头发对收入的影响。我们可能会像图 5.1 那样,先查看有棕色头发和没有棕色头发的人的收入分布情况;或者像表 5.1 那样,仅查看不同发色人群的平均收入。

Table 5.1: Mean Income by Hair Color

### DATA GENERATING PROCESS
set.seed(987987)

# colleges Indicates whether or not the person has attended college, which is about 30%.
df <- dplyr::tibble(College = runif(5000) < .3) %>%
  dplyr::mutate(Hair = case_when(
    runif(5000) < .2+.8*.4*(!College) ~ "Brown",
    TRUE ~ "Other Color")) %>%
  dplyr::mutate(logIncome = .1*(Hair == "Brown") + .2*College + rnorm(5000) + 5)

ggplot(df %>% dplyr::filter(Hair=="Brown"), aes(x = logIncome, linetype=Hair)) +
  stat_density(geom='line', linewidth = 1) +
  stat_density(data = df %>% dplyr::filter(Hair == "Other Color"), geom='line', linewidth=1) +
  theme_pubr() + 
  labs(x = "Log Income", y = "Density") + 
  theme(text         = element_text(size = 10, family="sans"),
        axis.title.x = element_text(size = 10, family="sans"),
        axis.title.y = element_text(size = 10, family= "sans"),
        legend.position = c(.2,.8),
        legend.background = element_rect())
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

ggsave('Identification/hair1.pdf', width = 6, height = 5, device = cairo_pdf)
# Raw means
df %>%
  group_by(Hair) %>%
  summarize(`Log Income` = round(mean(logIncome),3)) %>%
  dftoLaTeX(title = "Mean Income by Hair Color",
            file = 'Identification/hairtable1.tex',
            anchor = 'tab:identification-hair1')
## [1] "\\begin{table}[!htbp] \\centering \\renewcommand*{\\arraystretch}{1.1}\\caption{Mean Income by Hair Color}\\label{tab:identification-hair1}\n\\begin{tabular}{ll}\n\\hline\n\\hline\nHair & Log Income \\\\ \n\\hline\nBrown & 5.111 \\\\ \nOther Color & 5.095\\\\ \n\\hline\n\\hline\n\\end{tabular}\n\\end{table}\n"

Figure 5.1: Distribution of Log Income by Hair Color

我们在原始数据中观察到了什么?数据显示,棕色头发的人群收入略高。虽然图中难以清晰辨认,但通过表格可以确认,他们的对数收入高出约0.01,这意味着其收入比其他发色人群高出约1%(参见第3章)。
——但这是错误的结论! 我们确切地知道,棕色头发实际会带来10%的收入溢价,而数据中仅显示出1%的差异。

要从这里得出正确答案,我们还能怎么做?
实际上无计可施。我们的数据中虽包含大学信息,但若对其在”数据生成过程\(DGPs\)“中的作用机制一无所知,便完全无法合理运用这些信息。

现在,让我们引入已知的知识——具体而言,假设我们完全掌握数据生成过程的所有环节,唯独不清楚棕发对收入的影响机制。

若已知染发人群仅限非大学学历者,且大学学历能带来收入溢价,我们便获得了对数据的新解释——观测到的棕发效应微弱,实因大量未接受高等教育的棕发群体拉低了整体表现。尽管棕发本身具有实际增益,但受学历变量干扰,其真实效应被掩盖。

理解数据生成过程\(DGP\)能帮助我们明确数据处理的正确方法。在当前\(DGP\)中可观察到:大学生群体不存在染发行为,因此除”棕发直接带来收入提升”这一因果路径外,我们无法找到其他可能导致棕发与收入相关的机制。

\(表5.2\)中,我们将分析样本限定于大学生群体。此时可观察到棕发学生获得\(13\%\)的收入溢价——虽未精确等于理论值\(10\%\)(随机扰动有时确实恼人),但已显著接近。若将此模拟研究重复千次,所得结果的平均值必将精准命中\(10\%\)的理论预期。

Table 5.2: Mean Income by Hair Color Among College Students

df %>%
  dplyr::filter(College) %>%
  dplyr::group_by(Hair) %>%
  dplyr::summarize(`Log Income` = round(mean(logIncome),3)) %>%
  vtable::dftoLaTeX(title = "Mean Income by Hair Color Among College Students",
                    file = 'Identification/hairtable2.tex',
                    anchor = 'tab:identification-hair2')
## [1] "\\begin{table}[!htbp] \\centering \\renewcommand*{\\arraystretch}{1.1}\\caption{Mean Income by Hair Color Among College Students}\\label{tab:identification-hair2}\n\\begin{tabular}{ll}\n\\hline\n\\hline\nHair & Log Income \\\\ \n\\hline\nBrown & 5.34 \\\\ \nOther Color & 5.208\\\\ \n\\hline\n\\hline\n\\end{tabular}\n\\end{table}\n"

我们究竟如何实现这一结果?最终我们得到了正确(或足够接近)的答案。关键在于运用了关于数据生成过程\(DGP\)的信息——但具体而言,我们借助这些信息试图达成什么目标?又如何确定其使用方式?此刻的讲解或许像”按我说的做”这般简略,除非您已将我的联系方式存入手机随时咨询,否则这样的指导显然不够充分5

我们可以将此分解为两个核心概念,这将是接下来两节的重点内容:

第一,寻找有效变异的思路

数据生成过程\(DGP\)揭示了所有隐藏在数据背后的运作机制,但我们仅关注其中的部分变异——在本案例中,最终需要锁定的是大学生群体内部发色差异导致的收入变异
关键问题在于: 如何精准识别所需变异并排除干扰因素?

第二,识别(identification)的核心逻辑。
我们如何利用数据生成过程\(DGP\)确保所提取的变异是目标因果效应?识别过程本质上要求辨明需清除的数据干扰类型——正如案例中非大学生群体的染发行为导致的估计偏差。

5.2 变异源何在?

稍后我将展示\(图5.2\),该散点图的\(x\)轴表示牛油果价格,\(y\)轴表示牛油果销售总量6。图中每个数据点代表\(2015年1月\)\(2018年3月\)期间,加利福尼亚州单周内的牛油果售价与销量对应关系。

请容我邀请您花些时间仔细研读\(图5.2\)。观察时请思考以下问题:

  1. 基础解读
    您能从\(图5.2\)中得出什么结论?请像机器人般严格按数据说话,避免过度解读。

  2. 关系拓展
    从更广视角思考牛油果价格与销量的关系:

    • 可提出哪些研究问题?(例如:价格上涨\(10\%\)对需求量的影响)

    • 您还能设想其他研究问题吗?

  3. 验证局限
    仅凭\(图5.2\)能否回答第二步提出的问题?说明原因。

Figure 5.2: Weekly Sales of Avocados in California, Jan 2015-March 2018

### WHERE'S YOUR VARIATION?
# AVOCADO
# Weekly Sales of Avocados in California, Jan 2015-March 2018  \label{fig:identification-avocado}

dfavo <- read_csv('Identification/avocado.csv', show_col_types = FALSE) %>%
  dplyr::filter(region == "California",type == "conventional")
## New names:
## • `` -> `...1`
dfavo <- dfavo %>%
  dplyr::mutate(`Total Volume (Millions)` = `Total Volume`/1000000) %>% 
  # order by date
  dplyr::arrange(Date)

ggplot2::ggplot(dfavo, aes(y = `Total Volume (Millions)`, x = AveragePrice)) + 
  ggplot2::geom_point(size = 1)+
  ggpubr::theme_pubr()+
  ggplot2::theme(text = element_text(size = 10, family="sans"),
          axis.title.x = element_text(size = 10, family="sans"),
          axis.title.y = element_text(size = 10, family= "sans")) +
  ggplot2::labs(y = "Total Avocados Sold (Millions)",
       x = "Average Avocado Price",
       title = "",
       caption = "Data from Hass Avocado Board\nc/o https://www.kaggle.com/neuromusic/avocado-prices/")

ggplot2::ggsave('Identification/avocado.pdf', width = 6, height = 5, device = cairo_pdf)

好的——相信各位已对这些问题有了初步答案。我们观察到了什么?

首先,\(图5.2\)的直接呈现:
数据显示明显的负向关系 。这表明:

上述分析已基本涵盖全部信息。我们或许会倾向于得出”牛油果价格上涨导致销量下降”的结论——但这一因果推断并未体现在图中;同样,若断言”价格上涨使需求减少”亦不成立。任何合格的经济学家都会指出:市场价格与交易量是供需双方共同作用的结果,而当前我们尚无法单独剥离需求端的影响。仅能确定的是:低价时段往往伴随高销量,但其内在机制仍有待探究。

其次,关于价格与销量关系可提出哪些研究问题?
潜在研究方向包括:

当然,我们还可提出更多关键问题:

每个问题的解答都需要提取数据中不同类型的变异(如工具变量法分离供给冲击或面板数据分析动态效应)。

第三,能否通过该图表解答上述问题?
遗憾的是7,答案是否定的8。图表仅能展示价格与销量的协变关系——即二者的同向或反向变动,但这些变动可能源自多种混杂因素。

为简化说明,假设将\(图5.2\)简化为仅包含连续两周数据的\(图5.3\)

Figure 5.3: Weekly Sales of Avocados in California, Jan 2015-Feb 2015

我们依然可见与\(图5.2\)相同的负向关系。但为何当年\(1月\)\(2月\)间会出现价格下跌与销量上升?潜在机制可能包括:

  1. 需求端解释:价格下降刺激消费者购买量增加?

  2. 供给端冲击:市场牛油果过剩导致价格承压?

  3. 供给响应滞后\(1月\)高价格诱发\(2月\)供应量激增?

实际情况很可能是这些因素的综合作用。变量波动往往源于多重动因,这些动因均会体现在数据生成过程\(DGP\)中。但当我们聚焦特定研究问题时,通常只需追踪其中某一机制的因果效应。

我们面临的核心任务是:如何从数据中找出能够回答我们研究问题的特定变异?整体数据过于混杂——其变异源自多种因素。但在这些数据中,隐藏着我们真正关注的因果变异。该如何将其提取出来?

首先必须明确:我们需要识别何种变异?若想探究价格对消费者牛油果购买量的影响,则需要满足两个条件的变异:

  1. 必须反映购买者行为(而非销售者行为)

  2. 必须由价格变动直接驱动(而非牛油果流行度变化等其他因素)9

诚如前一节所述,若对数据生成过程\(DGP\)一无所知,我们将完全无法开展有效分析。必须基于对\(DGP\)的认知深化理解。为此,我们需要构建关于数据来源的假设情境:假设我们确切知晓,每月初牛油果供应商会制定当月各周的定价计划,且在该月内绝不调整此计划。

ggplot(dfavo %>% dplyr::mutate(isolate=row_number() %in% 4:5), 
       aes(y=`Total Volume (Millions)`, x=AveragePrice, alpha=isolate)) + 
  ggplot2::geom_point(size=2)+
  ggpubr::theme_pubr()+
  ggplot2::guides(alpha='none') + 
  # set alpha
  ggplot2::scale_alpha_manual(values = c(0,1))+
  ggplot2::theme(text = element_text(size = 10, family="sans"),
        axis.title.x = element_text(size = 10, family="sans"),
        axis.title.y = element_text(size = 10, family= "sans")) +
  # add label
  ggrepel::geom_label_repel(aes(label = as.character(Date)), direction='y', max.overlaps=100) + 
  ggplot2::labs(y = "Total Avocados Sold (Millions)",
       x = "Average Avocado Price",
       title = "",
       caption = "Data from Hass Avocado Board\nc/o https://www.kaggle.com/neuromusic/avocado-prices/")

ggplot2::ggsave('Identification/avocado2.pdf', width = 6, height = 5, device = cairo_pdf)
## Warning: ggrepel: 14 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

若该假设成立,则“供应商定价”“供应商定产”的解释力仅存在于月份之间。而同一月份内各周的价格与销量变异,将能有效:

  1. 隔离需求端变异:仅反映消费者购买行为

  2. 剔除供给端干扰:排除供应商销售策略的影响

更进一步,由于价格由卖方设定,我们观测到的销量变异只能由价格变动驱动(即满足排他性约束)。

我们得出这一结论的能力完全基于关于供应商跨月决策的假设。设定此特定假设的目的在于:

  1. 识别隔离:仅捕捉消费者行为端的变异

  2. 排除干扰:消除供应商行为端的变异扰动

  3. 聚焦分析:实现纯买方行为的有效观测10

需特别说明的是,这一为我们提供分析便利的魔法假设,实为本书教学演示而虚构。但读者需注意:并非所有为提取变异而设定的假设都属虚构——部分假设可能具有实证基础。

通过剔除月份间的所有变异,我们实质上排除了依赖此类变异的解释机制。根据假设,供应商行为仅在月份间调整,因此当我们消除跨月变异时,便同步排除了供给端解释,最终仅保留消费者行为相关的变异。

\(图5.4\)所示,若仅考察月份内部的变化,仍可观测到显著的负向关系。需注意:每个独立月份内部均存在该负向关系(忽略月份间差异)。因此,结合数据特征与供应商行为模式可知:价格上涨确实会降低消费者的牛油果需求意愿

Figure 5.4: Weekly Sales of Avocados in California, Feb 2015-Mar 2015

研究问题的解答本质上取决于对变异源的定位与提取。原始数据中的变异往往难以直接回答核心研究问题,因此必须明确:

  1. 目标变异何在?何种变异能有效解答您的问题?

  2. 提取方法为何?如何识别并分离该变异?

  3. 干扰项如何剔除?需清除哪些干扰变异以揭示底层因果机制?

这一过程——即定位目标变异所在,并隔离该部分变异以确保研究问题得到准确解答——被称为识别(identification)

5.3 识别

周二清晨,\(Abel\)\(Annie \space Vasquez\)醒来时,发现他们忠实的爱犬\(Rex\)并未如常趴在床脚。夫妇俩惊慌失措地在屋内四处搜寻,呼喊着它的名字、吹口哨、拿零食引诱。最终,其中一人打开前门,看到\(Rex\)正坐在草坪上摇着尾巴。他们将它带回了屋内。

“我一直提醒你要锁好宠物门,”\(Abel\)说。
“它根本不用那扇门。我打赌它是从地下室那扇开着的窗户跳出去的,”\(Annie\)反驳道。
“是啊,”\(Abel\)翻了个白眼应和。当晚,他特意锁好了宠物门。

周三清晨,当\(Abel\)\(Annie \space Vasquez\)再次醒来时,阳光和煦,自动咖啡机的香气已飘进卧室——而\(Rex\)又一次不见了踪影。

这次他们很快就在草坪上找到了\(Rex\)——它正在露水里打滚,有一小块皮毛已被磨得发红。显然,无论它用什么方式逃出去,每晚的路线都如出一辙。

当晚,他们锁好宠物门并给后门上了双重门闩。周四清晨,\(Rex\)依然失踪。
周四夜里,他们锁好宠物门、双重门闩后门、拉上所有窗帘。周五清晨,\(Rex\)再次消失。
周五夜间,他们锁好宠物门、双重门闩后门、拉紧窗帘、封住通风口。周六早晨,当他们在户外找到\(Rex\)时,它已经吃掉两只蝴蝶。

“我受够了,”\(Abel\)说道。周六晚,他们锁死每扇门窗,用木板封住烟囱,填补车库木板间半英寸的缝隙,堵住浴缸排水口,并对\(Rex\)进行了严厉的训话。

周日清晨,\(Annie\)下楼时,发现\(Abel\)正失魂落魄地坐在门阶上,盯着又一次成功”越狱”的爱犬。

“我不明白……明明堵住了所有可能的出口——每道缝隙、每个孔洞,所有逃生路线都被封死了。可它还是跑出去了!”\(Abel\)沮丧道。

\(Annie\)抿了口咖啡,淡定回应:“哦,我昨晚睡前又把地下室窗户打开了。早就告诉过你,它就是从那儿溜出去的。”

识别(Identification)的本质,是确定数据中能够解答研究问题的特定变异部分。这一过程之所以称为”识别”,是因为通过该方法,我们得以确保最终测算结果精准指向目标理论机制。换言之,我们已排除所有干扰线索,成功锁定真正的”元凶”。

研究问题(research question)搭建了从理论到假设的桥梁,确保所检验的假设能真正揭示理论内涵;而识别(identification)则构建了从假设到数据的通路,保证我们检验的是目标假设本身,而非其他干扰性假设。

\(Abel\)\(Annie\)的案例为例:实际数据中我们观察到什么?每晚封锁房屋的不同区域(自变量),而\(Rex\)总能成功”越狱”(因变量)。\(Annie\)的研究问题聚焦于:地下室窗户的开放状态是否为\(Rex\)逃脱的关键机制

我们(以及\(Abel\))都清楚,房屋存在多种逃脱路径。因此,仅凭当前数据无法解答\(Annie\)的研究问题。随着\(Abel\)逐步封锁更多出口,他实质上排除了部分干扰性变异——每封锁一处,\(Rex\)除窗户外的潜在逃脱路线就减少一条。这使得\(Annie\)关于”窗户是逃脱关键”的结论出错概率持续降低,但其他解释可能性仍未完全消除

当封锁房屋所有其他潜在出口后——若仅剩窗户未被封堵,便只能得出唯一结论:窗户开放正是\(Rex\)逃脱的原因。这一观测结果通过系统排除所有竞争性解释,最终锁定了问题的答案。

实证研究中解答研究问题的识别过程,本质上同样遵循这一方法论:通过逐步消除替代性解释,直至隔离出目标因果机制

回顾前文的牛油果案例:正如\(Abel\)\(Annie\)需要排查爱犬所有可能的逃脱路径,我们也必须厘清价格与销量之间所有潜在的关联机制。一旦理解数据生成过程\(DGP\)——即价格与销量可能产生关联的全部途径——便能明确后续分析所需的工作。

遵循与\(Abel\)夫妇相同的逻辑:通过消除由供应商驱动的月份间变异(相当于封锁除地下室窗户外的所有出口),我们排除了干扰性解释。此时,价格对销量的影响唯一可能通过消费者行为这一路径实现。

识别(Identification)的实现需要双重基础:

  1. 统计技术:通过计量方法剔除非目标变异

  2. 理论与假设:基于对现实运行规律的理解,预判干扰因素并选择对应统计工具

具体而言,识别依赖于对数据生成过程\(DGp\)的理论预设。唯有明确已知知识边界,方能探索新的因果发现。以牛油果案例为例:

必须承认,依赖假设来完成因果识别的过程似乎难以令人完全信服——但这一步骤不可或缺。试想,若\(Abel\)\(Annie\)在毫无假设、也不理解数据生成过程\(DGP\)的情况下分析爱犬逃脱机制,他们将不得不考虑诸如“狗会瞬移”“宇宙是全息投影”,乃至“墙壁存在仅犬类可见的隐形通道”等荒诞解释。如此不仅无法得出有效结论,更可能沦为哲学思辨的囚徒11

因此,我们的核心目标可明确为:若要识别数据中能解答研究问题的关键变异,必须遵循以下步骤——

  1. 理论建模:基于现有理论,尽可能精准刻画数据生成过程\(DGP\)的运作机制

  2. 干扰识别:根据\(DGP\)解析可能存在的非目标解释(即与研究问题无关的数据变异来源)

  3. 变异提取:通过计量方法阻断干扰因素,从而分离出目标因果变异

这一过程远比”直接观察数据表面现象”复杂得多。但若不愿多走几步完成上述步骤,我们很可能得出混乱、矛盾甚至完全错误的结论。接下来让我们看看,当识别工作未能充分落实时,会导致何种后果。

5.4 酒精与死亡率

若您习惯关注以”最新研究表明……“开头的新闻报道,可能会对酒精的健康影响产生严重困惑。某些研究宣称每周少量饮酒比完全不饮更健康;另一些则指出任何剂量的酒精都不安全;还有观点认为仅葡萄酒具有保健功效12

让我们审视一项关于酒精对全因死亡率(即早逝风险)影响的重要研究13。该研究由\(200\)余位学者共同完成,基于近\(60\)万人的样本,分析了饮酒与死亡率、心血管疾病等健康结局的关联。\(2018年\)发表于顶尖医学期刊《柳叶刀》\(The \space Lancet\),并成为制定医学饮酒指南的关键依据14

这项备受推崇的研究得出两个关键发现:首先,少量饮酒并未显现出健康益处;其次,当每周酒精摄入量达到\(100\)克(约每日一杯)时,死亡率等严重风险开始显著上升——该阈值甚至低于部分国家的现行指南标准。如\(图5.5\)所示,每周酒精消费量与死亡率呈\(J\)型关系:风险曲线在\(100\)克/周处出现拐点,之后急剧攀升。

Figure 5.5: Alcohol Consumption and Mortality from Wood et al. (2018).

# Data extracted from published graph using https://apps.automeris.io/wpd/
alc_mort <- read_csv('Identification/alcohol_mortality_digitizer.csv') %>%
  # Identify points by sets of three
  mutate(point = floor((row_number()-1)/3)) %>%
  group_by(point) %>%
  # The actual point is the first one
  mutate(datactr = row_number() == 1) %>%
  # make the x axes all identical
  mutate(X = mean(X)) %>%
  # Make the top and bottom equidistant from center
  pmdplyr::mutate_subset(Ycenter = Y, .filter = datactr) %>%
  pmdplyr::mutate_subset(Ydist=mean(abs(Y-Ycenter)), .filter = !datactr)
## Rows: 24 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (2): X, Y
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ggplot(alc_mort %>% dplyr::filter(datactr), aes(x=X, y=Y, ymin = Y-Ydist, ymax = Y+Ydist)) +
  # geom_errorbar(size = 1,width = .5) + 
  geom_point(size = 2) +
  geom_hline(aes(yintercept=1), size = .3, linetype = 'dashed') + 
  theme_pubr() + 
  labs(x="Usual Alcohol Consumption (Grams/wk)", y="Hazard Ratio (1 = no effect)") + 
  theme(text         = element_text(size=10, family="sans"),
        axis.title.x = element_text(size=10, family="sans"),
        axis.title.y = element_text(size=10, family= "sans"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

ggsave('Identification/original_alcohol_mortality.pdf', width = 6, height = 5, device = cairo_pdf)

通过本章前文的论述我们已经明确:要正确解读数据,就必须深入思考其背后的数据生成机制。

数据生成机制的本质是什么?究竟是哪些因素导致我们观察到人们的饮酒行为?又是哪些机制决定我们记录到他们的死亡事件?更重要的是——酒精消费与死亡率之间的关联性,可能隐藏着多少种不同的解释路径?

请暂停片刻完成以下思维训练:首先列举五个可能导致饮酒(或至少与饮酒相关)的因素;随后列出五个影响死亡率的因素。若存在同时出现在两个清单中的变量,则更能说明问题——这正是识别替代性解释的关键所在。

你想到哪些影响饮酒量和死亡率的因素了吗?可能性确实不胜枚举。比如,冒险倾向可能让人饮酒更多,同时也可能导致吸烟等其他行为——因此冒险性格既是饮酒的诱因,也通过吸烟与饮酒产生关联。至于死亡率,任何不良健康指标都可能导致死亡,吸烟或冒险行为亦然,甚至从事高危职业也会产生影响。此类混杂因素\(confounding \space factors\)的存在意味着:酒精与死亡率的观测关联,可能完全由吸烟行为驱动。

由此可以立即得出:任何同时出现在两个列表中的因素,都将自动成为研究结果的”干扰解释”。以吸烟为例——如果吸烟者更可能饮酒,而吸烟本身又会增加死亡率,那么饮酒与死亡率的相关性可能仅仅源于:吸烟者往往既饮酒,又因吸烟而更早死亡。任何同时满足这两个条件的变量,都会为我们提供新的干扰解释。

还有一个容易被忽略的因素——完全不饮酒的人群。如果饮酒危害极大,戒酒者理应有极低的死亡率?理论上如此,但请牢记数据生成机制:人们戒酒的原因是什么?部分人因健康状况不佳而被迫戒酒,另一些则是康复中的酗酒者。这些情况下,戒酒人群反而可能呈现更高的死亡率——但这绝不意味着”不饮酒有害健康”。这同样是个需要排除的干扰解释。

容我再次打扰各位15。经过更深入的思考后,请暂停片刻,试着列举更多可能解释酒精与死亡率相关性的非因果机制——这并非随堂测验,但培养这种思维习惯至关重要:既能帮助理解本书内容,也能提升解读新研究成果的能力。

值得欣慰的是,\(Woods\)等人的研究确实成功处理了部分替代性解释——他们对数据生成过程\(DGP\)进行了深入考量。

您可能已注意到,\(图5.5\)中实际上排除了非饮酒者群体。研究者刻意剔除该人群,旨在阻断”因病忌酒”和”戒酒康复者健康损耗”这两类干扰因素。这也解释了为何该研究未发现少量饮酒的保护效应,而其他研究却得出相反结论——因为那些研究(失误地)保留了非饮酒者数据!

研究者还通过统计调整方法排除了部分干扰因素:除了我们关注的吸烟变量外,他们还校正了年龄、性别等人口学特征,以及体重指数\(BMI\)、糖尿病史等健康指标的影响。

所以它们就是可靠的,对吗?其实未必。研究者虽然排除了部分干扰因素,但并不意味着解决了所有潜在问题。我们之前就提到过冒险倾向这个变量——他们虽然控制了吸烟因素,但冒险性格的影响远不止于此,而这类特质本身就难以精确测量。再看戒酒人群的处理:他们排除了因病戒酒或曾酗酒的样本,但这样也把许多健康的不饮酒者一并剔除了。更值得警惕的是,某些重症患者可能只是减少饮酒量而非完全戒除。诸如此类未被纳入考量的因素还有很多,甚至读者在阅读本章时可能都已发现不少疏漏。研究团队确实对数据生成机制进行了思考,但要么思考得还不够深入,要么即便考虑周全,现实中也不可能真正做到面面俱到。

对于他们的研究结果,仍然存在一些无法排除的其他解释。因此,尽管他们研究了数十万人,现在就利用这些结果来断言我们已经确定了酒精对死亡率的影响,可能还为时过早。

乍看之下,研究者似乎已经尽力排除了部分干扰因素,剩下的问题似乎无关紧要——但请注意,这些未被解决的干扰因素完全可能推导出极其荒谬的结论。\(Chris \space Auld\)在研读该论文后16,直接套用原研究的方法论,“证明”了饮酒量增加会导致人变成男性(参见\(图5.6\))。

Figure 5.6: Alcohol Consumption and Being a Man

# Alcohol and Maleness
# Data extracted from published graph using https://apps.automeris.io/wpd/
alc_male <- read_csv('Identification/alcohol_male_digitizer.csv', show_col_types = FALSE) %>%
  #X-axis is on round numbers
  mutate(X=round(X,0),
         # Odds ratio for similarity
         Y=Y/(1-Y))

ggplot(alc_male, aes(x=X, y=Y)) + 
  geom_point(size=2) +
  # 添加一条水平虚线,y = 1,作为参考线。Odds Ratio=1 表示该饮酒水平下事件发生的概率没有变化(即“无影响”基准线)
  # 若某点在该线上方,表示增加事件发生几率;若在下方,则可能降低事件发生几率
  geom_hline(aes(yintercept=1), size = .3, linetype = 'dashed') + 
  theme_pubr() + 
  labs(x="Drinks Per Week", y="Odds Ratio (1 = no effect)") + 
  theme(text         = element_text(size=10, family="sans"),
        axis.title.x = element_text(size=10, family="sans"),
        axis.title.y = element_text(size=10, family= "sans"))

ggsave('Identification/auld_alcohol_male.pdf', width = 6, height = 5, device = cairo_pdf)

“饮酒会让人变成男性”这种结论显然荒谬至极,相比之下,“酒精确实会提高死亡率”的说法则显得合理得多。但既然同样的研究方法能得出\(图5.6\)这样的结果,那么即便酒精确实会影响死亡率,我们又怎能确定\(图5.5\)所显示的效果就真的接近事实呢?
如此说来,媒体和医学权威对这项研究(以及类似研究)所表现出的确定性,是否多少令人不安?该研究的作者无疑发现了一个非常有趣的关联,并排除了一些干扰因素。但他们真的回答了你最关心的研究问题吗——饮酒究竟如何影响健康?这恰恰是制定医疗酒精指南等政策时最需要解答的问题。他们是否考虑了所有必要的背景因素?甚至有可能做到面面俱到吗?

5.5 研究背景与全知视角

本章最希望阐明的一个核心观点是:对于大多数研究问题——尤其是涉及因果关系的议题——理解研究背景至关重要。若不清楚数据从何而来,就根本不可能排除其他干扰因素,从而找到问题的真正答案。

用乔舒亚·安格里斯特和艾伦·克鲁格(2001)的话来说1718

此处的挑战主要不在于技术层面——即不需要新的定理或估计方法。真正的突破来自对特定研究场景的深刻制度性认知,以及对其中作用力的细致考察与量化。当然,这种努力并非新事物,它始终是优秀实证研究的核心所在。

两位学者当时具体讨论的是工具变量法的识别问题(参见第19章),但这一洞见具有普适意义。在试图通过实证研究回答问题前,务必投入充足时间理解数据来源的背景及其运作机制。尽可能完整地还原数据生成过程!这对正确解读研究结果至关重要,也能确保不会遗漏其他同样合理的解释——那些你无法排除的干扰因素。

这意味着对研究背景的深入理解具有决定性作用。那么,应该如何着手设计研究项目呢?答案是从大量背景研究开始。研读与研究环境相关的专著,查阅政策实施的文件记录,收集实际运作的一手资料并与相关人士访谈。务必确保细节准确,因为数据生成过程中每一个环节都体现着这些你本应掌握的细节。

这则消息对你而言可能是令人振奋的,也可能是极其沮丧的——取决于你是哪种类型的研究者19

或许最理性的态度是:将这种对研究背景的必要依赖,既视为重大机遇,也看作对我们认知局限的揭示

这同时也是一个绝佳的机会——因为这意味着你将掌握大量新知。而获取知识本身就有趣。如果我们不喜欢学习,当初根本就不会对研究产生兴趣。更何况,研究背景的探索往往正是研究灵感的来源。如第2章所述,提出研究问题的绝佳方式,就是通过观察某个环境或情境,意识到其中存在尚未被理解的重要现象。若你正采用这种方式,那么当你形成研究问题时,背景研究的部分其实早已完成。

这种背景知识的积累还能帮助你排除其他干扰解释。比如,一个对物理学一无所知的研究者,在探讨重力问题时或许能猜到行星运动不是魔法所致;但真正研究过行星运行规律的人,则能通过精确计算证明:仅用动量无法完全解释其运动轨迹——必须引入重力因素。

然而,对背景知识的依赖同时也暴露了我们的认知局限。如果我们只有在充分理解研究背景时才能回答科学问题,那么成功的研究项目往往只会出现在我们已基本掌握的领域——这未免乏味!那些无人涉足的狂野前沿领域呢?显然完全忽视它们绝非明智之举。毕竟,即便难以得出确切结论,像”酒精对死亡率的影响”这类重要问题,我们也不能置之不理。

我们当然不应放弃那些激动人心的未知研究领域。但对背景知识的依赖意味着:我们必须做好准备,接受这些研究结果可能更具争议性、更容易被其他解释所质疑——它们本质上更偏向”探索性研究”。这正是学术谦逊的体现,实属好事。认知有限,则结论亦有限。若忘记这点,当我们掌握更多知识后,那些曾经妄下的断言终将被证伪。

这种现象在社会新事物出现时几乎总会重演——无论是小说、铁路、普选制、电视、互联网还是电子游戏。当这些新生事物刚出现时,我们根本无从知晓它们在数据生成过程中的作用,因为尚未积累相关数据。但这丝毫阻挡不了人们对其”拯救/毁灭整个社会”的疯狂断言。总会有粗制滥造的研究成果,既让拥趸们欢欣鼓舞,又让质疑者振振有词——直到我们真正理解这些事物的运作机制,所有论断终将被推翻。

即便在更微观的研究层面,对背景知识的渴求同样令人却步。且不说研究飞行汽车或外星人的影响——单是要弄清牛油果价格对销量的影响,我们需要掌握多少背景知识?纵使你潜心研究数年成为顶尖专家,仍无法穷尽所有认知。若要真正识别数据中所有潜在干扰因素,完全理解那些诱人却隐形的底层规律,研究者几乎需要具备”全知视角”。你又如何确保自己的研究毫无疏漏?

好吧…你确实做不到!
很遗憾。
没有任何研究项目是完美的。我们唯一能期待的是:
• 尽可能掌握研究背景,避免遗漏数据生成过程中的关键要素
• 谨慎申明所有前提假设,并反思其可能的谬误
• 主动识别对数据生成过程的认知空白,并做出合理推测
• 不追求完美,但求无限接近真相

若执着于追求全知全能,我们注定失败——因此这毫无意义。但追求研究价值却意义非凡。为此,我们只需做到:汲取所能获取的知识,严谨推进研究,并努力将误差控制在最小范围。


  1. 这个‘基本上’的意思是‘不要给我发关于量子引力之类的愤怒邮件’。↩︎

  2. 以彗星闻名的埃德蒙·哈雷,在此也扮演了一个角色。↩︎

  3. 如果我们不相信存在某种潜在的、近似规律的法则,那么从事社会科学研究就没什么意义了,或者至少将其视为一门科学来思考就没什么意义了。不用费多大力气就能找到一些物理科学的拥趸,他们基于此判定社会科学不算一门科学。他们说得对吗?这是个有趣的问题。但这是一本科学哲学著作在状态好的时候才会探讨的问题,或是状态不好时在\(YouTube\)评论区里才会讨论的问题,而不是本书要探讨的内容。↩︎

  4. 这些规则的数学表达为:

    Pr(大学) = 0.3

    Pr(棕色头发) = 0.2 + 0.8 x 0.4 x (大学 == 0)

    log(收入) = 0.1 x 棕色头发 + 0.2 x 大学 + ε 其中 ε 服从正态分布。↩︎

  5. 若您确需就识别策略问题来电咨询,请仅限于工作时间联系。↩︎

  6. 出于培养统计思维的目的——或许也为了激怒某些经济学家——本图将价格置于\(x\)轴而非\(y\)轴。↩︎

  7. 除非您的研究问题确实仅关注相关性本身——这种情况下,您完全可以从图表中得出明确答案。事实上,探究相关性本身也是一个有价值的研究方向。↩︎

  8. 除非你的研究问题真的只是想探究两者之间的相关性——这当然是个可以明确回答的问题,而且本身也是个有价值的研究命题。↩︎

  9. 进阶说明:细心的读者可能已注意到,该方法与Angrist & Pischke(2008)提出的”理想实验”范式既存在相通之处,又存在关键差异↩︎

  10. 我们能否在不依赖这个奇怪假设的前提下,识别出真正想要研究的效应?当然可以!只不过操作起来相当巧妙。当研究结果来自两个独立系统(比如买方和卖方)的共同作用时,分析就会变得棘手。但研究者们总能找到方法——通常通过”工具变量”等手段——来分离出单方面的变动因素,第19章将对此展开详细讨论。↩︎

  11. 诚然,虽然无法完全避免假设,但我们可以确保其合理性。例如:

    • 可接受假设:“犬类不具备瞬移能力”

    • 待验证假设:“供应商每月初制定全月定价且绝不调整”(在缺乏额外证据时,该假设略显牵强)

    ↩︎
  12. 这种现象不仅见于酒精,几乎涵盖所有常见食品——巧克力、鸡蛋、小麦等。本月还被奉为养生佳品,下月就可能被列为健康杀手。↩︎

  13. Angela M Wood, Stephen Kaptoge, Adam S Butterworth, and 239 more. Risk thresholds for alcohol consumption: Combined analysis of individual-participant

    data for 599,912 current drinkers in 83 prospective studies. The Lancet, 391 (10129):1513–1523, April 2018. doi: 10.1016/S0140-6736(18)30134-X.
    ↩︎

  14. Jason Connor and Wayne Hall. Thresholds for safer alcohol use might need lowering. The Lancet, 391(10129):1460–1461, 2018.
    ↩︎

  15. 除非你正为应付课堂测验而阅读本书——那确实可能有随堂测试。↩︎

  16. Chris Auld. Breaking news! https://twitter.com/Chris_Auld/status/1035230771957485568, 2018.Accessed: 2020-02-20.
    ↩︎

  17. Joshua D. Angrist and Alan B. Krueger. Instrumental variables and the search for identification:From supply and demand to natural experiments. Journal of Economic Perspectives, 15(4):69–85, December 2001.↩︎

  18. 版权归属美国经济学会;经《经济展望杂志》许可转载。↩︎

  19. 我必须承认,这确实令人沮丧。什么?你的意思是,我必须先理解现实世界的运作方式,才能研究现实?如果我们都默认世界就该像我脑海中设想的那样运转,我本可以证明更多有趣的结果。↩︎