在第一章中,我将向你介绍因果推断的诸多基本概念,以及它的主要挑战和用途。在这里,你会学到本书其余部分会用到的大量术语。此外,我希望你始终牢记为何需要因果推断,以及能用它做些什么。本章不涉及编码内容,而是关于因果推断非常重要的初步概念 。

什么是因果推断?

因果关系,你或许知道它是一片危险的认识论领域,得避而远之。你的统计学老师可能反复讲过“相关并非因果”,混淆二者会让你在学术上遭排斥,至少也会饱受诟病。但问题就在于:有时,相关就是因果。

我们人类对这点再清楚不过,因为显然,我们天生就倾向于把相关当成因果。当你决定不喝第四杯葡萄酒时,你正确推断出这会让你次日难受。你借鉴了过往经验:那些喝太多、次日头疼醒来的夜晚;那些只喝一杯、甚至一杯没喝,次日毫无不适的夜晚。你已然明白,饮酒和宿醉之间的关联,背后另有深意。你从中推断出了因果关系 。

另一方面,你的统计学老师的警告也有一定道理。因果关系是个棘手的事儿。我小时候,吃过两次油炸鱿鱼,两次吃完都特别不舒服,于是我断定自己对鱿鱼(还有蛤蜊、章鱼以及其他任何海洋无脊椎动物)过敏。过了20多年我才再次尝试。再次吃的时候,它不仅美味,而且没给我造成任何伤害。在这种情况下,我把相关关系错当成了因果关系。这是一场无害的混淆,因为它只是让我多年没吃到美味的海鲜,但把相关关系错认为因果关系可能会产生严重得多的后果。要是你投资股票市场,你可能遇到过这样的情况:你决定在价格大幅上涨前投入资金,或者在一切崩盘前撤出资金。这可能会诱使你认为自己能把握市场时机。要是你成功克制住了这种诱惑,那很好。但很多人会信以为真,觉得自己的直觉和股票的异常波动存在因果关联。在某些情况下,这种信念会导致赌注越来越冒险,最终几乎失去一切。

简而言之,相关性指的是两个量或随机变量一同变化,而因果关系是指一个变量的变化导致另一个变量的变化 。比如,你可以把一个国家获得的诺贝尔奖数量和人均巧克力消费量联系起来,但即便这些变量可能一同变化,认为其中一个导致另一个也是愚蠢的。看出相关性不意味着因果关系很容易,但把二者划等号就是全然不同的事了。因果推断是一门从相关性中推断因果关系,并理解二者何时以及为何不同的科学 。

我们为何要进行因果推断

因果推断可以单纯为了理解现实而进行,但它往往也包含规范层面的因素。你推断过量饮酒会引发头痛,原因在于你想要改变饮酒习惯以避免疼痛。你所在的公司想要知晓营销成本是否会推动收入增长,因为如果确实如此,管理者就能将其作为提升利润的手段。一般来说,你想要了解因果关系,这样你就能对原因进行干预,从而达成预期的结果。要是你把因果推断应用到行业中,它在很大程度上就会成为决策科学的一个分支 。

由于本书主要面向行业应用,它会涵盖因果推断中专注于理解干预影响的部分。要是你对商品采用另一种价格,而非当前定价,会发生什么情况?要是你从目前的低糖饮食换成低脂饮食,会怎样?要是银行提高客户的信用额度,银行的利润率会有什么变化?政府是应该给学校里的每个孩子配备平板电脑以提高他们的阅读测试成绩,还是应该建一座传统图书馆?结婚对你的个人财务有益吗,抑或已婚夫妇更富有只是因为富人原本就更有可能吸引到伴侣?这些问题都很实际。它们源于一种渴望,即改变你工作或生活中的某些事物,从而让自己过得更好。

机器学习与因果推断

要是你深入审视想用因果推断来回答的问题类型,会发现它们大多是”如果……会怎样”\((what \space if)\)这类问题。很抱歉这么说,但机器学习\((ML)\)在处理这类问题上真的很糟糕。 机器学习非常擅长回答预测类问题。正如阿贾伊·阿格拉瓦尔\((Ajay \space Agrawal)\)、约书亚·甘斯\((Joshua \space Gans)\)\(Avi \space Goldfarb\)\(《Prediction \space Machines》\)(哈佛商业评论出版社出版)一书中所言:“新一轮人工智能浪潮并未真正给我们带来智能,而是带来了智能的一个关键组成部分——预测能力。借助机器学习,你可以完成各种各样美妙的任务。唯一的要求是把你的问题转化为预测类问题。想把英语翻译成葡萄牙语?那就构建一个机器学习模型,让它在给定英语句子时预测出葡萄牙语句子。想进行人脸识别?那就创建一个机器学习模型,让它预测图片的某个子区域中是否有人脸。”

然而,机器学习并非万能灵药。在严格限定的范围内,它能创造奇迹,但要是数据与模型习惯处理的数据稍有偏差,它就可能惨败。再举\(《Prediction \space Machines》\)里的一个例子,“在很多行业,低价与低销量相关联。比如,在酒店行业,旅游淡季时价格低,需求最高、酒店满客时价格高。依据这些数据,一个简单的预测可能会认为,提高价格会带来更多客房销量。”机器学习利用变量之间的相关性,从一个变量预测另一个变量。只要你不改变它用于预测的变量,它的效果会好得惊人。但这对于大多数涉及干预行为的决策而言,完全背离了使用预测性机器学习的初衷 。

大多数数据科学家对机器学习了解颇多,但对因果推断知之甚少,这就导致大量机器学习模型被部署在对当下任务并无用处的场景中。企业的主要目标之一是提高销售额或产品使用率。然而,一个仅用于预测销售额的机器学习模型,往往对实现这一目标毫无用处,甚至有害。这个模型可能会得出一些荒谬的结论,就像前面例子中,高销量与高价格相关联那样。但令人惊讶的是,很多企业在目标与预测毫无关联的情况下,仍会部署预测性机器学习模型

这并不意味着机器学习在因果推断中完全无用。只是说,如果单纯去应用,它往往弊大于利。但要是你从不同角度看待机器学习,将其视为一个包含强大模型的工具箱,而非纯粹的预测机器,你就会开始明白它们如何与因果推断的目标相契合。在第三部分\((Part \space \text{III})\),我会讲讲当把机器学习和因果推断结合时需要注意什么,以及如何改造常见的机器学习算法,像决策树和梯度提升算法,来进行因果推断 。

相关性与因果关系

直观来讲,你大概明白为什么相关性不等于因果关系。要是有人跟你说,顶尖咨询服务能让你的生意好转,你肯定会心存疑虑。你怎么知道是咨询公司真的促成了生意改善,还是仅仅因为只有蓬勃发展的企业才有财力购买那些服务呢? 为了把事情说得更具体些,不妨设身处地站在一家在线电商平台公司的角度想想。中小企业借助你的在线平台做广告销售产品。这些企业在定价、何时开展促销等方面拥有完全的自主权。但这些企业蓬勃发展对你的公司而言是最有利的。于是,你决定为它们提供指导,告诉它们如何、是否以及何时开展促销活动——也就是向消费者宣布暂时降价。要这么做的话,你首先得弄清楚降价对销量的影响。要是多卖产品带来的收益能抵消低价销售造成的损失,开展促销就是个好主意。要是你还没察觉到,这就是个因果问题。你得弄明白,企业降价相较于不采取任何行动,会多卖出多少产品 。

不用说,这是个复杂的问题,对于本书开头部分而言,可能太复杂了。你的平台上有不同的商家。有些卖食品,有些卖服装,有些卖化肥和农产品。因此,降价的影响可能因商家类型而异。比如,一家服装商家在父亲节一周前宣布降价可能是个好主意,但农业商家类似的降价可能效果甚微。所以,咱们把问题简化一点。咱们把注意力集中在一种商家类型上:销售儿童玩具的商家。另外,咱们把注意力集中在一年中的一个时间段:圣诞节前的\(12月\)。目前,你只需试着弄清楚在这些时间段降价如何促进销售,这样你就能把这些信息传达给儿童玩具行业的商家,让它们做出更优决策。

要判断开展促销活动(降价促进销售这种活动 )是否是个好主意,你可以利用多家儿童玩具商家的信息。这些数据存储在一个\(pandas \space dataframe\)中,供你访问。以下是数据框的前几行,让你了解一下要处理的数据情况:


import pandas as pd
import numpy as np
from scipy.special import expit
import seaborn as sns
from matplotlib import pyplot as plt
from cycler import cycler



default_cycler = (cycler(color=['0.3', '0.5', '0.7', '0.5']) + cycler(linestyle=['-', '--', ':', '-.']) +  cycler(marker=['o', 'v', 'd', 'p']))
color=['0.3', '0.5', '0.7', '0.5']
linestyle=['-', '--', ':', '-.']
marker=['o', 'v', 'd', 'p']

plt.rc('axes', prop_cycle=default_cycler)
plt.rc('font', size=20)
data = pd.read_csv("./data/xmas_sales.csv")
data.head(6)
##    store  weeks_to_xmas  avg_week_sales  is_on_sale  weekly_amount_sold
## 0      1              3           12.98           1              219.60
## 1      1              2           12.98           1              184.70
## 2      1              1           12.98           1              145.75
## 3      1              0           12.98           0              102.45
## 4      2              3           19.92           0              103.22
## 5      2              2           19.92           0               53.73

\(1\) 列是店铺的唯一标识符 \(\text{ID}\)。你有 \(12月\) 期间每家店铺的周度数据。你还掌握着以当年每周平均销售产品数量\((avg\_week\_sales)\)衡量的各商家规模信息。 有 \(1\) 列布尔值\((0或1)\)标识商家当时是否在进行促销。最后 \(1\) 列显示该店铺当周的平均周销售额 。


分析单位

因果推断研究中的分析单位,通常是你希望进行干预处理的对象。多数情况下,分析单位会是人,比如当你想了解新产品对客户留存的影响时。但也常有其他类型的分析单位。例如,在本章的例子里,分析单位是商家。在同一个例子中,你也可以尝试回答开展促销的最佳时机是什么,这种情况下,分析单位就会是一个时间段(此处为周 )。


处理与结果

现在你有了一些数据可以研究,是时候学习第一个专业术语了。咱们把第 \(i\) 个分析单位的处理(干预)记为 \(T_i\)

\(T_i = \begin{cases} 1 & \text{若分析单位 } i \text{ 接受了处理(干预)} \\ 0 & \text{反之} \end{cases}\)

这里的”处理干预” 不一定得是药物或者医学领域的东西。其实,它只是我用来表示某种干预的一个术语,我想了解这种干预产生的效果。在这个例子里,处理干预就是你在线平台上某家商家的降价行为,由 \(is\_on\_sale\) 这一列来表示。


处理干预的符号表示

在一些文献以及本书后续内容里,你有时会看到用 \(D\) 而非 \(T\) 来表示处理干预。当你的因果问题涉及时间维度时,用 \(D\) 能避免很多混淆。


此外,我会把 \(weekly\_amount\_sold\)(我此处想要影响的变量 )称作结果。我会用 \(Y_i\) 表示分析单位 \(i\) 的结果。有了这两个新概念,我可以把因果推断的目标重新表述为:了解处理干预 \(T\) 对结果 \(Y\) 产生的影响的过程。在我们的例子中,这就等同于弄清楚 \(is\_on\_sale\)\(weekly\_amount\_sold\) 的影响 。

因果推断的根本问题

接下来就是有趣的部分了。因果推断的根本问题在于,你永远无法在同一分析单位上同时观察到接受处理干预和不接受处理干预的情况。这就好比你面前有两条分岔路,却只能知道走了的那条路前方有什么。为了充分理解这个问题,咱们回到之前的例子,按处理干预情况来描绘结果,也就是按 \(is\_on\_sale\) 来呈现 \(weekly\_amount\_sold\)。你会立刻发现,降价的店铺销量要高得多(见\(图1-1\))。


fig, ax = plt.subplots(1,1, figsize=(10,5))
sns.boxplot(y="weekly_amount_sold", x="is_on_sale", data=data, ax=ax)

ax.set_xlabel("is_on_sale", fontsize = 10)
ax.set_ylabel("weekly_amount_sold", fontsize = 10)
# 设置 x 轴和 y 轴的主刻度标签字体大小为 10
ax.tick_params(axis='both', which='major', labelsize=10)

这也符合我们对世界运行方式的直觉:人们在价格低的时候会买得更多,而促销通常意味着更低的价格。这很不错,因为因果推断与专业知识是相辅相成的。但你也别太掉以轻心。开展折扣活动并宣传折扣,确实可能会让顾客买得更多。但能多这么多吗?从\(图1-1\)来看,促销期间的平均销量似乎比不促销时高出约 \(150单位\)。这听起来高得可疑,因为不促销时的销量范围大概在 \(0-50单位\) 之间。如果你稍微动动脑筋,就会开始意识到,你可能把相关性错当成了因果关系。有可能实际情况是,只有规模较大的商家(也就是本来销量就最多的商家 )才负担得起大幅降价。也有可能商家在临近圣诞节时开展促销,而不管怎样,那段时间顾客的购买量本来就最多

关键在于,只有当你能在同一时间,观察到同一家企业(同一分析单位 )既开展促销又不开展促销时的情况,你才能确切知晓降价对销量的真实影响。只有对比这两种反事实情况,你才能确定降价的效果。然而,正如之前所讨论的,因果推断的根本问题就在于,你根本无法做到这一点。所以,你得另想办法。

因果模型

你可以凭直觉去思考所有这些问题,但要是你想超越简单的直觉,就需要一些形式化的符号表示。这会成为我们探讨因果关系时的常用语言。把它想象成我们和其他因果推断从业者交流时通用的行话 。

因果模型是一系列由”\(\leftarrow\)“表示的赋值机制。在这些机制中,我会用 \(u\) 表示模型之外的变量,这意味着我不会对它们的生成方式做出说明。其他所有变量都是我非常关注的,因此会被纳入模型。最后,存在一些函数 \(f\),用于将一个变量映射到另一个变量。以下面这个因果模型为例:

\(\begin{align*} T &\leftarrow f_t(u_t)\\ Y &\leftarrow f_y(T, u_y) \end{align*}\)

对于第一个方程,我是在说 \(u_t\)(一组我未明确建模的变量,也叫外生变量 )通过函数 \(f_t\) 引发处理干预 \(T\)。接下来,\(T\) 与另一组变量 \(u_y\)(我同样选择不建模 )一起,通过函数 \(f_y\) 引发结果 \(Y\)。最后这个方程里有 \(u_y\),是为了说明结果并非仅由处理干预决定。还有其他一些变量也会对其产生影响,即便我选择不把它们纳入模型。回到销售的例子,这就意味着 \(weekly\_amount\_sold\) (周销量 )是由处理干预 \(is\_on\_sale\)(是否促销 )以及其他未指明的因素(用 \(u\) 表示 )共同导致的。\(u\) 的作用是解释由它引发、但未被模型纳入的变量(也叫内生变量 )的所有变化。在我们的例子中,我可以说降价是由一些模型未涵盖的因素导致的 —— 可能是企业规模,也可能是其他因素:

\(\begin{align*} IsOnSales &\leftarrow f_t(u_t)\\ AmountSold &\leftarrow f_y(IsOnSales, u_y) \end{align*}\)

我用 \(\leftarrow\) 而非 \(=\),是为了明确说明因果关系的不可逆性。用等号的话,\(Y = T + X\)\(T = Y - X\) 是等价的,但我不想说 \(T\) 导致 \(X\)\(Y\) 导致 \(T\) 是等价的。话虽如此,我常常会不用 \(\leftarrow\),只因它有点麻烦。只需记住,由于因果的不可逆性,和传统代数不同,处理因果模型时,你不能随意把等式两边的内容调换位置。

要是你想明确地对更多变量进行建模,你可以把它们从 \(u\) 中提取出来,在模型里对其加以考虑。比如,还记得我之前说过,你看到的降价和不降价之间的巨大差异,可能是因为规模更大的企业能够开展更激进的促销活动吧?在之前的模型中,\(BusinessSize\)(企业规模 )并未被明确纳入模型。相反,它的影响被归到了一边,和 \(u\) 中的其他因素混在一起。但我可以明确地对它进行建模:

\(\begin{align*} BusinessSize &\leftarrow f_s(u_s)\\ IsOnSales &\leftarrow f_t(BusinessSize, u_t)\\ AmountSold &\leftarrow f_y(IsOnSales, BusinessSize, u_y) \end{align*}\)

要纳入这个额外的内生变量,首先,我要添加另一个方程来表示该变量是如何产生的。接下来,我要把\(BusinessSize\)\(u_t\)中移除。也就是说,我不再把它当作模型之外的变量。我明确表明,\(BusinessSize\) 会导致 \(isOnSale\)(连同一些我仍选择不建模的其他外部因素 )。这只是一种将 “规模更大的企业更有可能降价”这一信念进行编码的正式方式。最后,我也可以把 \(BusinessSize\) 添加到最后一个方程中。这就编码了”规模更大的企业也会卖出更多产品”这一信念。换句话说,\(BusinessSize\) 是处理干预 \(isOnSales\) 和结果 \(AmountSold\) 的共同原因

由于这种建模方式对你而言可能很陌生,把它和你或许更熟悉的东西联系起来会很有帮助。要是你学过经济学或统计学,可能习惯用另一种方式对同一问题建模:\(AmountSold_i = \alpha + \beta_1 IsOnSales_i + \beta_2 BusinessSize_i + e_i\)

乍一看,它很不一样,但仔细审视就会发现,前面的模型和你之前看到的模型非常相似。首先,注意到它只是替换了之前模型中的最后一个方程,并且把 \(f_y\) 函数展开,明确说明内生变量 \(IsOnsales\) \(BusinessSize\) 通过线性相加的方式组合起来形成结果\(AmountSold\)。从这个意义上说,这个线性模型比你之前看到的模型假设更多。可以说,它给变量之间的关系强加了一种函数形式。其次,你没有说明自变量(内生变量 )——\(IsOnsales\) \(BusinessSize\)—— 是如何产生的。最后,这个模型用等号而非赋值运算符,但我们之前已经达成共识,不用太在意这一点。

干预

我花时间讲解因果模型的原因在于,一旦你有了一个因果模型,你就可以开始对它进行调整,期望借此回答因果问题。这种操作的正式术语是干预。例如,你可以拿那个非常简单的因果模型,强制让所有分析单位都接受处理干预 \(t_0\)。这会消除 \(T\) 的自然成因,用一个单一常数来替代它们:

\(\begin{align*} T &\leftarrow t_0\\ Y &\leftarrow f_y(T, u_y) \end{align*}\)

这是作为一个思想实验来做的,目的是回答 “如果我把处理干预设为 \(t_0\),结果 \(Y\) 会发生什么变化?”这个问题。你实际上不必真的对处理干预进行干预(不过你可以这么做,而且之后会这么做,但那是后面的事了 )。在因果推断文献中,你可以用 \(do(.)\) 算子来指代这些干预操作。要是你想推理对 \(T\) 进行干预会发生什么,你可以写成 \(do(T = t_0)\)


期望

从现在开始,我会大量用到期望和条件期望。你可以把期望看作平均值试图估计的总体数值。\(E[X]\) 表示随机变量 \(X\) 的边际期望值,它可以用 \(X\) 的样本均值来近似。\(E[Y|X = x]\) 表示当 \(X = x\)\(Y\) 的期望值,它可以用 \(X = x\)\(Y\) 的均值来近似。


\(do(.)\) 算子也让你初步了解到相关性为何有别于因果关系。我此前已论述过,正在促销的商家的高销量,即 \(E[AmountSold|IsOnSales = 1]\),可能会高估商家若实施降价会有的平均销量,也就是 \(E[AmountSold|do(IsOnSales = 1)]\)在第一种情况里,你关注的是那些选择降价的商家,而这些商家很可能是规模较大的商家。相反,后一个量\(E[AmountSold|do(IsOnSales = 1)]\),指的是如果你强制所有商家(而非仅大商家 )开展促销,会出现的结果。关键是,一般而言:

\(E[AmountSold|IsOnSales = 1] \neq E[AmountSold|do(IsOnSales = 1)]\)

理解这两者差异的一种方式是从选择和干预的角度来看。当你以促销为条件时,你测量的是在实际降价的商家这一选定子样本中的销量。当你以干预\(do(IsOnSales)\)为条件时,你是在强制所有商家降价,然后测量整个样本的销量\((见图1-2)\)

\(do(.)\)用于定义那些并非总能从观测数据中得到的因果量。在之前的例子中,你无法观测到对每个商家实施 \(do(IsOnSales = 1)\) 的情况,因为你没强制它们促销。\(do(.)\) 作为一个理论概念最有用,你可以用它明确表述你所追求的因果量。由于它无法直接观测,很多因果推断工作都围绕着将其从理论表达式中消除展开 —— 这个过程叫做识别

个体处理效应

\(do(.)\) 算子还能让你表述个体处理效应,也就是处理干预对个体分析单位 \(i\) 的结果产生的影响。你可以把它写成两种干预情况的差值:\(\tau_i = Y_i|do(T = t_1) - Y_i|do(T = t_0)\)

用文字表述的话,你可以这样理解:“对于分析单位 \(i\),从处理干预 \(t_0\) 变为 \(t_1\) 产生的效应 \(\tau_i\),是该分析单位在 \(t_1\) 处理干预下的结果与在 \(t_0\) 处理干预下的结果的差值”。你可以用这个来推理我们的问题,即弄清楚在 \(AmountSold\) (周销量 )中把 \(isOnSales\) (是否促销 )从 \(0\) 变为 \(1\) 产生的效应:

\(\tau_i = AmountSold_i|do(IsOnSales = 1) - AmountSold_i|do(IsOnSales = 0)\)

由于因果推断的根本问题,你只能观测到上述等式中的一项。所以,即便你能从理论上表述这个量,也不意味着你一定能从数据中得到它。

潜在结果

利用 \(do(.)\) 算子,你还能定义因果推断中最炫酷且应用最广泛的概念 —— 反事实结果或潜在结果\(Y_{ti} = Y_i|do(T_i = t)\)

你可以这样理解:“若分析单位 \(i\) 的处理干预被设定为 \(t\),其结果会是 \(Y\)” 。有时,鉴于下标很快会变得繁杂,我会用函数符号来定义潜在结果:\(Y_{ti} = Y(t)_i\)

当讨论二元处理(处理过或未处理)时,我会把 \(Y_{0i}\) 记作分析单位 \(i\) 未接受处理时的潜在结果,把 \(Y_{1i}\) 记作同一分析单位 \(i\) 接受处理时的潜在结果。我还会把其中一个潜在结果称为实际结果(即我能观测到的),另一个称为反事实结果(即无法观测到的)。比如,如果分析单位 \(i\) 接受了处理,我就能看到它在处理下的情况,也就是能看到 \(Y_{1i}\),我会把这个称为实际潜在结果。相反,我看不到如果分析单位 \(i\) 未接受处理会发生什么情况。也就是说,我看不到 \(Y_{0i}\),因为它是反事实的:

\(Y_i = \begin{cases} Y_{1i} & \text{若分析单位 } i \text{ 接受了处理} \\ Y_{0i} & \text{反之} \end{cases}\)

你可能也会看到同样的内容写成这样:\(Y_i = T_iY_{1i} + (1 - T_i)Y_{0i} = Y_{0i} + (Y_{1i} - Y_{0i})T_i\)

回到我们的例子,你可以用\(AmountSold_{0i}\) 表示商家 \(i\) 未进行任何降价时本会售出的数量,用 \(AmountSold_{1i}\) 表示商家 \(i\) 进行促销时本会售出的数量。你也可以用这些潜在结果来定义效应:\(\tau_i = Y_{1i} - Y_{0i}\)


假设在整本书中,你会发现因果推断总是伴随着假设。假设是你在表达对数据生成方式的看法时所做的陈述。问题在于,这些假设通常无法用数据来验证,这就是为什么你需要假定它们成立。假设并不总是容易识别,所以我会尽力把它们清晰呈现出来。


一致性与稳定单位处理值

在之前的等式中,存在两个隐含假设。第一个假设意味着潜在结果与处理干预是一致的:当 \(T_i = t\)时,\(Y_i(t) = Y\)换句话说,除了用 \(T\) 指明的处理干预版本外,不存在隐藏的其他处理干预版本。如果处理干预有多个剂量水平,但你只考虑了其中两种,这个假设就可能不成立;比如,你关注折扣券对销量的影响,把它当作二元变量(顾客要么收到优惠券,要么没收到 ),但实际上你尝试了多种折扣额度。

当处理干预定义不清晰时,也会出现不一致情况。比如,想象一下,试图弄清楚从财务规划师那里获得帮助对个人财务的影响。这里的”帮助”是什么意思呢?是一次咨询?还是定期的建议和目标追踪?把所有这些不同形式的财务建议归为一个类别,也会违反一致性假设。

第二个隐含的假设是无干扰,或者叫稳定单位处理值假设(\(SUTVA\)) 。也就是说,一个单位的处理干预效应不会受到其他单位处理干预情况的影响:\(Y_i(T_i) = Y_i(T_1, T_2, \ldots, T_i, \ldots, T_n)\)要是存在溢出效应或网络效应,这个假设就可能不成立。比如,你想了解疫苗对预防传染病的效果,给一个人接种疫苗会让她身边的其他人也不太容易染上这种病,即便那些人自己没接种疫苗。违背这个假设通常会让我们觉得效应比实际情况要小。存在溢出效应时,对照组单位会获得一些处理干预效应,这反过来会使处理组和对照组的差异,比没有干扰时要小。


假设违背的处理

幸运的是,对于这两种假设的违背情况,你通常都有办法应对。要解决一致性假设被违背的问题,你得在分析中纳入处理干预的所有版本。要处理溢出效应,你可以扩展处理效应的定义,把来自其他单位的效应包含进来,并且使用更灵活的模型来估计这些效应。


感兴趣的因果量

一旦你了解了潜在结果的概念,就可以重新表述因果推断的根本问题:你永远无法知晓个体处理效应,因为你只能观测到潜在结果中的一个。但事情并非毫无转机。有了这些新概念,你就能在解决这个根本问题上取得一些进展。尽管你永远无法知晓个体效应 \(\tau_i\),但还有其他有趣的因果量可以从数据中获知。例如,我们把平均处理效应\((ATE)\)定义如下:\(ATE = E[\tau_i]\) 或者 \(ATE = E[Y_{1i} - Y_{0i}]\) 甚至\(ATE = E[Y|do(T = 1)] - E[Y|do(T = 0)]\)

平均处理效应代表处理干预 \(T\) 平均会产生的影响。有些单位受其影响会大些,有些会小些,而你永远无法知晓对单个单位的个体影响。此外,要是你想从数据中估计平均处理效应,你可以用样本均值替代期望:\(\frac{1}{N} \sum_{i = 0}^{N} \tau_i\) 或者 \(\frac{1}{N} \sum_{i = 0}^{N} (Y_{1i} - Y_{0i})\)

当然,实际上,由于因果推断的根本问题,你没法真的这么做,因为对于每个单位,你只能观测到潜在结果中的一个。目前,别太担心该如何去估计这个量。你很快就会学到。只需专注于理解如何用潜在结果来定义这个因果量,以及为何想要估计它。

另一个受关注的组效应是已处理单位的平均处理效应\((ATT)\)\(ATT = E[Y_{1i} - Y_{0i}|T = 1]\)

这是处理干预对接受了处理干预的单位产生的影响。比如,你在一个城市开展线下营销活动,想知道这次活动在该城市为你带来了多少额外客户,这就是\(ATT\):营销活动对开展该活动的城市产生的效应。在此,要注意到两个潜在结果都是针对同一处理干预定义的。就 \(ATT\) 而言,由于你以已处理的单位为条件,\(Y_{0i}\) 始终无法观测,但依然是定义良好的。

最后,还有条件平均处理效应\((CATE)\)\(CATE = E[Y_{1i} - Y_{0i}|X = x]\)

它是由变量 \(X\) 定义的组内的效应。比如,你可能想了解一封邮件对 \(45\) 岁以上客户和 \(45\) 岁以下客户的影响。条件平均处理效应对于个性化而言极为宝贵,因为它能让你知晓哪种类型的单位对干预的响应更好。

当处理干预是连续变量时,你也可以定义上述这些量。在这种情况下,你用偏导数替代差值:\(\frac{\partial}{\partial t} E[Y_i]\)

这看似复杂,实则只是一种表述方式,用于说明当处理干预有一个小的增加量时,你预期 \(E[Y_i]\) 会有多大变化。

因果量:示例

来看看在我们的商业问题中如何定义这些量。首先要注意,你永远无法知晓降价(开展促销)对单个商家的效应,因为这需要你同时看到两个潜在结果,即 \(AmountSold_{0i}\)\(AmountSold_{1i}\) 。但你可以转而关注一些可估计的内容,比如降价对销量的平均影响:\(ATE = E[AmountSold_{1i} - AmountSold_{0i}]\)

开展降价的商家的销量增长情况:\(ATT = E[AmountSold_{1i} - AmountSold_{0i}|IsOnSales = 1]\)

或者在圣诞节当周开展促销的影响:\(CATE = E[AmountSold_{1i} - AmountSold_{0i}|weeksToXmas = 0]\)

我知道你无法同时看到两个潜在结果,但为了论证,也为了让事情更直观,咱们假设你可以。暂且想象因果推断之神对你在诸多统计战役中的表现很满意,赐予你如神般的能力,让你能看到潜在的平行宇宙,在每个宇宙中,不同的结果都会成为现实。有了这种能力,假设你收集了 \(6\) 家商家的数据,其中 \(3\) 家在开展促销,\(3\)家没开展。

在下面的表格中,\(i\) 是单位标识符,\(y\) 是观测到的结果,\(y_0\)\(y_1\) 分别是控制组(未处理)和处理组(已处理)下的潜在结果,\(t\) 是处理干预指示变量,\(x\) 是标记距离圣诞节剩余时间的协变量。要记住,开展促销是处理干预,销量是结果。咱们再假设,对于其中 \(2\) 家商家,你收集的数据是在圣诞节前一周(记为 \(x = 1\) ),而其他观测数据来自圣诞节当周。

pd.DataFrame(dict(
    i= [1,2,3,4,5,6],              # individual id
    y0=[200,120,300, 450,600,600], # potential outcome if treatment is not received
    y1=[220,140,400, 500,600,800], # potential outcome if treatment is received
    t= [0,0,0,1,1,1],              # treatment indicator
    x= [0,0,1,0,0,1],              # confounder
)).assign(
    y = lambda d: (d["t"]*d["y1"] + (1-d["t"])*d["y0"]).astype(int),    # observed outcome
    te=lambda d: d["y1"] - d["y0"]                                      # treatment effect
)
##    i   y0   y1  t  x    y   te
## 0  1  200  220  0  0  200   20
## 1  2  120  140  0  0  120   20
## 2  3  300  400  0  1  300  100
## 3  4  450  500  1  0  500   50
## 4  5  600  600  1  0  600    0
## 5  6  600  800  1  1  800  200

借助如神般的能力,你可以看到\(AmountSold_0\)\(AmountSold_1\) 。这使得计算我们之前讨论过的所有因果量变得极其容易。例如,这里的平均处理效应会是最后一列(即处理效应列)的均值:\(ATE = (20 + 20 + 100 + 50 + 0 + 200)/6 = 65\)

这意味着,促销平均使销量增加了 \(65\) 个单位。

至于已处理单位的\(ATT\),它就是当 \(T = 1\)时最后一列的均值:\(ATT = (50 + 0 + 200)/3 = 83.33\)

换句话说,对于选择降价(即接受处理)的商家,降价平均使销量增加了 \(83.33\) 个单位。

最后,以距离圣诞节前一周(\(x = 1\) )为条件的平均效应,就是单位 \(3\) 和单位 \(6\) 的效应的平均值:\(CATE(x = 1) = (100 + 200)/2 = 150\)

而圣诞节当周的平均效应,是当\(x = 0\)时的平均处理效应:\(CATE(x = 0) = (20 + 20 + 50 + 0)/4 = 22.5\)

这意味着,商家在圣诞节前一周开展降价(增加 \(150\) 个单位销量 )比在圣诞节当周开展降价(增加 \(22.5\) 个单位销量 )受益多得多。因此,较早降价的商店比较晚降价的商店从中获益更多。

既然你对通常感兴趣的因果量\((ATE、ATT和CATE)\)有了更清晰的理解,是时候离开梦幻岛,回到现实世界了。在现实中,情况很残酷,你实际拥有的数据处理起来要难得多。在这里,你只能看到一个潜在结果,而个体处理效应就隐藏其中:

pd.DataFrame(dict(
    i= [1,2,3,4,5,6],
    y0=[200,120,300, np.nan, np.nan, np.nan,],  # control group
    y1=[np.nan, np.nan, np.nan, 500,600,800],   # treatment group
    t= [0,0,0,1,1,1],
    x= [0,0,1,0,0,1],
)).assign(
    y = lambda d: np.where(d["t"]==1, d["y1"], d["y0"]).astype(int),
    te= lambda d: d["y1"] - d["y0"]
)
##    i     y0     y1  t  x    y  te
## 0  1  200.0    NaN  0  0  200 NaN
## 1  2  120.0    NaN  0  0  120 NaN
## 2  3  300.0    NaN  0  1  300 NaN
## 3  4    NaN  500.0  1  0  500 NaN
## 4  5    NaN  600.0  1  0  600 NaN
## 5  6    NaN  800.0  1  1  800 NaN


缺失数据问题

可以把因果推断看作一个缺失数据问题。要推断出感兴趣的因果量,你必须对缺失的潜在结果进行填补。


你或许会看着这个情况思索:这肯定不理想,但我就不能取处理组的均值,再和未处理组的均值比较吗?换句话说,我就不能这样算:\(ATE = (500 + 600 + 800)/3 - (200 + 120 + 300)/3 = 426.67\)

不行!你刚刚犯下了把相关性错当因果关系的最严重错误!

注意看结果差别多大。你之前算出的 \(ATE\) 还不到 \(100\),现在却算出 \(400\) 多。问题在于,开展促销的商家和没开展的商家本就不同。实际上,开展促销的商家,即便不降价,可能销量也会更多。要明白这一点,回到能看到两个潜在结果的时候。那时,处理组单位的 \(Y_0\) 比未处理组单位的 \(Y_0\) 要高得多。处理组和未处理组在 \(Y_0\) 上的这种差异,使得仅通过比较两组来揭示处理效应变得困难重重。

虽说比较均值不是什么高明的主意,但我觉得你的直觉是对的。是时候运用你刚学的新概念来完善这个直觉,最终明白为何相关性不等于因果关系了。是时候直面因果推断的主要敌人了。

偏差

直截了当地说,偏差正是导致相关性不同于因果关系的原因。你从数据中估计出的结果,与你想要还原的因果量不匹配,这就是核心问题。幸运的是,凭借一些直觉就能轻松理解这点。咱们回顾一下之前的商业案例。当有人宣称降价能增加商家销量时,你可以提出质疑,指出那些开展促销的商家,即便不降价,可能本来也会卖出更多商品。或许这是因为它们规模更大,有能力开展更激进的促销活动。换句话说,接受处理开展促销的商家,和未接受处理未开展促销的商家,并不具备可比性

为了进行更严谨的论证,你可以用潜在结果的符号体系来阐释这种直觉。首先,要估计 \(ATE\),你需要估计接受处理的群体若未接受处理会出现的情况,即 \(E[Y_0|T = 1]\),以及未接受处理的群体若接受处理会出现的情况,即 \(E[Y_1|T = 0]\) 。当你对比接受处理群体和未接受处理群体的平均结果时,本质上是用 \(E[Y|T = 0]\) 去估计 \(E[Y_0]\),用 \(E[Y|T = 1]\) 去估计 \(E[Y_1]\) 。换句话说,你在估计\(E[Y|T = t]\),期望借此还原出\(E[Y_t]\) 。要是两者不匹配,像利用接受处理 \(t\) 的群体的平均结果来还原 \(E[Y|T = t]\) 这样的估计量,就会成为\(E[Y_t]\) 的有偏估计量 。


技术定义

如果一个估计量与它试图估计的参数存在差异,那么可以说这个估计量是有偏的。偏差的计算公式为 \(Bias = E[\hat{\beta} - \beta]\) ,其中 \(\hat{\beta}\) 是估计值,\(\beta\) 是它试图估计的对象,也就是被估量。例如,若一个用于估计\(ATE\)的估计量,系统性地低估或高估了真实的\(ATE\),那么这个估计量就是有偏的。


偏差方程

既然你已经明白样本均值为何可能与其试图估计的平均潜在结果存在差异,接下来咱们更深入探究一下,为何均值差异通常无法还原出\(ATE\)。这部分内容可能有点技术化,要是你不喜欢数学公式,完全可以跳过,直接看下一部分。

在销售的例子中,处理促销和结果销量之间的相关性,是通过 \(E[Y|T = 1] - E[Y|T = 0]\) 来度量的。这表示开展促销的商家的平均销量,减去未开展促销的商家的平均销量。而另一方面,因果关系是通过 \(E[Y_1 - Y_0]\)(它是 \(E[Y|do(t = 1)] - E[Y|do(t = 0)]\) 的简写形式 )来度量的。

为理解它们为何不同以及差异是怎样产生的,咱们用潜在结果替换相关性度量 \(E[Y|T = 1] - E[Y|T = 0]\) 里的观测结果。对于接受处理的群体,观测结果是 \(Y_1\);对于未接受处理的群体,观测结果是 \(Y_0\)

\(E[Y|T = 1] - E[Y|T = 0] = E[Y_1|T = 1] - E[Y_0|T = 0]\)

现在,咱们加上并减去 \(E[Y_0|T = 1]\),这是一个反事实结果,它能告诉我们接受处理的群体若未接受处理,其结果会怎样 :

\(E[Y|T = 1] - E[Y|T = 0] = E[Y_1|T = 1] - E[Y_0|T = 0] + E[Y_0|T = 1] - E[Y_0|T = 1]\)

最后,你可以重新排列这些项,并合并一些期望:\(\begin{align*} E[Y|T = 1] - E[Y|T = 0]&= E[Y_1 - Y_0|T = 1] + \{E[Y_0|T = 1] - E[Y_0|T = 0]\}\\ & \quad\quad\ ATT \quad\quad\quad\quad\quad\quad\quad\quad\ BIAS \end{align*}\)

这段简单的数学推导涵盖了你在因果问题中会遇到的所有难题。为了更好地理解它,咱们来剖析一下它的一些含义。首先,这个等式向我们阐释了为何相关性并非因果关系。正如你所见,相关性等于对已处理群体的处理效应加上一个偏差项。偏差由处理组和对照组在不考虑处理的情况下存在的差异决定,具体体现为 \(Y_0\) 的差异。

现在,你就能解释为何当有人声称降价能大幅提升销量时,你会心存疑虑。在这个销售案例中,你认为 \(E[Y_0|T = 0] < E[Y_0|T = 1]\),这意味着那些有能力开展降价的商家,不管是否真的进行促销,往往本身销量就更高 。

为什么会出现这种情况呢?这是第 \(3\) 章要探讨的内容,届时你会研究混杂因素。眼下,你可以认为偏差的产生是因为许多你无法观测到的因素会和处理促销一起发生变化。结果就是,开展促销和未开展促销的商家,除了是否进行促销这一点,在其他方面也存在差异。它们在规模、位置、选择开展促销的时间、管理风格、所在城市以及诸多其他因素上都有不同。要确定降价能在多大程度上提升销量,你需要开展促销和未开展促销的商家,平均而言,彼此较为相似。换句话说,处理组和对照组的个体必须是可交换的


实际案例

每日一杯葡萄酒,医生远离我

一种广为流传的观点认为,适度饮用葡萄酒对健康有益。其论据是,像意大利和西班牙这样的地中海文化,因每日饮用一杯葡萄酒而闻名,且人均寿命也很长。你应当对这一主张持怀疑态度。要把人均寿命的延长归因于葡萄酒,饮酒者和不饮酒者需要具备可交换性,但我们知道事实并非如此。例如,意大利和西班牙都拥有完善的医疗保障体系,且人类发展指数相对较高。

用专业术语来讲,\(E[Lifespan_0|WineDrinking = 1] > E[Lifespan_0|WineDrinking = 0]\)

所以,偏差可能会掩盖真正的因果效应。


偏差的可视化指南

谈及可交换性,你不必只依靠数学和直觉。在我们的例子中,你甚至可以通过绘制开展促销和未开展促销的商家在各变量下与结果的关系图,来验证它们是否具备可交换性。要是你以 平均周销售额\((avg\_week\_sales)\)衡量企业规模,绘制 周销售额\((weekly\_amount\_sold)\)企业规模\((avg\_week\_sales)\)的关系图,再用处理标识(是否促销 \(is\_on\_sale\))为每个绘图上色,你会发现,接受处理的商家在图中更集中于右侧,这意味着它们通常是规模更大的企业。也就是说,处理组和未处理组并不平衡。

# 设置整个图表的默认字体大小为 10 号,让文字(如坐标轴标签、图例)统一且清晰,避免不同元素字体大小混乱。
plt.rc('font', size=10)
# 创建一个空的图表对象(容器),后续所有绘图操作(如绘制散点、直线)都会在这个容器中进行
fig = plt.figure()    

# aspect=2:图表宽高比为 2:1(宽度是高度的 2 倍),让图表更舒展
sns.lmplot(data=data, ci=None, x="avg_week_sales", y="weekly_amount_sold", scatter=False, height=4, aspect=2)


# alpha=.8:散点透明度(0-1 之间,0.8 表示轻微透明,避免重叠散点完全遮挡)
# label="on sale":图例名称(后续图例中显示 “on sale”,表示促销数据)
plt.scatter(x=data.query("is_on_sale==1")["avg_week_sales"],y=data.query("is_on_sale==1")["weekly_amount_sold"],label="on sale",
            color=color[0], alpha=.8, marker=marker[0])
            
plt.scatter(x=data.query("is_on_sale==0")["avg_week_sales"],y=data.query("is_on_sale==0")["weekly_amount_sold"],label="not on sale",
            color=color[2], alpha=.6, marker=marker[1])
            
# fontsize="10":图例文字大小为 10 号,与全局字体大小一致            
plt.legend(fontsize="10")

这是非常有力的证据:表明你的假设 \(E[Y_0|T = 1] > E[Y_0|T = 0]\) 是正确的。存在一种向上的偏差,因为实施降价的商家数量 \(T = 1\),以及它们若未进行任何促销活动时的结果\(Y_0\),都会随着企业规模的扩大而增加。

如果你听说过辛普森悖论,这种偏差就像是它的一个没那么极端的版本。在辛普森悖论中,两个变量之间最初的关系是正相关的,但一旦你对第三个变量进行调整,关系就会变成负相关。在我们的案例里,偏差还没极端到翻转相关性的符号(见\(图1-3\))。在这里,一开始降价和销量之间的相关性过高,而控制第三个变量企业规模会减小这种相关性的程度。如果你聚焦于相同规模的企业内部,降价和销量之间的相关性会降低,但仍为正相关

我觉得这一点至关重要,所以值得再次深入探讨,这次我们结合一些图像来说明。这些图像虽不写实,但能很好地阐释偏差问题。假设你有一个表示企业规模的变量。要是你绘制销量与企业规模的关系图,会看到一种上升趋势,即企业规模越大,销量越多。接下来,你根据是否进行处理(降价促销)给这些点上色:白色点代表实施降价的企业,黑色点代表未实施降价的企业。要是你简单对比实施降价和未实施降价的企业的平均销量,会得到如下结果:

注意观察,两组企业在销量上的差异可能(而且很可能确实)有两个成因:

  1. 处理效应:销量的增长是由降价这一处理手段导致的。

  2. 企业规模:规模更大的企业既能卖出更多产品,也更有能力开展降价活动。处理组和未处理组之间的这种差异,并非由降价导致。

因果推断面临的挑战,就在于梳理清楚这两种成因 。

将此与在图中加入两种潜在结果(反事实结果用三角形表示 )后你会看到的情况对比一下。个体处理效应是某个单元接受处理后的结果与该单元若接受另一种处理会产生的理论结果之间的差异。你想要估计的平均处理效应,是每个个体单元潜在结果的平均差异,即\(Y_1 - Y_0\) 。这些个体差异,比你在前一幅图中看到的处理组和未处理组之间的差异要小得多。出现这种情况的原因是偏差,右侧的图描绘了偏差的情况:

你可以通过设定所有人都不接受处理来呈现偏差。在这种情况下,就只剩下 \(Y_0\) 潜在结果了。然后,你就能看到在未接受处理时,处理组和未处理组在这些潜在结果上的差异情况。要是存在差异,那就说明是处理之外的其他因素,导致了处理组和未处理组之间的不同。这正是我一直在说的偏差,它会掩盖真正的处理效应。

识别处理效应

既然你已经理解了问题所在,现在就该看看解决方案或者说至少是其中一种方案了。识别是任何因果推断分析的第一步。你会在第 \(3\) 章中更深入地探讨它,但就目前而言,了解它是什么是有价值的。

要记住,你无法观测到因果量,因为只有一种潜在结果是可观测的。你无法直接估计像 \(E[Y_1 - Y_0]\) 这样的量,因为对于任何数据点,你都无法观测到这种差异。但或许你能找到其他可观测的量,并用它来还原你关心的因果量。这就是识别的过程:弄清楚如何从可观测数据中还原因果量。例如,要是奇迹般地,\(E[Y|T = t]\) 能够还原出\(E[Y_t]\),那么你只需估计\(E[Y|T = 1] - E[Y|T = 0]\),就能得到\(E[Y_1 - Y_0]\)。这可以通过估计处理组和未处理组的平均结果来实现,而这两个平均结果都是可观测的量。


另见

在过去的十年\((2010-2020年)\)里,\(Judea \space Pearl\) 和他的团队普及了关于因果识别的整个知识体系,以此来统一因果推理语言。 我在本章中使用了一些这种语言——虽然可能是一种异端的版本——我将在 \(3\) 中更多地介绍它。 如果您想了解更多相关信息,一篇简短但非常酷的论文值得一看,名为《\(Causal \space Inference \space and \space Data \space Fusion \space in \space Econometrics\)》,作者是 \(Paul \space Hunermund\)\(Elias \space Bareinboim\)


你也可以把识别看作是消除偏差的过程。借助潜在结果,你也可以说明要让相关性等同于因果关系需要哪些条件。如果 \(E[Y_0|T = 0] = E[Y_0|T = 1]\),那么, 相关性就是因果关系!理解这一点不只是记住这个等式。这里有很强的直观依据。说 \(E[Y_0|T = 0] = E[Y_0|T = 1]\),意思是处理组和对照组不管是否接受处理,都是可比的。从数学层面讲,偏差项会消失,只剩下对处理组的效应:\(E[Y|T = 1] - E[Y|T = 0] = E[Y_1 - Y_0|T = 1] = ATT\)

此外,如果处理组和未处理组对处理的反应相似,即\(E[Y_1 - Y_0|T = 1] = E[Y_1 - Y_0|T = 0]\),那么均值差异就成为\(ATE\)\(E[Y|T = 1] - E[Y|T = 0] = ATT = ATE = E[Y_1 - Y_0]\)

尽管这里数学看起来花里胡哨,但它的意思很简单:一旦你让处理组和对照组具备可交换性,用数据中可观测的量来表述因果效应就变得轻而易举了。把这个原理应用到我们的例子中,如果实施降价和未实施降价的商家彼此相似(也就是具备可交换性)。那么,开展促销的商家和未开展促销的商家在销量上的差异,就可以完全归因于降价这一行为 。

独立性假设

这种可交换性是因果推断中的关键假设。由于它极为重要,不同的科学家找到了不同的表述方式。我将从一种可能最常见的方式开始,也就是独立性假设。在此,我会说潜在结果与处理相互独立:\((Y_0, Y_1) \perp T\)

这种独立性意味着 \(E[Y_0|T] = E[Y_0]\),或者说,处理不会为你提供关于潜在结果的任何信息。某个单元接受了处理这一事实,并不意味着若它未接受处理 \(Y_0\),其结果会更低或更高。这只是 \(E[Y_0|T = 1] = E[Y_0|T = 0]\) 的另一种表述方式。

在我们的商业案例中,它简单来说就是:要是所有商家都未开展促销,你无法区分那些原本选择开展促销的商家和未开展促销的商家。除了处理促销及其对结果的影响外,它们彼此之间是相似的。同理,\(E[Y_1|T] = E[Y_1]\)意味着,要是所有商家都开展了促销,你同样无法区分它们。简而言之,这意味着无论所有商家是否都接受了处理,处理组和未处理组都是可比且难以区分的。

借助随机化进行识别

在此,你把独立性当作一种假设。也就是说,你明白需要让相关性等同于因果关系,但还没学会如何让这一条件成立。回想一下,因果推断问题通常可拆解为两个步骤:

  1. 识别:弄清楚如何用可观测数据来表述你感兴趣的因果量。

  2. 估计:实际运用数据,对之前识别出的因果量进行估计。

为了用一个非常简单的示例阐释这个过程,假设你可以对处理促销进行随机化。我知道我之前说过,在你工作的在线市场中,商家在定价方面有完全的自主权,但你仍然可以找到一种方法来随机化 “是否促销\((isOnSales)\)” 这一处理。比如,假设你与商家协商,获得强制它们降价的权利,而市场会支付你强制降价产生的差价。好的,那么假设你现在有了一种随机开展促销的方法,那又怎样呢?实际上,这是件大事!

首先,随机化将处理分配与抛硬币等随机事件挂钩,这样处理分配的变化就与因果机制中的任何其他因素完全无关

\(\begin{align*} IsOnSales &\leftarrow rand(t)\\ AmountSold &\leftarrow f_y(IsOnSales, u_y) \end{align*}\)

在随机化的情况下,\(u_t\) 从我们的模型中消失了,因为处理的分配机制变得完全可知。此外,由于处理是随机的,它变得与任何事物都相互独立,包括潜在结果。随机化几乎可以强制让独立性成立。

为了把这一点讲得极其清楚,咱们看看随机化是如何在处理分配之前就几乎消除偏差的。第\(1\)幅图呈现的是尚未实现的潜在结果(三角形)所处的情况。左侧的图描绘了这种情形:

然后,通过随机化,处理会使其中一种潜在结果成为现实 。


随机化研究与观察性研究

在因果推断中,我们用随机化\((randomized)\) 一词描述以下两种数据情况:一是处理干预是经随机化分配的;二是处理分配机制是完全可知且非确定性的。与之相对,观察性\((observational)\) 一词用于描述这样的数据:你能看到哪些对象接受了何种处理,但不清楚处理是如何被分配的 。


接下来,咱们去掉繁杂的部分,把未实现的潜在结果(三角形)移除。现在你就可以对处理组和未处理组进行对比了:

在这种情况下,处理组和未处理组在结果上的差异就是\(ATE\)这是因为,除了处理本身之外,它们之间不存在其他导致差异的来源。因此,你看到的所有差异都必须归因于处理。或者简单地说,不存在偏差。要是你让所有人都不接受处理,这样你就只能观测到 \(Y_0\),你会发现处理组和未处理组之间没有差异:

这就是因果识别这项艰巨任务的核心所在。它关乎找到巧妙的方法来消除偏差,让处理组和未处理组具备可比性,这样你看到的所有差异都能归因于处理效应。重要的是,只有当你了解或愿意假设有关数据生成过程的某些信息时,识别才有可能实现。通常是了解处理是如何分配的。这就是为什么我之前说仅靠数据无法回答因果问题。当然,数据对于估计因果效应很重要。但除了数据,你始终需要一份关于数据具体来说是处理是如何产生的说明。你可以利用专业知识,或者通过干预现实世界、影响处理并观察结果如何响应变化来获得这份说明


一项出色的会员计划

一家大型在线零售商推出了一个会员计划,会员支付额外费用,就能享受更多折扣、更快配送、免退货费以及优质客户服务。为了解该计划的影响,公司向随机抽取的客户群体推出了这个计划,这些客户可以选择支付费用以获得会员福利。一段时间后,公司发现,参与会员计划的客户比对照组的客户盈利能力高得多。客户不仅从公司购买商品,而且花费在客户服务上的时间也更少。那么,我们是否可以说这个会员计划在增加销售额和减少客户服务耗时方面取得了巨大成功呢?

其实并非如此。虽然参与该计划的资格是随机分配的,但有资格选择加入的这部分客户群体,仍是自行选择是否加入该计划的。换句话说,计划参与资格的随机化,确保了有资格加入计划的人与没资格的人是可比的。但在有资格的人群中,只有一部分人选择参与。这种选择并非随机。很可能只有参与度更高的客户会选择加入,而随意型的客户则会放弃。所以,尽管参与计划的资格是随机分配的,但实际参与计划的情况并非如此。结果就是,参与计划的客户和未参与的客户并不具备可比性。

仔细想想,在有资格参与的客户中,那些实际选择参与的客户,很可能正是因为他们已经在这家在线公司花费了很多,所以才觉得额外折扣值得花钱购买,进而选择加入该计划。这就意味着:\(E[Revenues_0|OptIn = 1] > E[Revenues_0|OptIn = 0]\)

也就是说,那些选择加入的客户,即便不考虑这个会员计划,可能也会产生更多的收入 。


归根结底,因果推断关乎弄清楚世界的运行方式,摒弃所有错觉与误读。既然你已明白这一点,便可继续前行,去掌握一些最强有力的消除偏差的方法——这些方法是勇敢且追求真理之人的工具,用以识别因果效应 。

核心思想

你已经学习了本书后续讨论因果推断时会用到的数学语言。重要的是你已了解潜在结果的定义:对于一个单元,若它接受特定处理 \(T = t\),你会观测到的结果,即:\(Y_{ti} = Y_i \vert do(T_i = t)\)

潜在结果在理解 “相关性为何不等同于因果关系” 方面非常有用。具体而言,当处理组和未处理组因处理之外的原因存在差异,即 \(E[Y_0 \vert T = 1] \neq E[Y_0 \vert T = 0]\)时,两组间的比较不会得出真实的因果效应,而是有偏差的估计。我们也用潜在结果说明了”让相关性等同于因果关系”需要满足的条件:\((Y_0, Y_1) \perp T\)

当处理组和对照组具备可交换性或可比性(比如通过随机化分配处理时),对处理组和未处理组的结果进行简单比较,就能得到处理效应:\(E[Y_1 - Y_0] = E[Y \vert T = 1] - E[Y \vert T = 0]\)

你也开始理解进行因果推断时需要做出的一些关键假设。例如,为了在估计处理效应时不产生偏差,你假设了处理分配与潜在结果之间相互独立,即\(T \perp Y_t\)

你还假设了一个单元的处理不会影响另一个单元的结果(稳定单元处理值假设,\(SUTVA\)),并且在将结果 \(Y\) 定义为潜在结果之间的切换函数时,考虑到了处理的所有版本(若\(Y_i(t) = Y\),则\(T_i = t\) ),该切换函数为:\(Y_i = (1 - T_i)Y_{0i} + T_iY_{1i}\)

总体而言,始终牢记因果推断总是需要假设,这一点很重要。你需要通过假设,才能从你希望了解的因果量,推导到能够为你还原该因果量的统计估计量。