【python因果推断库3】使用 CausalPy 进行贝叶斯geolift 分析

news2024/12/23 15:36:06

目录

导入数据

丹麦的销售额是否有地理提升(GeoLift)?

结果


本笔记本介绍如何使用 CausalPy 的贝叶斯{术语}合成控制功能来评估“地理提升”(GeoLift)。我们的假设情景如下:

你是一家在欧洲运营的公司的数据科学家。你得到了一份过去四年的历史销售量数据集,数据按千单位计算,按周频率收集,并按国家细分。数据涵盖了过去四年的时间。

从2022年初开始,市场部门决定翻新丹麦所有的门店。到了2022年底,公司希望你能评估这次翻新计划是否增加了销售额。如果你告诉他们门店翻新计划提高了销售额,那么他们会将这一计划推广到其他国家。虽然没有人明说,但在你的潜意识里你担心如果报告翻新能提高销售额但实际上未来并没有发生这种情况,那么公司的利润将会下降,你的股票价值也会减少,甚至你的工作也可能面临风险。

你的上司非常明白这些担忧。她也有同样的顾虑。她知道虽然很容易建立门店翻新与销售额变化之间的关联,但我们真正想知道的是门店翻新是否导致了销售额的增加。

我们知道提出因果主张的最佳方式是运行随机对照试验(有时称为A/B测试)。如果我们随机选择欧洲各地的门店(或选择一个国家),那么也许A/B测试就能完成任务。但我们并没有随机选择丹麦,所以我们担心可能存在混淆变量。

但我们听说过合成控制方法以及所谓的GeoLift。经过一番研究后,我们决定这就是我们要做的事情。但我们特别关心我们对检测到的任何提升程度的确信程度,所以我们希望使用贝叶斯方法并获得易于解释的贝叶斯可信区间。你找到了一个叫做 CausalPy 的库,正好支持这种应用场景,感到非常高兴。

import arviz as az
import matplotlib.dates as mdates
import pandas as pd

import causalpy as cp
%load_ext autoreload
%autoreload 2
pd.set_option("display.precision", 2)
seed = 42

导入数据

CausalPy 包含了一个适用于探索地理提升测试概念的示例(模拟)数据集。我们所需要做的就是加载这个数据集,适当地在 Pandas 数据框中设置观察日期,并定义处理时间。

df = (
    cp.load_data("geolift1")
    .assign(time=lambda x: pd.to_datetime(x["time"]))
    .set_index("time")
)

treatment_time = pd.to_datetime("2022-01-01")
df.head()

在我们的数据集中,各列代表我们在欧洲运营的不同国家。我们还有一个索引,用于标记每一行的日期 —— 观测频率为每周一次。表格中的值代表销售量,并以千为单位。因此,一个2.4的值代表每周售出2,400单位。

那么,让我们来绘制一下这个图表。

untreated = list(set(df.columns).difference({"Denmark"}))
ax = df[untreated].plot(color=[0.7, 0.7, 0.7])
df["Denmark"].plot(color="r", ax=ax)
ax.axvline(treatment_time, color="k", linestyle="--")
ax.set(title="Observed data", ylabel="Sales volume (thousands)");

看起来挺不错的,但也有些令人失望。从视觉检查中并不明显看出,在门店翻新后(由虚线表示),丹麦的销售数据有明显的变化。这一点因为数据中存在的年度季节性(每个国家都不同)以及周销售数据本身的随机性而变得更糟。

为了更好地分析丹麦门店翻新后的销售变化,我们可以考虑对数据做一些处理,例如使用移动平均来平滑数据,或者建立一个时间序列模型来分离季节性和趋势成分。这样可以帮助我们更清晰地观察到翻新前后销售的具体变化。

丹麦的销售额是否有地理提升(GeoLift)?

为了计算门店翻新所带来的因果效应(如果有),我们需要比较干预后丹麦的实际销售额与如果没有进行干预时丹麦的反事实销售额。这就是为什么称之为反事实的原因——我们在丹麦确实进行了门店翻新,所以这是一个完全假设的情景,与事实相反。但如果我们可以测量(或者更现实地说是估算)这个反事实情形,那就会成为我们的对照组。

在这种情况下,我们将生成一个合成控制组,这是一种用来估算如果门店没有翻新的情况下丹麦反事实销售额的技术。你可以阅读合成控制维基百科页面了解更多关于合成控制方法的信息,但基本思想如下。对于熟悉传统(非贝叶斯)建模方法的人来说,基本的合成控制算法可以这样描述:

import my_custom_scikit_learn_model as weighted_combination


# fit the model to pre-intervention (training) data
weighted_combination.fit(X_train, y_train)
# estimate the counterfactual given post-intervention (test) data
counterfactual = weighted_combination.predict(X_test)
# estimate the causal impact
causal_impact = y_test - counterfactual
# cumulative causal impact
np.cumsum(causal_impact)

这里并没有什么魔法——我们只是将未接受处理的单位作为加权和来估计一个合成的丹麦。我们基于干预前观察到的“训练”数据来做这件事。然后,我们使用这个加权和模型根据干预后未处理国家的“测试”数据来预测我们的合成丹麦。之后,我们可以简单地将这个反事实的估计与丹麦观察到的销售数据进行比较,从而得到因果影响的估计值。我们还可以(可选地)计算累积因果影响来回答这个问题:“门店翻新在2022年带来了多少额外的销售额?”

我们可以使用CausalPy的API来运行这个过程,但是采用贝叶斯推断方法如下:

对于PyMC采样器的random_seed关键字参数并不是必需的。我们在这里使用它是为了使结果可以重现。

formula = """
    Denmark ~ 0 + Austria + Belgium + Bulgaria + Croatia + Cyprus + Czech_Republic
"""

result = cp.pymc_experiments.SyntheticControl(
    df,
    treatment_time,
    formula=formula,
    model=cp.pymc_models.WeightedSumFitter(
        sample_kwargs={"target_accept": 0.95, "random_seed": seed}
    ),
)

结果

让我们使用ArviZ来检查每个国家的beta权重以及测量标准差sigma的后验参数估计值。

az.plot_forest(result.idata, var_names=["~mu"], figsize=(8, 3), combined=True);

 现在我们可以使用从 CausalPy 返回的结果对象的绘图方法。这将为我们提供一个非常详细的可视化输出。

fig, ax = result.plot(plot_predictors=False)

# formatting
ax[2].tick_params(axis="x", labelrotation=-90)
ax[2].xaxis.set_major_formatter(mdates.DateFormatter("%Y"))
ax[2].xaxis.set_major_locator(mdates.YearLocator())
for i in [0, 1, 2]:
    ax[i].set(ylabel="Sales (thousands)")

通过创建一个简单的模型公式并调用一次 CausalPy,我们就能够评估出处理单元产生的提升效果。

在这个例子中,测量噪声相当多,但由于我们在这里使用的是贝叶斯推断方法,因此我们对自己的不确定性有了精确且合理的原则性量化。

我们可以看到,对于预处理数据的贝叶斯值大约是 0.5。这个值虽然不是特别好,但对于真实世界的数据来说已经很不错了。它表明线性加权组合模型(合成控制的核心)在构建虚拟(即合成)丹麦直到处理期之前的工作表现还算合理。

这个合成控制的丹麦就是我们估计的反事实情况——如果商店翻新项目没有实施的话,销售额会是多少。通过对比我们可以估算因果影响,也可以称之为“地理位置提升”。

在实施后的一年内,我们可以看到丹麦的销售额累计因果影响接近 10,000 单位。让我们更详细地看看这一点。下面我们将查看时间序列末尾时累计因果影响的后验分布,在该方案实施一年之后。

# get index of the final time point
index = result.post_impact_cumulative.obs_ind.max()
# grab the posterior distribution of the cumulative impact at this final time point
last_cumulative_estimate = result.post_impact_cumulative.sel({"obs_ind": index})
# get summary stats
ax = az.plot_posterior(last_cumulative_estimate, figsize=(8, 4))
ax.set(
    title="Estimated cumulative causal impact (at end of 2022)",
    xlabel="Sales (thousands)",
);

如果我们愿意,我们也可以以数值形式提取这些统计信息:

如此,在我们因果建模工作的最后,我们可以向我们的上司汇报如下:“我们认为商店翻新计划对推动总共约 9,150 个额外销售起到了因果作用。但我们对确切的额外销售数量有所不确定——我们的 94% 可信区间范围是从 7,420 到 10,790。”

当然,还有一些需要注意的限制条件。我们所进行的分析假设唯一可能选择性地影响丹麦销售额的重大事件就是商店翻新项目。如果这是一个合理的假设,那么我们在提出因果主张时可能会相对稳固。但如果还有其他事件选择性地影响了一些单位(国家)而不是其他的单位,那么我们在提出主张时就需要更加谨慎,并可能需要采取更深入的建模方法。

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

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

相关文章

集成电路学习:什么是ISP系统编程

一、ISP:系统编程 ISP(In-System Programming)即系统编程,是一种在系统内部进行的编程方法,主要用于对闪存(FLASH)、EEPROM等非易失性存储器的编程。ISP编程提供了巨大的灵活性,允许…

SaaS用户增长:提升转化率的实践路径

在SaaS(软件即服务)行业这片竞争激烈的蓝海中,企业要实现稳健的用户增长,必须聚焦于优化用户获取与转化策略,以提升用户转化率。用户转化率,作为衡量SaaS产品市场吸引力和用户接纳度的核心指标,…

图文解析保姆级教程: IDEA里面创建SpringBoot工程、SpringBoot项目的运行和测试、实现浏览器返回字符串

文章目录 一、创建SpringBoot工程(需要联网)二、 定义请求处理类三、运行测试 此教程摘选自我的笔记:黑马JavaWeb开发笔记13——Springboot入门(创建、运行&测试项目)、Http协议(请求&响应协议&…

Unity实战案例 2D小游戏HappyGlass(模拟水珠)

本案例素材和教程都来自Siki学院,十分感谢教程中的老师 本文仅作学习笔记分享交流,不作任何商业用途 预制体 在这个小案例中,水可以做成圆形但是带碰撞体,碰撞体比图形小一圈,顺便加上Trail renderer组件 材质 将碰撞…

SVN介绍和使用

一、SVN(Subversion) SVN 是一种版本控制系统,可以用于管理和控制文件的变更。以下是SVN的基本使用步骤: 安装SVN:首先,您需要在计算机上安装SVN客户端。您可以从Subversion官方网站下载安装程序&#xff…

sql-labs61-65关通关攻略

第61关 一:查看数据库 ?id1)) and updatexml(1,concat(1,(select database())),1)-- 二:查看表名 ?id1)) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity)),1)-- 三&#…

MATLAB/Simulink 汽车ABS仿真模型 防抱死刹车 教程 资料 程序 模型 论文 视频

项目概述 防抱死制动系统(ABS)是现代车辆中的一项重要安全技术,它能够在紧急制动时防止车轮锁死,从而提高车辆的稳定性和操控性。本项目旨在使用MATLAB/Simulink建立一个完整的ABS仿真模型,帮助学习者理解ABS的工作原理…

WebRTC协议下的视频汇聚融合技术:EasyCVR构建高效视频交互体验

视频汇聚融合技术是指将来自不同源、不同格式、不同网络环境的视频流进行集中处理、整合和展示的技术。随着视频监控、远程会议、在线教育、直播娱乐等领域的快速发展,视频数据的规模急剧增长,对视频处理能力和效率提出了更高要求。视频汇聚融合技术通过…

【杭州】目前就业情况-自述

博主在今年6月份,被自己领导下达了裁员通知,所以近期一直都没有更新博文。那么接下来简单介绍下杭州2024年就业情况吧! 目录 一、行情 二、薪资 三、外包 四、如果你真快吃不上饭了 五、博主被问的面试题 一、行情 今年应该是有史以…

低代码技术助力移动端开发:简化开发流程,实现快速创新

在移动互联网快速发展的今天,企业和开发者面临着越来越高的需求,要求开发高质量、功能强大的移动应用,以满足用户的期待和市场的变化。然而,传统的移动端开发流程通常复杂且耗时,需要投入大量的资源和开发人员。为了应…

Unity坐标系计算3D中两直线的最短距离及最近点的几何原理

方法1: 已知空间中两直线AB, CD,判断它们是否相交 问题的关键是求出这两条直线之间的最短距离,以及在这个距离上最接近两线的点坐标,判断该点是否在直线AB和直线CD上。 首先将直线方程化为对称式,分别得到两直线方向向…

VUE 实现三级权限选中与全选

功能:点击全选时所有子级选中,点击子级时对应的所有父级要选中。 实现思路:通过递归将所有子级转化为一级,选中时将选中的ID存为一个二级数组。循环时判断当前项在选中的数组中存在时即为勾选状态。 1、所有子级选中&#xff1a…

【盖世汽车-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…

python django 使用教程

前言 python django使用起来简单方便,大大节省开发时间,提高开发效率,现在介绍下如何使用 一、创建 Django 项目 首先,建立虚拟环境,(最好养成一个项目一个环境的习惯,防止多个项目pip包混乱问…

Web3与AI的融合:开启去中心化应用的新纪元

在数字科技不断发展的今天,Web3与人工智能(AI)的融合正引领去中心化应用(DApps)的新纪元。这种结合不仅扩展了去中心化技术的应用场景,还为智能应用提供了更加高效和创新的解决方案。本文将深入探讨Web3与A…

深入理解HTTP连接池及其在Java中的应用

更多内容前往个人网站:孔乙己大叔 在现代的Web开发中,HTTP请求已经成为应用程序与外部服务交互的主要方式。随着微服务架构的流行,一个应用可能需要同时与多个外部服务进行通信,这导致HTTP请求的数量显著增加。为了提升性能和资源…

微信小程序垃圾回收的前景方向

在当今这个环保意识日渐增强的时代,如何有效处理日常生活产生的垃圾已成为亟待解决的社会问题。微信小程序凭借其便捷性和广泛的用户基础,在推广垃圾分类与回收方面展现出巨大潜力。作为一款集智能化分类指导、在线预约回收、环保知识普及于一体的微信小…

使用JavaScript读取手机联系人列表:从理论到实践

更多内容前往个人网站:孔乙己大叔 在现代Web开发中,随着技术的不断进步,以前看似不可能的任务现在变得可行。例如,使用JavaScript读取手机联系人列表这一功能,在几年前几乎是不可想象的,但现在随着Web API的…

SQL 五十周年:何去何从?

原文地址 https://www.infoworld.com/article/2337457/sql-at-50-whats-next-for-the-structured-query-language.html SQL 即使被生成式 AI 隐藏在幕后,也将继续在数据交互和使用方面发挥关键作用。 CREDIT: PAVEL L PHOTO AND VIDEO / SHUTTERSTOCK 1974 年 5 月…

SQL进阶技巧:如何取时间序列最新完成状态的前一个状态并将完成状态的过程进行合并?

目录 0 问题描述 1 数据准备 2 问题分析 问题1:取最新完成状态的前一个状态 方法1:分析函数求解 方法2:关联求解 问题2:如何将完成状态的过程合并 方法1:分析函数作为辅助变量 方法2:自关联形式获取全量结果集 3 小结 0 问题描述 表status 字段及内容如下:…