【因果推断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 KNeighborsRegressor

treated = 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 model
    treated.assign(match=mt0.predict(treated[X])),
    
    # find matches for the untreated looking at the treated knn model
    untreated.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天。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/686131.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何减少Apache Spark日志的数量

修改log4j配置文件,没有就创建: 内容: # 设置日志记录器 log4j.rootCategoryWARN, console log4j.appender.consoleorg.apache.log4j.ConsoleAppender log4j.appender.console.targetSystem.err log4j.appender.console.layoutorg.apache.lo…

什么是IDE?– 集成开发环境

IDE (集成开发环境)是将常用的开发人员工具组合到紧凑的 GUI(图形用户界面)应用程序中的软件。它是代码编辑器、代码编译器和代码调试器等工具与集成终端的组合。 为什么 IDE 很重要? 人们当然不需要 IDE来编码或开发…

cnPuTTY 0.81.0.1-JK—PuTTY 0.81中文JK补丁版的简单说明~~

原始补丁网站的链接:PuTTY for win32 storing configuration into file2. 6. 2024 - Update: this modified PuTTY is now based on PuTTY 0.81 (version 0.23.0) 本次官方正式发布的补丁与上一版本的补丁相同,无明显变化。关于JK补丁的信息也可以参考&…

企业微信hook接口协议,ipad协议http,内部联系人备注修改

内部联系人备注修改 参数名必选类型说明uuid是String每个实例的唯一标识,根据uuid操作具体企业微信 请求示例 {"uuid":"1688855749266556","vid":1688856554448765,"remark":"备注啦啦啦22222","des&quo…

每天五分钟深度学习:逻辑回归算法的单样本的梯度下降计算

本文重点 上节课我们已经知道了如何利用计算图通过链式法则来求解输出J对变量的梯度或者导数。本节课程我们将通过逻辑回归这一个具体的例子,来演示如何使用计算图完成逻辑回归的梯度下降算法。 逻辑回归 逻辑回归算法的目标函数,损失函数,代价函数,以及参数更新的方式如…

计算机网络学习记录 应用层 Day6

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我…

【Python报错】已解决AttributeError: Nonetype Object Has NoAttribute Group

解决Python报错:AttributeError: ‘list’ object has no attribute ‘get’ 在Python中,AttributeError通常表示你试图访问的对象没有你请求的属性或方法。如果你遇到了AttributeError: list object has no attribute get的错误,这通常意味着…

苹果Vision Pro 界面中英翻译

目录 菜单 🔷General🔄一般 AirDrop 隔空投送 Background App Refresh 后台应用刷新 Keyboards 键盘 VPN & Device Management VPN与设备管理​编辑Legal & Regulatory 法律法规 🔷Apps🔄应用程序 🔷Pe…

【python/pytorch】已解决ModuleNotFoundError: No module named ‘torch‘

【PyTorch】成功解决ModuleNotFoundError: No module named torch 一、引言 在深度学习领域,PyTorch作为一款强大的开源机器学习库,受到了众多研究者和开发者的青睐。然而,在安装和使用PyTorch的过程中,有时会遇到一些问题和挑战…

关于python包导入问题的重思考

将顶层目录直接设置为一个包 像这样,每一个文件从顶层包开始导入 这样可以解决我的问题,但是要注意的时,要避免使用出现上下级出现同名包的情况,比如: AutoServer--AutoServer--__init__.py--__init__.py这种情况下…

双指针问题1

文章目录 1. 移动零(283)2. 复写零(1089)3. 快乐数(202)4. 盛最多水的容器(11) 1. 移动零(283) 题目描述: 算法原理: 设置两个指针…

Centos7安装ElasticSearch

Centos7安装ElasticSearch 准备工作 下载elasticsearch https://www.elastic.co/cn/elasticsearch 将下载好的包上传到/usr/local/elasticsearch/ 路径下 安装 安装elasticsearch解压缩即可! tar -zxvf elasticsearch-8.12.2-linux-x86_64.tar.gz进入/usr/loca…

计算机毕业设计PySpark+Hadoop地震预测系统 地震数据分析可视化 地震爬虫 大数据毕业设计 Flink Hadoop 深度学习

基于Hadoop的地震预测的 分析与可视化研究 姓 名:____田伟情_________ 系 别:____信息技术学院___ 专 业:数据科学与大数据技术 学 号:__2011103094________ 指导教师:_____王双喜________ 年 月 日 …

度安讲 | 第二期「安全左移·业务护航」技术沙龙成功举办

当下,“安全左移”作为落地DevSecOps的重要实践之一,已在业界达成共识。DevSecOps作为一种集开发、安全、运维于一体的软件开发和运营模式,强调在敏捷交付下,“安全”在软件开发生命周期的全覆盖贯穿和核心位置。所谓“安全左移”…

多线程..

线程定义:线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中实际运作单位。简单来说,应用软件中相互独立,可以同时运作的功能。 多线程作用:有了多线程,我们就可以让程序…

03-240605-Spark笔记

03-240605 1. 行动算子-1 reduce 聚合 格式: def reduce(f: (T, T) > T): T 例子: val sparkConf new SparkConf().setMaster("local[*]").setAppName("Operator")val sc new SparkContext(sparkConf) ​val rdd sc.makeRDD(List(1…

MySQL第二种实现方式:现在有一个生产计划,甲乙丙3个品类共16个产品,生产时间6天,每天甲品类可以生产1张单,乙3张,丙1张,请用MySQL写出H列的效果

接上篇:链接: 现在有一个生产计划,甲乙丙3个品类共16个产品,生产时间6天,每天甲品类可以生产1张单,乙3张,丙1张,请用MySQL写出H列的效果 第二种写法: -- 使用WITH子句创建CTE WITH…

【Python报错】已解决ImportError: cannot import name ‘mapping‘ from ‘collections‘

成功解决“ImportError: cannot import name ‘mapping’ from ‘collections’”错误的全面指南 成功解决“ImportError: cannot import name ‘mapping’ from ‘collections’”错误的全面指南 一、引言 在Python编程中,当我们尝试从某个模块中导入某个名称时&…

QT学习过程中遇到的问题自记

文章目录 前言问题1问题2问题3 前言 学习QT嵌入式实战开发(从串口通信到JSON通信微课视频版)的过程中遇到的几个小问题 问题1 1.将书中的示例代码导入自己的电脑,然后点击工程进去,不能运行,报错 no kits are enabled for this project… 我…

python pip 安装

如果您不确定pip的安装路径,可以通过以下命令来查询: pip show pip 这个命令会显示pip的详细信息,其中包括pip安装的路径。如果您想修改pip的默认安装路径,可以使用pip的"--target"参数指定目标路径,例如&a…