【因果推断python】44_评估因果模型2

目录

累积弹性曲线

累积增益曲线

考虑差异

关键思想


累积弹性曲线

再次考虑将价格转换为二元处理的说明性示例。我们会从我们离开的地方拿走它,所以我们有弹性处理带。我们接下来可以做的是根据乐队的敏感程度对乐队进行排序。也就是说,我们把最敏感的组放在第一位,第二个最敏感的组放在第二位,依此类推。对于模型 1 和 3,无需重新订购,因为它们已经订购。对于模型 2,我们必须颠倒排序。

一旦我们有了有序的组,我们就可以构建我们称之为累积弹性曲线的东西。我们首先计算第一组的弹性;然后,第一个和第二个等等,直到我们包含所有组。最后,我们将只计算整个数据集的弹性。这是我们的说明性示例的外观。

img

请注意,累积弹性中的第一个 bin 只是根据该模型来自最敏感组的 ATE。此外,对于所有模型,累积弹性将收敛到同一点,即整个数据集的 ATE。

在数学上,我们可以将累积弹性定义为直到单位 k 之前估计的弹性。\widehat{y^{\prime}(t)}_k=\hat{\beta}_{1k}=\frac{\sum_i^k(t_i-\bar{t})(y_i-\bar{y})}{\sum_i^k(t_i-\bar{t})^2}

为了构建累积弹性曲线,我们在数据集中迭代地运行上述函数以产生以下序列。\widehat{(y^{\prime}(t)_1,\widehat{y^{\prime}(t)_2},\widehat{y^{\prime}(t)_3},\ldots,\widehat{y^{\prime}(t)_N})}

就模型评估而言,这是一个非常有趣的序列,因为我们可以对其进行偏好陈述。首先,模型更好的程度

\hat{y}'(t)k > \hat{y}'(t){k+a}

对于任何 k 和 a>0。换句话说,如果一个模型擅长对弹性进行排序,那么在前 k个样本中观察到的弹性应该高于在前 k+a 个样本中观察到的弹性。或者,简单地说,如果我查看顶部单位,它们应该比它们下面的单位具有更高的弹性。

其次,模型更好的程度

\hat{y}'(t)k - \hat{y}'(t){k+a}

是最大的,对于任何 k 和 a>0。直觉是,我们不仅希望顶部 k 单位的弹性高于其下方单位的弹性,而且我们希望这种差异尽可能大。

为了使其更具体,这是用代码表示的这个想法。

def cumulative_elast_curve(dataset, prediction, y, t, min_periods=30, steps=100):size = dataset.shape[0]# orders the dataset by the `prediction` columnordered_df = dataset.sort_values(prediction, ascending=False).reset_index(drop=True)# create a sequence of row numbers that will define our Ks# The last item is the sequence is all the rows (the size of the dataset)n_rows = list(range(min_periods, size, size // steps)) + [size]# cumulative computes the elasticity. First for the top min_periods units.# then for the top (min_periods + step*1), then (min_periods + step*2) and so onreturn np.array([elast(ordered_df.head(rows), y, t) for rows in n_rows])

关于此功能的一些注意事项。 它假定对弹性进行排序的事物存储在传递给“预测”参数的列中。 此外,第一组有 min_periods 单位,因此它可以与其他组不同。 原因是,由于样本量小,弹性在曲线开始时可能过于嘈杂。 为了解决这个问题,我们可以传递一个已经足够大的第一组。 最后,steps 参数定义了我们在每个后续组中包含多少额外单元。

使用此功能,我们现在可以根据每个模型产生的顺序绘制累积弹性曲线。

plt.figure(figsize=(10,6))for m in range(3):cumu_elast = cumulative_elast_curve(prices_rnd_pred, f"m{m+1}_pred", "sales", "price", min_periods=100, steps=100)x = np.array(range(len(cumu_elast)))plt.plot(x/x.max(), cumu_elast, label=f"M{m+1}")plt.hlines(elast(prices_rnd_pred, "sales", "price"), 0, 1, linestyles="--", color="black", label="Avg. Elast.")
plt.xlabel("% of Top Elast. Days")
plt.ylabel("Cumulative Elasticity")
plt.title("Cumulative Elasticity Curve")
plt.legend();

解释累积弹性曲线可能有点挑战性,但这是我的看法。同样,考虑二分类情况可能更容易。曲线的 X 轴代表我们正在处理的样本数量。在这里,我将轴归一化为数据集的比例,所以 0.4 意味着我们正在处理 40% 的样本。 Y 轴是我们在这么多样本上应该预期的弹性。因此,如果一条曲线在 40% 处的值为 -1,则意味着前 40% 单位的弹性为 -1。理想情况下,我们希望尽可能大的样本具有最高的弹性。理想的曲线将在 Y 轴上从高处开始,然后非常缓慢地下降到平均弹性,这表示我们可以处理高百分比的单位,同时仍保持高于平均弹性。

不用说,我们的模型都没有接近理想的弹性曲线。随机模型 M3 围绕平均弹性波动,并且永远不会离它太远。这意味着该模型无法找到弹性与平均弹性不同的组。至于预测模型 M1,它似乎是反向排序的弹性,因为曲线从低于平均弹性开始。不仅如此,它还在大约 50% 的样本处很快收敛到平均弹性。最后,因果模型 M2 似乎更有趣。一开始它有这种奇怪的行为,累积弹性增加远离平均值,但随后它达到了一个点,我们可以处理大约 75% 的单位,同时保持几乎为 0 的相当不错的弹性。这可能是因为这个模型可以识别非常低弹性(高价格敏感度)的日子。因此,如果我们在那些日子不提价,我们可以对大部分样本(约 75%)进行提价,同时价格敏感度仍然较低。

在模型评估方面,累积弹性曲线(Cumulative Elasticity Curve) 已经远远好于简单的分区间的弹性概念。在这里,我们设法对我们的模型做出更精确的偏好陈述。不过,这是一条复杂的曲线,难以理解。出于这个原因,我们可以做进一步的改进。

累积增益曲线

下一个想法是在累积弹性之上进行非常简单但强大的改进。我们将累积弹性乘以比例样本量。例如,如果累积弹性在 40% 时为 -0.5,那么此时我们将得到 -0.2 (-0.5 * 0.4)。然后,我们将其与随机模型产生的理论曲线进行比较。这条曲线实际上是一条从 0 到平均干预效果的直线。可以这样想:随机模型的累积弹性中的每个点都是 ATE,因为该模型只生成数据的随机代表性分区。如果在 (0,1) 线上的每一点,我们将 ATE 乘以该点,我们最终会得到一条介于 0 和 ATE 之间的直线。

img

一旦我们有了理论上的随机曲线,我们就可以将其用作基准,并将我们的其他模型与它进行比较。所有曲线将在同一点开始和结束。然而,模型的弹性排序越好,曲线在零到一之间的点处偏离随机线的程度就越大。例如,在上图中,M2 优于 M1,因为它在到达终点 ATE 之前发散得更多。对于熟悉 ROC 曲线的人,您可以将累积增益视为因果模型的 ROC。

从数学上讲,

\widehat{F(t)}_k=\hat{\beta}_{1k}*\frac kN=\frac{\sum_i^k(t_i-\bar{t})(y_i-\bar{y})}{\sum_i^k(t_i-\bar{t})^2}*\frac kN

要在代码中实现它,我们所要做的就是添加比例样本大小归一化。

def cumulative_gain(dataset, prediction, y, t, min_periods=30, steps=100):size = dataset.shape[0]ordered_df = dataset.sort_values(prediction, ascending=False).reset_index(drop=True)n_rows = list(range(min_periods, size, size // steps)) + [size]## add (rows/size) as a normalizer. return np.array([elast(ordered_df.head(rows), y, t) * (rows/size) for rows in n_rows])

 使用我们的冰激凌数据,我们会得到如下曲线。

plt.figure(figsize=(10,6))for m in range(3):cumu_gain = cumulative_gain(prices_rnd_pred, f"m{m+1}_pred", "sales", "price", min_periods=50, steps=100)x = np.array(range(len(cumu_gain)))plt.plot(x/x.max(), cumu_gain, label=f"M{m+1}")plt.plot([0, 1], [0, elast(prices_rnd_pred, "sales", "price")], linestyle="--", label="Random Model", color="black")plt.xlabel("% of Top Elast. Days")
plt.ylabel("Cumulative Gain")
plt.title("Cumulative Gain")
plt.legend();

现在很清楚,因果模型(M2)比其他两个要好得多。它与随机线的差异远大于 M1 和 M3。此外,请注意随机模型 M3 如何非常接近理论随机模型。两者之间的区别可能只是随机噪声。

有了这个,我们介绍了一些关于如何评估因果模型的非常好的想法。仅此一项就是一件大事。即使我们没有要比较的基本事实,我们也设法评估了模型在排序弹性方面的好坏。只缺少最后一件事,即包括围绕这些测量值的置信区间。毕竟,我们不是野蛮人,不是吗?

考虑差异

当我们处理弹性曲线时,不考虑方差是错误的。特别是由于它们都使用线性回归理论,因此在它们周围添加置信区间应该相当容易。

为此,我们将首先创建一个函数,该函数返回线性回归参数的 CI。我在这里使用简单线性回归的公式,但可以随意提取 CI。s_{\hat{\beta}_1}=\sqrt{\frac{\sum_i\hat{\epsilon}_i^2}{(n-2)\sum_i(t_i-\bar{t})^2}}

def elast_ci(df, y, t, z=1.96):n = df.shape[0]t_bar = df[t].mean()beta1 = elast(df, y, t)beta0 = df[y].mean() - beta1 * t_bare = df[y] - (beta0 + beta1*df[t])se = np.sqrt(((1/(n-2))*np.sum(e**2))/np.sum((df[t]-t_bar)**2))return np.array([beta1 - z*se, beta1 + z*se])

通过对我们的cumulative_elast_curve函数进行一些小的修改,我们可以输出弹性的置信区间。

def cumulative_elast_curve_ci(dataset, prediction, y, t, min_periods=30, steps=100):size = dataset.shape[0]ordered_df = dataset.sort_values(prediction, ascending=False).reset_index(drop=True)n_rows = list(range(min_periods, size, size // steps)) + [size]# just replacing a call to `elast` by a call to `elast_ci`return np.array([elast_ci(ordered_df.head(rows), y, t)  for rows in n_rows])

最后,这是因果 (M2) 模型的 95% CI 的累积弹性曲线。

plt.figure(figsize=(10,6))cumu_gain_ci = cumulative_elast_curve_ci(prices_rnd_pred, "m2_pred", "sales", "price", min_periods=50, steps=200)
x = np.array(range(len(cumu_gain_ci)))
plt.plot(x/x.max(), cumu_gain_ci, color="C0")plt.hlines(elast(prices_rnd_pred, "sales", "price"), 0, 1, linestyles="--", color="black", label="Avg. Elast.")plt.xlabel("% of Top Elast. Days")
plt.ylabel("Cumulative Elasticity")
plt.title("Cumulative Elasticity for M2 with 95% CI")
plt.legend();

注意随着我们积累更多的数据集,CI 是如何变得越来越小的。 那是因为样本量增加了。

至于累积增益曲线,获取 CI 也同样简单。 同样,我们只是将调用 elast 函数替换为调用 elast_ci 函数。

def cumulative_gain_ci(dataset, prediction, y, t, min_periods=30, steps=100):size = dataset.shape[0]ordered_df = dataset.sort_values(prediction, ascending=False).reset_index(drop=True)n_rows = list(range(min_periods, size, size // steps)) + [size]return np.array([elast_ci(ordered_df.head(rows), y, t) * (rows/size) for rows in n_rows])

这是因果模型的样子。 请注意,现在 CI 开始时很小,即使曲线开始时的样本量较小。 原因是归一化因子 \frac{k}{N} 回避了 ATE 参数,并且它是 CI。 由于这条曲线应该用于比较模型,所以这应该不是问题,因为曲线会将这个推卸因子平等地应用于所有正在评估的模型。

plt.figure(figsize=(10,6))cumu_gain = cumulative_gain_ci(prices_rnd_pred, "m2_pred", "sales", "price", min_periods=50, steps=200)
x = np.array(range(len(cumu_gain)))
plt.plot(x/x.max(), cumu_gain, color="C0")plt.plot([0, 1], [0, elast(prices_rnd_pred, "sales", "price")], linestyle="--", label="Random Model", color="black")plt.xlabel("% of Top Elast. Days")
plt.ylabel("Cumulative Gain")
plt.title("Cumulative Gain for M2 with 95% CI")
plt.legend();

关键思想

在这里,我们看到了三种方法来检查模型在排序弹性方面的好坏。我们使用这些方法来比较和决定具有因果关系的模型。这是非常重要的。我们已经设法检查了一个模型是否擅长识别具有不同弹性的组,即使无法看到弹性!

在这里,我们严重依赖随机数据。我们在非随机数据上训练了模型,但所有评估都是在随机处理的样本上完成的。那是因为我们需要某种方法来自信地估计弹性。如果没有随机数据,我们在这里使用的简单公式将不起作用。正如我们现在非常清楚的那样,简单的线性回归在存在混杂变量的情况下忽略了变量偏差。

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

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

相关文章

韩顺平0基础学java——第26天

p523-547 HashSet扩容时,只要节点到达了阈值就会扩,而不是数组长度到了才扩。 比如长16的数组,索引1放了8个,索引3放了4个,我再加一个他就会扩容。 另外谁能告诉我老师的debug界面是怎么设置的吗忘光了 HashSet存放…

基于Spring+Vue的前后端分离的计算器

麻雀虽小,五脏俱全 该项目已部署上线:http://calculator.wushf.top/ 并通过Gitee Go流水线实现持续部署。 需求分析 表达式求值 支持加减乘除四则运算、支持高精度 获取日志 Api文档定义 前后端分离,人不分离 通过Apifox定义接口细节&#…

(el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程

Ⅰ、Element-plus 提供的Select选择器组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供Select组件情况&#xff1a; 其一、Element-ui 自提供的Select代码情况为(示例的代码)&#xff1a; // Element-plus 提供的组件代码: <template><div class"f…

闹大了!高考作文“人工智能与AI”引发争议,专家喊话,部分考生家长无奈,直呼:“太不公平了!这哪里是考作文,分明是在考城乡差距啊!”

闹大了&#xff01;高考作文“人工智能与AI”引发争议&#xff0c;专家喊话&#xff0c;部分考生家长无奈&#xff0c;直呼&#xff1a;“太不公平了&#xff01;这哪里是考作文&#xff0c;分明是在考城乡差距啊&#xff01;” ​高考&#xff0c;本该是最公平的战场&#xff…

IO流2.

字符流-->字符流的底层其实就是字节流 public class Stream {public static void main(String[] args) throws IOException {//1.创建对象并关联本地文件FileReader frnew FileReader("abc\\a.txt");//2.读取资源read()int ch;while((chfr.read())!-1){System.out…

MySQL系列-语法说明以及基本操作(一)

1、前言 主要讲解MySQL的基本语法 官网文档 https://docs.oracle.com/en-us/iaas/mysql-database/doc/getting-started.html 关于MySQL的基本语法&#xff0c;关于数据类型、表的操作、数据操作、事务、备份等&#xff0c;可参考 http://www.voidme.com/mysql 2、数据类型 数…

多环境镜像晋级/复用最佳实践

作者&#xff1a;木烟 本文主要介绍镜像构建部署场景&#xff0c;多环境镜像晋级/复用最佳实践&#xff0c;保证“所发即所测”。 场景介绍 应用研发场景有效地管理镜像产物是确保软件快速、安全、可靠部署的关键环节。通常一个应用研发需要经过测试、预发、生产各个阶段&am…

PHP转Go系列 | 变量常量的使用姿势

大家好&#xff0c;我是码农先森。 变量 在 PHP 语言中&#xff0c;初始化变量虽然只有一行&#xff0c;其实包含了两步&#xff0c;一是声明变量&#xff0c;二是赋值给变量&#xff0c;同一个变量可以任意再赋值任何类型的数据。 <?php// 初始化变量 $name "man…

防爆气象仪的工作原理

TH-WFB5矿山气象传感器在矿山安全监测系统中扮演着至关重要的角色&#xff0c;它们能够及时发现异常情况&#xff0c;为矿山的安全运营提供可靠的数据支持。矿山气象传感器能够实时监测矿山环境中的风速、风向、温度、湿度和大气压力等关键气象参数。这些传感器采用先进的传感技…

网页五子棋对战项目测试(selenium+Junit5)

目录 网页五子棋对战项目介绍 网页五子棋对战测试的思维导图​ 网页五子棋对战的UI自动化测试 测试一&#xff1a;测试注册界面 测试二&#xff1a;测试登陆界面 测试三&#xff1a;测试游戏大厅界面 测试四&#xff1a;测试游戏房间界面以及观战房间界面 测试五&#…

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!

天津工业大学&#xff08;Tiangong University&#xff09;&#xff0c;简称“天工大”&#xff0c;位于天津市&#xff0c;是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…

多态性(Java)

本篇学习面向对象语言的第三个特性——多态。 目录 1、多态的概念 2、继承多态实现条件 3、重写 4、重新与重载的区别&#xff1a; 5、向上转移和向下转型 5、1向上转型&#xff1a; 5、2 向下转型 1、多态的概念 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态…

从零开始! Jupyter Notebook的安装教程

&#x1f680; 从零开始! Jupyter Notebook的安装教程 摘要 &#x1f4c4; Jupyter Notebook 是一个广受欢迎的开源工具&#xff0c;特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤&#xff0c;包括各种操作系统的安装方法&am…

从钉钉到跨境电商领域的技术演变,HHO如何通过NineData实现全球化业务布局

两氢一氧&#xff08;HHO&#xff09;是一家跨境出海电商平台&#xff0c;专注于通过数字化手段连接全球市场和中国优质供应链&#xff0c;致力于打造数字化时代的全球化新品牌。 创始人陈航&#xff0c;曾任钉钉 CEO 并成功打造行业领先的亿级活跃用户产品--钉钉。离开阿里后创…

Game-Fi 新贵 MetaArena 项目全解析:重塑区块链游戏生态

在区块链技术迅猛发展的浪潮中&#xff0c;全球各行业都在探索如何利用这一革命性技术来提升效率、降低成本&#xff0c;并创造新的商业模式。游戏行业作为数字娱乐的核心领域之一&#xff0c;也在经历前所未有的变革。尽管传统游戏巨头如Steam和任天堂已推出Web3元宇宙游戏产品…

Ceph入门到精通-ceph边缘集群你听说过嘛?

边缘集群是一种经济高效的对象存储配置解决方案。 Red Hat 支持以下 Red Hat Ceph Storage 集群的最低配置: 具有两个 SSD 副本的三节点集群。 具有三个 HDD 副本的四节点群集。 具有 EC 池的四节点集群,具有 2+2 配置。 对于较小的群集,由于使用量和复原能力的损失,利用率…

13.2 Go 接口的动态性

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

RK3588 代码中导入torch报错

RK3588 代码中导入torch报错 使用RK3588测试官方的YOLOv8,出现下面的问题 发现是dfl函数中导入torch的时候产生的&#xff0c;但是我在python终端上执行导入torch并没有发生报错 Traceback (most recent call last):File "infer.py", line 243, in <module>b…

数据结构-算法和算法分析

目录 前言一、算法1.1 算法与程序1.2 算法描述方法1.3 算法特性1.4 算法设计的要求 二、算法分析2.1 算法时间效率的度量2.1.1 事前分析方法算法的渐进时间复杂度算法时间复杂度分析例子算法最坏时间复杂度时间复杂度的计算规则 2.2 算法空间效率的度量 总结 前言 程序 数据结…

docker回顾--docker compose详细解释,安装,与常用命令

文章目录 Docker compose简介什么是Docker compose核心概念优势 安装常用命令总结 Docker compose简介 什么是Docker compose Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。它使得开发者可以使用一个单独的 YAML 文件来定义应用所需的所有服务、网络和卷&a…