【Python实战因果推断】2_因果效应异质性2

目录

CATE with Regression

Evaluating CATE Predictions


CATE with Regression

我想你可能已经预料到了:与应用因果推理中的大多数情况一样,答案往往从线性回归开始。但在走这条路之前,让我们把事情变得更具体一些。假设你在一家遍布全国的连锁餐厅工作。这项业务的一个关键组成部分是了解何时应该给顾客打折。为此,该公司在全国范围内进行了一项为期三年的实验,在连锁店中的六家不同餐厅随机提供折扣。数据存储在以下数据框中:

您的目标是了解何时是打折的最佳时机。在这些数据中,每家餐厅和每一天都有一行数据。这与本书中使用的大多数示例有些不同,以前的示例以顾客为单位。现在,单位是日-餐厅组合。即便如此,你仍然可以运用以前的推理方法,只是你要 "对待"(给予折扣)的不是顾客,而是 "对待 "日。您也可以在每一天的每家餐厅采用不同的价格,但我们还是把问题简化为保持各餐厅的价格一致。

您可以将这一业务问题视为 CATE 估算问题。如果您能创建一个模型,输出每一天的销售额对折扣的敏感度以及协变量,即 \frac\partial{\partial t}E[Sales(t)|X] ,那么,您就可以使用该模型来决定何时打折以及打多少折。

现在你有了更具体的东西可以利用,让我们来看看回归如何帮助你。回想一下,您当时的情况很复杂。您需要预测 \frac{\delta Y_{i}}{\delta T_{i}},但遗憾的是,它是不可观测的。所以你不能简单地使用多项式回归算法,然后将其作为目标。但也许你并不需要观察 \frac{\delta Y_{i}}{\delta T_{i}} 来预测它。

例如,假设您对数据拟合了以下线性模型:y_i=\beta_0+\beta_1t_i+\beta_2X_i+e_i

如果在治疗上加以区分,结果会如下:\frac{\delta y_i}{\delta t_i}=\beta_1  即 在随机治疗的情况下ATE。

由于可以通过估计前面的模型得到 \widehat{\beta}_{1} ,因此甚至可以说,即使无法观察到斜率,也可以预测斜率。在这个例子中,预测相当简单。您预测的是每个人的恒定值 \widehat{\beta}_{1}。这是件好事,但并不是您想要的。这是 ATE,而不是 CATE。这对您计算何时给予折扣没有任何帮助,因为每个单位(日和餐厅组合)得到的斜率预测都是一样的。

要改进它,可以做以下简单的改变:y_i=\beta_0+\beta_1t_i+\beta_2X_i+\beta_3t_iX_i+e_i,这样就可以预测出以下坡度:\frac{\widehat{\delta y_i}}{\delta t_i}=\widehat{\beta_1}+\widehat{\beta_3}X_i其中,\beta_3 是 X 特征的向量系数!

每个由不同 Xi 定义的实体都会有不同的斜率预测。换句话说,斜率预测会随着 X 的变化而变化。直观地说,包含治疗与协变因素之间的交互作用可以让模型了解效果如何随着这些协变因素的变化而变化。这就是回归如何为您提供估计 CATE 的方法,即使您无法直接预测它。
理论就讲到这里。让我们来看看如何编写代码。首先,您需要定义协变量。在本例中,协变量基本上是日期的特定特征,如月份、星期以及是否是节假日。我还加入了竞争对手的平均价格,因为这可能会影响顾客对每家餐厅折扣的反应。

一旦有了协变量,就需要将它们与治疗进行交互。* 运算符就可以做到这一点。它为左侧和右侧创建一个加法项,再加上一个交互项。例如,a*b 将在回归中包含 a、b 和 a * b 项。在你的例子中,结果如下:

sales_i=\beta_0+\beta_1discount_i+\beta_2X_i^\star discount_i+\beta_3X_i+e_i

import statsmodels.formula.api as smf
X = ["C(month)", "C(weekday)", "is_holiday", "competitors_price"]
regr_cate = smf.ols(f"sales ~ discounts*({'+'.join(X)})",data=data).fit()

估算出模型后,就可以从参数估算值中提取预测斜率:

\frac{\delta sales_i}{\delta discounts_i}=\widehat{\beta_1}+\widehat{\beta_3}X_i

其中,β1 是折扣系数,β3 是交互系数向量。您可以直接从拟合模型中提取这些参数,但获得斜率预测的更简便方法是使用导数的定义:\frac{\delta y}{\delta t}=\frac{y(t+\epsilon)-y(t)}{(t+\epsilon)-t}\epsilon趋近0, 您可以用 1 代替 \epsilon 来近似地理解这一定义:\frac{\delta y}{\delta t}\approx\hat{y}(t+1)-\hat{y}(t), 其中 y 由模型预测值给出。由于这是一个线性模型,因此近似值是精确的。

换句话说,您将用模型做出两个预测:一个通过原始数据,另一个通过原始数据,但处理量增加了一个单位。这两个预测之间的差异就是您的 CATE 预测。下面是一些代码:

ols_cate_pred = (regr_cate.predict(data.assign(discounts=data["discounts"]+1))-regr_cate.predict(data))

好了,您有了 CATE 模型及其预测。但仍有一个潜伏的问题:它到底有多好?换句话说,如何评估这个模型?您可能已经知道,比较实际值和预测值在这里是行不通的,因为实际治疗效果并不是在单位水平上观察到的。

Evaluating CATE Predictions

如果您有传统数据科学的背景,您可能会发现这种 CATE 预测看起来很像常规的机器学习预测,但却有一个无法在单位层面观察到的隐秘目标。这意味着,传统机器学习中使用的大量模型评估技术(如交叉验证)在这里仍然适用,而其他技术则需要一些调整。

因此,为了保持传统,我们将数据分为训练集和测试集。既然有时间维度,那就用它吧。训练集将包含 2016 年和 2017 年的数据,测试集则包含 2018 年以后的数据:

train = data.query("day<'2018-01-01'")
test = data.query("day>='2018-01-01'")

现在,让我们重试之前的 CATE 回归模型,但只使用训练数据进行估计,并对测试集进行预测:

X = ["C(month)", "C(weekday)", "is_holiday", "competitors_price"]regr_model = smf.ols(f"sales ~ discounts*({'+'.join(X)})",data=train).fit()cate_pred = (regr_model.predict(test.assign(discounts=test["discounts"]+1))-regr_model.predict(test))

为了增加趣味性,让我们用一个纯粹的预测性机器学习模型来衡量这个回归模型。这个机器学习模型只是试图预测结果 Y:

from sklearn.ensemble import GradientBoostingRegressorX = ["month", "weekday", "is_holiday", "competitors_price", "discounts"]y = "sales"np.random.seed(1)ml_model = GradientBoostingRegressor(n_estimators=50).fit(train[X],train[y])ml_pred = ml_model.predict(test[X])

最后,让我们把一个非常糟糕的模型也纳入比较范围。这个模型简单地输出-1 和 1 之间的随机数。这显然是无稽之谈,但也是一个值得关注的有趣基准。归根结底,你想知道用 CATE 模型分配治疗是否会比随机分配更好,这就是最后一个模型的作用。

为了方便起见,我将所有数据存储在一个新的数据帧 test_pred:

np.random.seed(123)test_pred = test.assign(ml_pred=ml_pred,cate_pred=cate_pred,rand_m_pred=np.random.uniform(-1, 1, len(test)),)

有了模型之后,就该想办法评估和比较它们了。也就是说,你必须面对ground truth是不可观测的这一事实。正如你很快就会看到的,诀窍在于认识到,尽管你无法测量单个个体的治疗效果,但你可以估计很小群体的治疗效果。因此,如果你想用 CATE 来评估你的模型,就必须依赖于群体层面的指标。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[A133]uboot启动流程

[A133]uboot启动流程 hongxi.zhu 2024-6-21 1. 第一阶段 lds描述 从u-boot.lds中能找到程序的汇编入口ENTRY(_start) brandy/brandy-2.0/u-boot-2018/u-boot.lds OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUT…

Spring Boot中的异步编程技巧

Spring Boot中的异步编程技巧 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨在Spring Boot应用程序中如何使用异步编程技巧&#xff0c;以提升性…

LeetCode题练习与总结:单词拆分--139

一、题目描述 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 示例 1&#xff1a; 输入: s "l…

vant组件 顶部下拉刷新和页面底部下拉获取数据+顶部搜索框

1.html部分&#xff08;顶部tab切换无&#xff0c;只有主体list部分&#xff09; <div class"yd" ><!-- yd端 --><!-- 搜索框 --><van-searchv-model"ydsearchvalue"show-actionplaceholder"请输入搜索关键词"search"…

JavaEE之HTTP协议(1)_HTTP基础知识,HTTP 请求、响应格式,方法,状态码

一、HTTP协议 1.1 基本概念: HTTP全称超文本传输协议&#xff0c;是一种无状态的、应用层的协议&#xff0c;它基于请求/响应模型。客户端&#xff08;通常是Web浏览器&#xff09;通过发送HTTP请求到服务器来获取或发送信息&#xff0c;服务器则返回HTTP响应作为回应。HTTP协…

shell (三)shell脚本

SHELL脚本 编程语言的分类 解释型语言&#xff1a;shell&#xff0c;Python&#xff0c;需要解析器 编译型语言&#xff1a;C语言&#xff0c;C&#xff0c;需要编译器 shell脚本 操作系统的结构 shell&#xff08;贝壳&#xff09; 应用层 app&#xff0c;代码 应用层需要通…

2024年软件测试面试题大全【答案+文档】

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、面试基础题 简述测试流程&#xff1a; 1、阅读相关技术文档&#xff08;如产品PRD、UI设计…

1、线性回归模型

1、主要解决问题类型 1.1 预测分析(Prediction) 线性回归可以用来预测一个变量(通常称为因变量或响应变量)的值,基于一个或多个输入变量(自变量或预测变量)。例如,根据房屋的面积、位置等因素预测房价。 1.2 异常检测(Outlier Detection) 线性回归可以帮助识别数…

鸿蒙开发系统基础能力:【@ohos.systemTime (设置系统时间)】

设置系统时间 本模块用来设置、获取当前系统时间&#xff0c;设置、获取当前系统日期和设置、获取当前系统时区。 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import systemTime …

沙盒在数据防泄密领域意义

在信息化快速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据泄密事件频发&#xff0c;给企业的安全和发展带来了巨大威胁。SDC沙盒防泄密系统&#xff0c;作为一种创新的数据防泄密解决方案&#xff0c;正逐渐在数据防泄密领域发挥着越来越重要的…

理解和使用JavaScript的闭包

闭包 在前端开发中&#xff0c;JavaScript是一种非常重要的编程语言。它的灵活性和强大功能使得开发者可以创建丰富的用户体验。然而&#xff0c;JavaScript中有些概念对于初学者来说可能比较难以理解&#xff0c;闭包就是其中之一。本文将深入探讨JavaScript中的闭包&#xf…

安装zabbix时报错Could not resolve host: mirrors.huaweicloud.com;Unknown error解决办法

目录 1、问题原因 2、解决办法 3、知识拓展 DNS的区别 DNS配置文件解析 域名解析过程 4、书籍推荐 当安装Zabbix server&#xff0c;Web前端&#xff0c;agent时出现&#xff1a; [rootsc-zabbix-server ~]# yum install zabbix-server-mysql zabbix-agent安装过程中会出…

Python3极简教程(一小时学完)上

开始 Python 之旅 本教程基于 Python for you and me 教程翻译制作&#xff0c;其中参考了 Python tutorial 和 _The Python Standard Library_&#xff0c;并对原教程的内容进行了改进与补充。 相关链接地址如下&#xff1a; _Python tutorial_&#xff1a;Python 入门指南…

数字孪生流域:定义、组成等

数字孪生流域&#xff1a;定义、组成等 1 数字孪生流域&#xff08;Digital Twin Basin/Watershed&#xff09;总则1.1 定义1.2 适用范围1.3 建设目标1.4 建设原则 2 数字孪生流域框架与组成2.1 数字孪生流域框架2.2 数字孪生流域组成2.2.1 数字孪生平台2.2.2 信息化基础设施 3…

类的装饰器

1 使用类定义装饰器 class Person(object):def __init__(self):self._age 0propertydef age(self):return self._ageage.setterdef age(self,newValue):print(触发了吗)self._age newValuep Person() print(p.age) # 0 p.age 20 print(p.age) # 20 2 类属性 class Pe…

JavaScript学习笔记(二)

12、数字 常规用法和java的用法相似&#xff0c;就不再做详细的记录, JavaScript 数字 以下只记录特殊用法&#xff1a; 12.1 数字字符串运算 在所有数字运算中&#xff0c;JavaScript 会尝试将字符串转换为数字&#xff1a; var x "100"; var y "10"…

探索QCS6490目标检测AI应用开发(一):Yolov8n模型转换及量化

目标检测&#xff08;Object Detection&#xff09;是计算机视觉领域的核心任务之一&#xff0c;它旨在识别图像中的物体并确定其位置&#xff0c;在本期的文章中&#xff0c;我们用一个端到端的目标检测AI应用为例子。介绍如何在QCS6490 Ubuntu系统上实现一个目标检测应用开发…

第 5 章理解 ScrollView 并构建 Carousel UI

通过上一章的学习,我相信你现在应该明白如何使用堆栈构建复杂的 UI。当然,在你掌握 SwiftUI 之前,你还需要大量的练习。因此,在深入研究 ScrollView 以使视图可滚动之前,让我们先以一个挑战开始本章。你的任务是创建一个类似于图 1 所示的卡片视图。 …

如何迁移R包

迁移R包涉及将一个或多个R包从一个系统转移到另一个系统。以下是迁移R包的详细步骤&#xff1a; 1. 确定要迁移的R包 首先&#xff0c;列出你在当前系统中安装的所有R包&#xff0c;或仅列出你需要迁移的R包。你可以使用以下代码列出所有安装的R包&#xff1a; installed_pa…

swp添加池子addLiquidity失败

案发现场 首次添加交易对、一直失败、但是也没提示具体的原因。到这一步就没了、由下图可知、也没看到log、由此可见第一步就失败了。 解决方案 一、添加 工厂KywFactory 添加如下 bytes32 public constant INIT_CODE_PAIR_HASH keccak256(abi.encodePacked(type(KywPair…