机器学习如何改进工业中的因果推理?我用零售定价代码描述了一个真实的例子。
因果推理是机器学习中的一个热门话题,有许多关于因果推理理论的优秀入门书。但是,机器学习驱动的因果推理在现实世界中的应用实例要少得多。本文介绍了一个来自行业背景的此类示例,使用的是(公共)真实世界数据集。它面向了解因果关系基础知识的技术受众。
具体来说,我将研究价格弹性估计的“理想”场景。这种情况与希望优化价格的零售商高度相关,例如为了更好地管理库存或只是为了提高竞争力。
第1节将提出问题并提供简要背景。这也将说明更普遍的观点,即估计因果效应需要在“只是”数据分析之上的领域专业知识。第2节将解释由于混淆,从历史数据中学习是很困难的。第3节将概述针对此问题的机器学习驱动的解决方案。第4节的代码示例中对此进行了详细说明。需要代码notebook的可私信。最后,我将讨论这种因果有效估计的业务相关性。1.为什么要关心弹性?
大多数经济学概念课程的核心概念“需求价格弹性”描述了给定产品的价格敏感需求。如果产品“更具弹性”,价格上涨将导致更大的需求减少。作为一个因果概念,弹性允许我们量化如果我们将价格降低5%,我们可以销售多少单位?
弹性作为价格和需求量之间的效应描述了一个复杂的因果系统:价格当然不会直接影响需求,而是通过许多个人消费者决定购买或不购买以及次要效应(例如特价商品)来调节。在尝试估计弹性时,零售商会跳过所有这些复杂性,直接衡量他们控制的事物(价格)对他们关心的事物(需求)的影响。
因此,实际上可以估计弹性是有些令人惊讶的。但自从年正式定义以来,经济学家发现需求的价格弹性在许多情况下是对现实的恰当近似。这种近似在其相对变化的规范定义中特别方便:在给定价格(p)的百分比,弹性衡量需求量(q)的百分比变化:
这里的直觉很简单:与售价美元的产品相比,售价5美元的产品价格变化1美元会导致需求的剧烈变化。总的来说,消费者关心“相对”的变化。根据经验,这个定义很方便,因为它意味着要估计的参数θ随着p的变化保持近似恒定。
有了对θ的有效估计,零售商现在可以对他们的价格进行反事实推理:“如果我将产品的价格提高5%,我可以期望多售出5θ%的单位”(θ通常为负值)。
为了更直觉地表示,假设他们目前以5美元的价格和4美元的成本出售个单位。那么他们目前赚取*(5–4)=美元的利润。假设他们估计弹性为θ=-3,即他们预计价格上涨5%(从5美元到5.25美元)会导致需求减少15%(从到85)。那么新的利润会略有增加,85*(5.25–4)=$。但是,如果他们将价格降低5%,他们将损失利润:*(4.75–4)=86美元。请注意,更高的价格并不总是会带来更高的利润:例如,如果单位成本仅为3美元:价格上涨5%会减少利润,从*(5-3)=美元到85*(5.25-3)=美元。
你可能会说服自己,不同的弹性值会改变最优价格:一般来说,需求弹性越大(例如,如果θ=-5而不是-3),成本和价格之间的加价应该越低。
能够做出这样的反事实陈述,通过给出是否应该提高或降低价格的指示,为零售商节省了很多“尝试新价格”的时间。当然,例如,当零售商希望管理其库存以在季节结束前销售所有库存时,对弹性的良好估计会提供额外的价值。简而言之,高度准确的弹性估计为零售商提供了个人购买决策复杂因果系统的简明摘要,从而允许对其预期结果充满信心的业务决策。
这篇对基本需求经济理论的简短介绍是因果推理专家知识的一个例子:有关数据生成过程的知识告知要回答的问题类型、需要注意的机制,并且通常作为求和的函数形式。从数据中学习所有这些结构是很困难的——当然数据效率低下。
2.迎接挑战
在了解为什么零售商想要估计弹性的入门之后,本节将描述为什么这会导致一个有趣的问题。
当然,因果推断的首选方法是(随机)实验:零售商可能会花一些时间随机上下调整产品价格(或者更好的是,随机化用户的价格)。但是这样的实验是昂贵的,因为产品以次优的价格出售,客户体验受到影响。更糟糕的是,零售数据中的信噪比通常很低,因为大多数商店提供大量产品,其中很大一部分在任何给定时间范围内都不会销售。因此,在销售出足够多的产品以进行推理之前,实验需要运行很长时间。最后,例如,零售商可能会担心短期实验可能无法跨季节推广。
因此,从观测数据中学习因果有效弹性的能力是关键;这个例子中的观察数据只是零售商的价格和销售单位的历史记录。但是由于混杂因素,很难从观察数据中估计因果关系。要了解这意味着什么,请考虑(1)产品质量和(2)季节作为许多潜在混杂因素的两个重要示例:
1MacBook比Chromebook贵。假设零售商销售的MacBook比Chromebook多(除此之外别无其他),观察数据表明高价格与高销量相关。但是(与事实相反)期望将Chromebook的价格提高到Apple的水平将允许销售更多的Chromebook,这将是愚蠢的。
2许多产品的需求是季节性的,例如由于假期(圣诞节)和天气变化(夏季)。通常情况下,旺季价格较高(但销售的产品很多),而淡季价格较低(销售较少的产品);然而,尽管存在这种相关性,但期望将淡季价格提高到旺季水平会增加销售额是愚蠢的。
通常来讲,零售商必须注意不要混淆相关性和因果关系。以下因果图代表了一个简单的混杂关系:未能控制产品质量(以及季节等,未显示)将显着偏差θ的估计。这种偏见会导致零售商对最优价格得出错误的结论,直接损害他们的业务。
价格和数量之间的最小(即不完整)因果图,产品质量只是混杂因素。
顺便说一句:价格弹性是计量经济学中称为“同时方程模型”的问题的一个实例——核心见解是价格实际上是由供应方和需求方的同时决策决定的。在这个例子中,零售商相信他们有足够的关于他们自己的定价决策的数据来区分市场对价格变化的反应的一致估计。
知道正确控制所有可用混杂因素的重要性,零售商现在转向机器学习驱动的因果推理。
3.双机器学习,或控制可观察对象2.0
我在这里描述的解决方案主要解决两个问题:首先,正则化从大量潜在的混杂因素中挑选出合适的控制。其次,由于我使用的是灵活的机器学习算法,控制变量的函数形式和交互(即它们的预处理)比在传统回归方法中更重要,在传统回归方法中,使用普通线性回归来控制混杂因素。当然,仍然需要大量思考来寻找可能是混杂因素的变量——以及应该避免哪些变量,因为它们可能会引入“对撞机偏差”,而这种方法也不能幸免。
我的解决方案实现了双重机器学习(DML)。主要思想相对直观:给定一些观察到的潜在混杂因素,我使用非参数、灵活的估计器(机器学习模型)来有效地控制各种功能形式和交互效果。换句话说,我用ML模型近似了数据生成过程中的实际混淆机制。
为此,我训练了两个独立的“辅助”模型来分别预测治疗(价格,P)和结果(需求量,Q)。这两个模型都使用一组X的潜在混杂变量(例如产品质量和季节)独立训练,因此它们的预测接近预期值E[P
X]和E[Q
X]。
使用这些预测,然后我将通过一组控制变量可预测的治疗和效果的部分残差:
在我下面的安装启用中,我选择RandomForests来估计条件期望,选择它们是因为它们的稳健性能。你可以想到这两个辅助作为“控制模型”的iary模型:如果X包含有关相关混杂因素的足够信息,并且如果至少有一个模型“拟合得很好”,那么通过构造P和Q现在是“无混杂的”,只有真正的因果关系仍然存在(有关这方面有很多文献)。
所以在残差之后,我对
这个数量仍然难以估计,但幸运的是,计量经济学中有一种估计弹性的标准方法:对数-对数回归。θ完全等同于以下回归模型中的参数:
具体如何工作超出了本文的范围。重要的一点是,在现实中,我将(线性地)对残差对数价格回归残差对数数量以获得θ。
在下面的分箱散点图中,我展示了在我的样本数据集中仅取对数数量和对数价格之间的相关性的“天真”结果:即使在控制混杂因素(例如季节或产品质量)之前,这种关系似乎也有些线性。弹性θ是这条线的斜率。正如你将看到的,控制混杂因素会显着改变(改进)估计。
数据清理后的朴素相关分析中,可视化分箱散点图可以观察到对数数量和对数价格之间的(某种程度上)线性关系
现在,把方法放在一起:
我会记录p和q的对数。我将构建一组潜在的混杂因素X。我将训练一个辅助RandomForest模型从X预测log(p)。我将训练一个单独的辅助RandomForest模型来根据X预测log(q)。
如果你密切
接下来,对于实际推理,我将使用线性回归模型。如上所述,这将估计log-log-regression的斜率θ。
最初的DML论文为这种回归提出了一个与OLS略有不同的估计器,以实现更好的鲁棒性:而不是采用标准的OLS解决方案,
Q~θP+截距的标准OLS解
他们使用以下去偏估计器。请注意,第一个P是残差的,而第二个不是,第三个是:
去偏回归估计器
在下面的代码片段中,我实现了上述步骤(1)到(6):将数据分成两半,在前半部分训练辅助模型,对后半部分进行残差,并推断弹性。重复交换两半后,我取两个估计的平均值,以获得可靠的因果估计(假设我能够捕获相关的混杂因素)。
fromsklearn.model_selectionimportKFold #SinceQmightbe0,cantjusttakelogs.Thisisaquick #workaroundfordemonstration.Betteroptionsexist. df_mdl[LnP]=np.log1p(df_mdl[P]) df_mdl[LnQ]=np.log1p(df_mdl[Q]) elast_estimates=list() #Step1:splitintotwohalves foridx_aux,idx_infinKFold( n_splits=2,shuffle=True).split(df_mdl): df_aux=df_mdl.iloc[idx_aux] df_inf=df_mdl.iloc[idx_inf].copy() #Step2+3:fitauxiliarymodelsonfirsthalf model_q.fit(df_aux,df_aux[LnQ]) model_p.fit(df_aux,df_aux[LnP]) #Step4:residualizeinsecondhalf df_inf=df_inf.assign( LnP_res=df_inf[LnP]-model_p.predict(df_inf), LnQ_res=df_inf[LnQ]-model_q.predict(df_inf), ) #Step5:DMLinference elast=( df_inf[LnP_res].dot(df_inf[LnQ_res]) / df_inf[LnP_res].dot(df_inf[LnP]) #thelastpartheredeviatesfromstandardOLSsolution ) print(DMLelasticity:,elast) elast_estimates.append(elast) print(OLSelasticityfor
这就是我们的双重稳健的,ml控制的需求价格弹性估计。即价格对售出数量的平均处理效果。在一个行业环境中,零售商现在可以尝试用小实验(即随机价格变化)来验证这个估计。
这个最终结果在下面的分类散点图中显示:
DML结果的可视化显示,控制混杂因素减少了治疗变量中的“噪声”变化,并改变了效果大小。
在图中,您可以看到蓝色的“幼稚”方法。这只是简单地绘制对数量与对数价格的关系图,没有控制混杂因素(即混淆相关性和因果关系)。即使这种关系是“混乱的”,但你已经可以看到一个负斜率:更高的价格导致更低的需求。这里的回归参数约为θ≈0.6。
橙色线是DML结果的可视化,已经控制了潜在的混杂因素。请注意,斜率变得更陡,表明需求更具弹性(θ≈1.9)。您还可以观察到,这种关系已经显著地变得不那么嘈杂了,您可以看到价格的差异(x轴上的线的范围)急剧地减少了,这是由于DML残值化“解释掉”了大部分这种变化的结果。
5.讨论
与开头的示例类似,假设零售商目前以5美元的价格销售件产品,成本为2美元。估计弹性为-1.9,零售商应该降低价格以获得更多利润。但是如果(有偏见的,天真的)估计为-0.6,他们就会提高价格。
在这个例子中,适当的因果推理会颠倒推荐决策,直接影响零售商的利润。混淆相关性和因果关系会让零售商付出实实在在的代价。相反,使用精心设计的DML机制,零售商能够在价格变化发生之前自信地预测其影响。
本文旨在解释一个端到端的行业应用程序。你可以在可运行的笔记本上更详细地遵循每一步。许多业务问题都受益于类似的方法,我希望这是一个有用的例子。
为了进一步优化价格,零售商现在可能转向异质处理效果,即探索弹性的差异。这也引出了一个问题:我实际估计的“平均治疗效果”是什么,我的训练数据中的产品组合是否代表了未来的产品组合。我将在后续文章中探讨各种影响。