【因果推断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` column
    ordered_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 on
    return 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_bar
    e = 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();

关键思想

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

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

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

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

相关文章

day13 二叉树的遍历

一、二叉树的递归遍历 题目链接: 144.二叉树的前序遍历(opens new window)145.二叉树的后序遍历(opens new window)94.二叉树的中序遍历 文章讲解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%80%92%E5%BD%92%E9%81%8D%E5%8E…

苍穹外卖---编辑员工(P27-P29)

一、需求分析与设计 (1)产品原型 在员工管理列表页面点击 "编辑" 按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击 "保存" 按钮完成编辑操作。 员工列表原型: 修改…

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系(m_coord)

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系(m_coord) 0. 引言1. m_proj使用方法2. 结语 0. 引言 上一篇介绍了m_proj函数用于初始化投影,本篇介绍的函数m_coord用于初始化地理坐标系或地磁坐标系,地理/地磁坐标系和投影…

数学建模----单源最短路径模型建立和求解

目录 1.引言和声明 2.单源最短路径 3.建立模型 4.代码求解 1.引言和声明 (1)最近又在准备学习matlab,有了一些新的理解和体会,记录一下; (2)这个首先要声明两个符号,这两个符号也是今天才知…

机械臂 CoppeliaSim Simulink联合仿真

实现机械臂在CoppeliaSim(以前称为V-REP)和Simulink上的联合仿真涉及多个步骤,包括环境设置、模型导入、通信配置、控制算法设计和测试调试。 前期准备 安装软件配置工作环境创建和配置CoppeliaSim场景 导入机械臂模型配置机械臂参数在Simuli…

2024年化学、能源与核工程国际会议(ICCENE 2024)

2024年化学、能源与核工程国际会议(ICCENE 2024) 2024 International Conference on Chemical, Energy and Nuclear Engineering (ICCENE 2024) 会议地点:三亚,中国 网址:www.iccene.com 邮箱: iccenesub-conf.com 投稿主题请注明:ICCEN…

Leetcode刷题笔记11

415. 字符串相加 415. 字符串相加 - 力扣(LeetCode) 解法一:头插 头插是指将一个新元素插入到链表的头部(即第一个位置)。 比如对于456和77,先计算两个数字的末项67的结果,然后往前挪动一位 …

基于PLC的全自动洗衣机控制系统课设

一、设计题目 1.1课题内容 根据设计参数和控制要求,设计一全自动洗衣机,画出其运行框图及梯形图控制程序的编制,并画出硬件接线图。 1.2设计参数 1.3控制要求 (1)按下启动按扭及水位选择开关,开始进水直…

18张Python数据科学速查表.png

数据科学已经发展成为一个庞大的系统,包含数学、统计学、概率论、计算机、数据库、编程等各种理论技术。 目前在主流的数据科学领域一般有三大生态,一是以sas、matlab、spss等为代表的商业软件生态,二是围绕R语言建立起来的开源生态&#xf…

CPN IDE实现分层效果

Shift键鼠标选中要分层的库所和变迁!然后create subpage。 Subpage是这样的,不会像CPN tools里面自动生成IN和OUT库所,但是也能正确运行。 虽然父页面在运行中有标红:"port not defined" 错误通常意味着在模型中有一些连…

电脑提示d3dcompiler_47.dll丢失的解决方法,实测靠谱的5种方法

在计算机使用过程中,缺失d3dcompiler_47.dll这一系统文件是一个常见问题,尤其是对于游戏和图形密集型应用程序用户来说尤为重要。这个文件是DirectX软件工具包的一部分,主要用于处理图形渲染的应用程序接口的核心元素。当你在运行游戏或某些软…

连获殊荣,天润融通以AI技术重塑企业客户联络体验!

天润融通又获奖了。 2024年3月22日,「ToB行业头条」联合3W集团共同举办的「2024ToB头条行业大会」在北京举行。 为表彰在过去一年中表现卓越、对行业发展作出显著贡献的企业、产品和数字化转型案例,大会颁布了ToB年度榜单【2023中国ToB行业影响力价值榜…

【尝鲜】SpringCloudAlibaba AI 配置使用教程

1、环境配置 maven依赖pom.xml 注意配置远程仓库&#xff0c;原因见&#xff1a;Unresolved dependency: ‘org.springframework.ai:spring-ai-core:jar:0.8.1’ <dependencies><!--Base--><dependency><groupId>org.springframework.boot</group…

进化版ChatGPT的Siri今年无缘上线!苹果正打造史上最薄iPhone 17

目录 01 超强Siri助手预计2025年上线 02 集成ChatGPT但没有买单 03 iPhone 17更轻薄 最新报道称&#xff0c;苹果的AI功能将在未来几个月逐步推出&#xff0c;并持续到2025年。 据称&#xff0c;今年夏天结束前&#xff0c;开发者们仍无法试用和体验。 因此&#xff0c;在即…

【JavaEE】Spring Web MVC详解

一.基本概念. 什么是Spring Web MVC? 官方链接: https://docs.spring.io/spring-framework/reference/web/webmvc.html Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. Th…

Ubuntu22.04系统安装及配置

文章目录 一、选择“安装” 二、选择“语言” 三、安装器更新 四、键盘布局 五、选择安装类型 六、网络配置 七、代理设置 八、镜像地址 九、磁盘划分 十、设置用户名、主机名、登录密码 十一、升级到Ubuntu Pro 十二、SSH设置 十三、选装软件包 十四、开始安装进…

13.2 Go 接口的动态性

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

移动硬盘在苹果电脑上无法识别的诊断与恢复策略

一、问题描述 在数字时代&#xff0c;移动硬盘已成为我们存储和传输数据的重要工具。然而&#xff0c;当我们将移动硬盘插入苹果电脑时&#xff0c;有时会遇到无法识别的情况&#xff0c;这让我们感到十分困扰。本文将详细探讨移动硬盘插苹果电脑后读不出来的现象&#xff0c;…

超神级!Markdown最详细教程,程序员的福音

超神级&#xff01;Markdown最详细教程&#xff0c;程序员的福音Markdown最详细教程&#xff0c;关于Markdown的语法和使用就先讲到这里&#xff0c;如果喜欢&#xff0c;请关注“IT技术馆”。馆长会更新​最实用的技术&#xff01;https://mp.weixin.qq.com/s/fNzhLFyYRd3skG-…

经验分享,16进制与字符串的互相转换网站

分享一个16进制与字符串的互相转换的网站&#xff0c;比较实用。 网址&#xff1a; https://www.bejson.com/convert/ox2str/ 截图&#xff1a;