【因果推断python】21_匹配2

2024-06-07 08:36
文章标签 python 21 匹配 推断 因果

本文主要是介绍【因果推断python】21_匹配2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

匹配估计器


匹配估计器

子分类估计器在实践中用得不多(我们很快就会明白为什么,主要是因为维度诅咒这个原因),但它让我们很好地、直观地了解了因果推理估计器应该做什么,以及它应该如何控制混淆因素。这使我们能够探索其他类型的估计器,例如匹配估计器。

这个想法非常相似。由于某种混淆因素 X 使得经过干预的和未干预的样本单元最初无法比较,我可以通过将每个经过干预的单元与类似的未经干预的单元匹配来做到这一点。这就像我为每个干预单元找到一个未经干预的双胞胎。通过进行这样的比较,干预过的和未经干预的样本再次变得可比较。

举个例子,假设我们试图估计一个练习生训练计划对收入的影响。这是练习生的基本情况:

trainee = pd.read_csv("./data/trainees.csv")
trainee.query("trainees==1")

下面是非练习生的基本情况:

如果我对均值做一个简单比较,我们会发现那些练习生相比非练习生赚的更少。

但是,如果我们看一下上面的表格,我们会注意到练习生比非练习生年轻得多,这表明年龄可能是一个混淆因素。让我们使用年龄匹配来尝试纠正这一点。我们将从接受干预的人那里取出1号单元,并将其与27号单元配对,因为两者都是28岁。对于单元2,我们将它与单元34配对,而单元3则与单元37配对,对于单元4我们将它与单元35配对...当涉及到5号单元时,我们需要从未接受干预的人中找到29岁的人,但那是37号单元,它已经配对了。这其实不是问题,因为我们可以多次使用相同的单元。如果可以匹配的单位超过1个,我们可以在它们之间随机选择。

这是前 7 个单元在匹配后的数据集中的样子:

# make dataset where no one has the same age
unique_on_age = (trainee.query("trainees==0").drop_duplicates("age"))matches = (trainee.query("trainees==1").merge(unique_on_age, on="age", how="left", suffixes=("_t_1", "_t_0")).assign(t1_minuts_t0 = lambda d: d["earnings_t_1"] - d["earnings_t_0"]))matches.head(7)

请注意,最后一列的收益差额为已干预单元和与其匹配的未干预单位之间的差异。如果我们取最后一列的平均值,我们得到控制年龄情况下的ATET估计值。请注意,与之前我们使用简单均值差值的估计值相比,该估计值现在显著为正。

matches["t1_minuts_t0"].mean()

2457.8947368421054

这是一个人为设置的例子,只是为了引入匹配这个概念。实际上,我们通常有多个特征,并且单元间也是不能完全可以匹配。在这种情况下,我们必须定义一些接近度的测量值,以比较单元之间的接近程度。一个常见的指标是欧几里得范数 ||X_i-X_j||。 但是,这种差异在特征的大小变化时并不是保持不变。这意味着,与收入等量纲更大的特征相比,在计算此范数时,类似年纪这种以十分之一为单位的特征的重要性要小得多。因此,在应用范数之前,我们需要缩放特征的值,使它们具有大致相同的比例。

定义了距离的测度指标后,我们现在可以将匹配定义为寻找要匹配的样本的最近邻居。在数学方面,我们可以通过以下方式编写匹配估计器:

\hat{ATE}=\frac1N\sum_{i=0}^N(2T_i-1)\big(Y_i-Y_{jm}(i)\big)

其中 Y_{jm}(i)是来自与 Y_{i} 最相似的另一个干预组的样本。我们这样做2T_{i}-1次,并以两种方式匹配:从干预组匹配对照组样本,以及从对照组匹配干预样本。

为了测试这个估计器,让我们考虑一个医学示例。跟上次一样,我们想找到药物对病人恢复时间长短的效果。不幸的是,这种影响被疾病的严重程度、性别以及年龄所混淆。我们有理由相信,病情更严重的患者接受药物治疗的机会更高。

med = pd.read_csv("./data/medicine_impact_recovery.csv")
med.head()

如果我们看一个简单的均值差,E[Y|T=1]-E[Y|T=0],我们得到受到治疗的病人平均需要比未接受治疗的病人多16.9天才能恢复。这可能是由于混淆,因为我们不认为药物会对患者造成伤害。

med.query("medication==1")["recovery"].mean() - med.query("medication==0")["recovery"].mean()

16.895799546498726

为了纠正这个偏差,我们需要使用匹配来控制X。首先,我们一定要记得缩放我们的特征,否则,类似年龄这样的特征在我们计算两个样本点间距离的时候,会比严重性这种特征有更高的重要性。我们可以通过对特征进行归一化的方式来解决这个问题。

# scale features
X = ["severity", "age", "sex"]
y = "recovery"med = med.assign(**{f: (med[f] - med[f].mean())/med[f].std() for f in X})
med.head()

现在,到匹配本身。我们将使用来自 Sklearn 的 K 最近邻算法,而不是编写匹配函数。此算法通过在估计或训练集中查找最近的数据点来进行预测。

为了匹配,我们需要其中的2个函数。一个是; mt0 ,它将存储未干预的样本,并在被要求时在未处理的点中找到匹配项。另一个,mt1,将存储被干预的样本,并在需要时在被干预的样本点中找到匹配项。在此拟合步骤之后,我们可以使用这些 KNN 模型进行预测,从而是我们的匹配样本。

from sklearn.neighbors import KNeighborsRegressortreated = med.query("medication==1")
untreated = med.query("medication==0")mt0 = KNeighborsRegressor(n_neighbors=1).fit(untreated[X], untreated[y])
mt1 = KNeighborsRegressor(n_neighbors=1).fit(treated[X], treated[y])predicted = pd.concat([# find matches for the treated looking at the untreated knn modeltreated.assign(match=mt0.predict(treated[X])),# find matches for the untreated looking at the treated knn modeluntreated.assign(match=mt1.predict(untreated[X]))
])predicted.head()

匹配完成后,我们就可以应用匹配估计器的公式了:\hat{ATE}=\frac1N\sum_{i=0}^N(2T_i-1)\big(Y_i-Y_{jm}(i)\big)

np.mean((2*predicted["medication"] - 1)*(predicted["recovery"] - predicted["match"]))

-0.9954

使用这种匹配,我们可以看到药物的效果不再是增加恢复所需时间。这意味着,控制X后,药物平均将恢复时间减少约1天。这已经是一个巨大的改进,毕竟之前的有偏估计可是预测恢复时间需要增加16.9天。

但是,我们仍然可以做得更好。

这篇关于【因果推断python】21_匹配2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038671

相关文章

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

Python打包成exe常用的四种方法小结

《Python打包成exe常用的四种方法小结》本文主要介绍了Python打包成exe常用的四种方法,包括PyInstaller、cx_Freeze、Py2exe、Nuitka,文中通过示例代码介绍的非... 目录一.PyInstaller11.安装:2. PyInstaller常用参数下面是pyinstal

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数