Press "Enter" to skip to content

动态定价与多臂赌博机:通过实践学习

应用强化学习策略到现实世界的使用案例,尤其是动态定价,可能会揭示许多意外

![Photo by Markus Spiske on Unsplash](https://miro.medium.com/v2/resize:fit:640/0*PtB_85QrbCPNJXXb)

动态定价、强化学习和多臂赌博机

在庞大的决策问题世界中,有一个困境特别适合强化学习策略:探索与开发。想象一下走进一个有一排老虎机(也称为“单臂赌博机”)的赌场,每台机器都有不同的、未知的奖励。你是要探索并玩每台机器,找出哪台机器的奖金最高,还是坚持其中一台机器,希望它是大奖?这个比喻的情景构成了多臂赌博机(MAB)问题的基础。目标是找到一种策略,能够在一系列游戏中最大化奖励。探索提供新的见解,而开发则利用你已经拥有的信息。

现在,将这个原则转移到零售场景中的动态定价。假设你是一家电子商务商店的店主,有一种新产品。你不确定它的最佳销售价格应该是多少。你该如何设置一个最大化收入的价格?你应该尝试不同的价格来了解顾客的支付意愿,还是应该利用历史上表现良好的价格?动态定价本质上就是一个伪装的多臂赌博机问题。在每个时间步骤,每个候选价格点都可以看作是一个老虎机的“臂”,而从该价格产生的收入则是其“奖励”。另一种看待这个问题的方法是,动态定价的目标是迅速而准确地测量顾客群体对不同价格点的需求反应。简单地说,目标是找到最能反映顾客行为的需求曲线。

在本文中,我们将探索四种多臂赌博机算法,评估它们对一个明确定义(尽管并不直观)的需求曲线的有效性。然后,我们将剖析每种算法的主要优势和局限,并深入研究衡量它们性能的关键指标。

建模需求曲线

传统上,经济学中的需求曲线描述了产品价格与消费者愿意购买的产品数量之间的关系。它们通常呈下降趋势,代表了一个常见的观察结果:随着价格上涨,需求通常下降,反之亦然。想想智能手机或音乐会门票这样的热门产品。如果价格降低,更多的人倾向于购买,但如果价格飙升,即使是忠实的粉丝也可能三思而后行。

然而在我们的背景下,我们将稍微不同地对待需求曲线:我们将价格与概率对比。为什么?因为在动态定价的场景中,特别是数字商品或服务,用给定价格出售的可能性来思考比精确数量更有意义。在这种环境中,每次定价尝试都可以看作是对成功(或购买)概率的探索,这可以很容易地建模为一个依赖于给定测试价格的伯努利随机变量。

这里特别有趣的是:直觉上,人们可能认为我们的多臂赌博机算法的任务是找到那个概率最高的购买概率的理想价格,但事实并不是这么简单。事实上,我们的最终目标是最大化收入(或利润)。这意味着我们不是寻找能够让最多人点击“购买”的价格——我们在寻找的是,当乘以与之相关的购买概率时,能够给出最高预期回报的价格。想象一下设置一个价格很高,很少有人购买,但每一次销售都能产生巨大的收入。另一方面,一个非常低的价格可能吸引更多的买家,但总收入可能仍然低于高价情况。因此,在我们的背景中,谈论“需求曲线”有些不寻常,因为我们的目标曲线主要代表的是购买的概率,而不是直接的需求。

现在,进入到数学中,让我们从说消费者行为开始,特别是在涉及价格敏感性时,不总是线性的。线性模型可能会暗示,对于价格的每一次递增,需求会有一个恒定的减少。但实际上,这种关系通常更复杂和非线性。一种模拟这种行为的方法是使用逻辑函数,它可以更有效地捕捉到这种微妙的关系。我们选择的需求曲线模型是:

动态定价与多臂赌博机:通过实践学习 四海 第1张

在这里,a代表购买的最大可实现概率,而b调节需求曲线对价格变化的敏感性。b值越高,曲线越陡峭,随着价格的增加,购买概率更快地接近较低的概率。

具有不同参数a和b组合的需求曲线的四个示例

对于给定的价格点,我们将能够获得相应的购买概率p。然后我们可以将p输入到伯努利随机变量生成器中,以模拟顾客对特定价格提案的反应。换句话说,给定一个价格,我们可以很容易地模拟我们的奖励函数。

接下来,我们可以将这个函数乘以价格,以获得给定价格点的预期收入:

动态定价与多臂赌博机:通过实践学习 四海 第3张

毫不奇怪,这个函数在与最高概率对应的地方并不达到最大值。而且,与最高值相关联的价格并不依赖于参数a的值,而最大预期收益则取决于参数a的值。

与相关最大值的预期收入曲线

通过一些微积分的回忆,我们还可以推导出导数的公式(您需要使用乘积规则和链式规则的组合)。这并不是一个轻松的练习,但也并不太具有挑战性。这是预期收入的导数的解析表达式:

动态定价与多臂赌博机:通过实践学习 四海 第5张

这个导数使我们能够找到使我们的预期收入曲线最大化的确切价格。换句话说,通过将这个特定公式与一些数值算法结合使用,我们可以轻松确定将其设置为0的价格。反过来,这就是最大化预期收入的价格。

这正是我们所需要的,因为通过固定a和b的值,我们将立即知道我们的赌徒将不得不找到的目标价格。在Python中编写这段代码只需要几行代码:

对于我们的用例,我们将设置a = 2和b = 0.042,这将给我们一个约为30.44的目标价格,与0.436的最佳概率相关联(→最佳平均奖励为30.44*0.436=13.26)。这个价格通常是未知的,它正是我们的多臂赌博算法将要寻找的价格。

多臂赌博策略

现在我们已经确定了我们的目标,是时候探索各种策略,以测试和分析它们的性能、优势和劣势。虽然MAB文献中存在多种算法,但在现实世界的情景中,四种主要策略(以及它们的变体)主要构成了骨干。在本节中,我们将简要介绍这些策略。我们假设读者对它们有基本的了解;然而,对于那些对它们更深入地探索感兴趣的人,文章末尾提供了参考资料。在介绍每个算法之后,我们还将呈现其Python实现。虽然每个算法都具有其独特的一组参数,但它们都共同使用一个关键输入:`arm_avg_reward`向量。这个向量表示从每个臂(或行动/价格)到当前时间步t为止获得的平均奖励。这个关键输入指导所有算法在做出关于随后的价格设置的明智决策时。

我将应用于我们的动态定价问题的算法如下:

贪婪算法:这个策略就像是总是回到最初几次玩时给你最多硬币的机器。在试过每台机器一段时间后,它会坚持选择看起来最好的那台。但可能会有一个问题。如果那台机器只是一开始运气好呢?贪婪策略可能错过更好的选择。但好消息是,代码实现非常简单:

区分初始情景(所有奖励为0时)和常规情景是至关重要的。通常,你会发现只有“else”部分被实现,即使在所有奖励都为0时也能正常工作。然而,这种方法可能会导致对第一个元素的偏见。如果你犯了这个错误,你可能会为此偏见付出代价,特别是如果最优奖励恰好与第一个臂相连(是的,我也有过这种经历)。贪婪方法通常是最低效的方法,我们将主要将其用作性能基准。

ϵ-贪婪:ε-贪婪(epsilon-贪婪)算法是对贪婪方法的一种修改,以解决其主要缺点。它引入了一个概率ε(epsilon),通常是一个小值,来选择一个随机臂,促进探索。以概率1−ε选择具有最高估计奖励的臂,倾向于利用。通过在随机探索和已知奖励的利用之间取得平衡,ε-贪婪策略旨在实现比纯粹的贪婪方法更好的长期回报。同样,实现是直接的,只需在贪婪代码之上添加一个额外的“if”语句。

UCB1(上置信界):UCB1策略就像一个好奇的探险者,试图在一个新城市找到最好的餐厅。虽然他们有一个喜欢的地方,但随着时间的推移,发现一个更好的地方的吸引力越来越大。在我们的背景下,UCB1将已知价格点的奖励与未经探索的价格点的不确定性相结合。在数学上,通过一个公式实现这种平衡:价格点的平均奖励加上一个基于上次尝试时间的“不确定性奖励”。这个奖励的计算方式如下:

动态定价与多臂赌博机:通过实践学习 四海 第6张

它代表了对未尝试价格的“不断增长的好奇心”。超参数C控制着利用和探索之间的平衡,C的值越高,鼓励对样本较少的臂进行更多的探索。通过始终选择已知奖励和好奇心奖励的综合值最高的价格,UCB1确保了在已知和未知之间的平衡,旨在发现最优价格以获得最大收益。我将从按照规范实现这种方法开始,但我们很快会发现需要稍作调整。

汤普森抽样:这种贝叶斯方法通过根据后验奖励分布以概率选择臂来解决探索-利用困境。当这些奖励遵循伯努利分布时,表示二元结果(如成功/失败),汤普森抽样(TS)使用Beta分布作为共轭先验(参见此表格以供参考)。对于每个臂,算法从一个非信息性的Beta(1,1)先验开始,根据观察到的奖励更新分布的参数:成功增加alpha参数,失败增加beta参数。在每次游戏中,TS从每个臂的当前Beta分布中抽取样本,并选择具有最高抽样值的臂。这种方法使TS能够根据收集到的奖励进行动态调整,巧妙地在不确定臂的探索和已知有回报臂的利用之间取得平衡。在我们具体的情景中,尽管基本奖励函数遵循伯努利分布(购买为1,未购买为0),但实际感兴趣的奖励是基本奖励与当前测试价格的乘积。因此,我们对TS的实现需要进行轻微修改(这也会引入一些意外)。

这个变化实际上非常简单:为了确定最有希望的下一个臂,从后验估计中提取的样本将与它们各自的价格点相乘(第3行)。这种修改确保决策基于预期的平均收入,将焦点从最高购买概率转移到其他方面。

我们如何评估结果?

此时,我们已经收集到了构建一个模拟的所有关键要素,以比较四种算法在我们的动态定价环境中的性能,我们必须问自己:我们将评估什么?我们选择的指标至关重要,因为它们将指导我们比较和改进算法的过程。在这个努力中,我将关注三个关键指标:

  1. 遗憾:这个指标衡量了选择的行动获得的奖励与通过采取最佳行动获得的奖励之间的差异。在数学上,时间t的遗憾由以下公式给出:遗憾(t)=最优奖励(t)−实际奖励(t)。遗憾在随时间累积时,提供了关于我们通过不总是选择最佳行动而“损失”了多少的见解。与累积奖励相比,它更能清楚地指示算法相对于最优情况的性能。理想情况下,遗憾值接近0表示决策接近最优。
  2. 反应性:这个指标衡量算法接近目标平均奖励的速度。本质上,它是算法适应性和学习效率的度量。算法能够快速实现期望的平均奖励,就越具有反应性,意味着更快地调整到最优价格点。在我们的情况下,目标奖励设定为最优平均奖励的95%,即13.26。然而,初始步骤可能会表现出较高的变异性。例如,幸运的早期选择可能导致从与高价格相关的低概率臂获得成功,快速达到阈值。由于这种波动,我选择了更严格的反应性定义:达到95%最优平均奖励十次所需的步骤数,不包括初始的100步。
  3. 臂分配:这表示每个算法随时间使用可用臂的频率。以百分比形式呈现,它揭示了算法选择每个臂的倾向。理想情况下,对于最有效的定价策略,我们希望算法将100%的选择分配给表现最好的臂,而将0%分配给其他臂。这样的分配将固有地导致遗憾值为0,表示最佳性能。

运行仿真

评估多臂老虎机算法面临挑战,因为其结果具有高度随机性。这意味着由于确定数量的内在随机性,结果在不同运行之间可能会有很大的差异。为了进行强大的评估,最有效的方法是多次执行目标仿真,累积每次仿真的结果和指标,然后计算平均值。

初始步骤涉及创建一个函数来模拟决策过程。该函数将实现下面图像中表示的反馈循环。

在仿真函数中实现的反馈循环

这是仿真循环的实现:

该函数的输入包括:

  • prices:我们希望测试的候选价格列表(实质上是我们的“臂”)。
  • nstep:仿真中的总步数。
  • strategy:我们旨在测试其对下一个价格做出决策的算法。

最后,我们需要编写外部循环的代码。对于每个目标策略,该循环将多次调用run_simulation,收集和汇总每次执行的结果,然后显示结果。

对于我们的分析,我们将使用以下配置参数:

  • prices:我们的价格候选项 → [20, 30, 40, 50, 60]
  • nstep:每次仿真的时间步数 → 10000
  • nepoch:仿真执行次数 → 1000

此外,通过设置我们的价格候选项,我们可以迅速获得相关的购买概率,它们大约为[0.60, 0.44, 0.31, 0.22, 0.15]。

结果

在运行仿真后,我们最终能够看到一些结果。让我们从累积遗憾的图开始:

动态定价与多臂赌博机:通过实践学习 四海 第8张

从图中可以看出,从平均累积遗憾的角度来看,TS是优胜者,但它需要大约7500步才能超过ε-greedy。另一方面,我们有一个明显的输家,即UCB1。在其基本配置下,它基本上与贪婪方法表现一致(稍后我们将回到这个问题)。让我们通过探索其他可用的指标来更好地理解结果。在所有四种情况下,反应性都显示出非常大的标准差,因此我们将关注中位数值而不是平均值,因为它们对异常值更加抵抗。

动态定价与多臂赌博机:通过实践学习 四海 第9张

从这些图中的初步观察可以得出结论,虽然从平均值上看,TS超过了ε-greedy,但从中位数上看,它略有落后。然而,它的标准差较小。特别有趣的是反应性条形图,它显示了TS在迅速达到有利的平均奖励方面的困难。起初,这对我来说是违反常理的,但在这种情况下,TS背后的机制澄清了问题。我们之前提到过,TS估计购买概率。然而,决策是基于这些概率和价格的乘积进行的。了解真实概率(即[0.60, 0.44, 0.31, 0.22, 0.15])使我们能够计算TS正在积极导航的预期收益:[12.06, 13.25, 12.56, 10.90, 8.93]。实质上,尽管基础概率有很大差异,但从TS的角度来看,预期收入值相对接近,特别是接近最佳价格。这意味着TS需要更长的时间来确定最佳臂。虽然TS仍然是表现最好的算法(如果延长仿真,其中位数最终会降低到低于ε-greedy),但在这种情况下,它需要更长的时间来确定最佳策略。下面,臂分配饼图显示了TS和ε-greedy在识别最佳臂(价格=30)方面表现出色,并在仿真过程中大部分时间使用它们。

动态定价与多臂赌博机:通过实践学习 四海 第10张

现在让我们回到UCB1。遗憾和反应性证实了它基本上是一个完全利用性的算法:迅速获得良好的平均奖励水平,但遗憾和结果的高变异性。如果我们看一下手臂分配,这一点更加明显。 UCB1只比贪婪方法聪明一些,因为它更注重具有更高预期奖励的3个手臂(价格为20、30和40)。然而,它基本上根本不探索。

进入超参数调整。很明显,我们需要确定平衡探索和利用的权重C的最佳值。第一步是修改UCB1代码。

在这个更新的代码中,我已经加入了在添加“不确定性奖励”之前对平均奖励进行归一化的选项,该选项由超参数C加权。这样做的理由是为了为最佳超参数(例如0.5-1.5)提供一致的搜索范围。如果没有这种归一化,我们可能会获得类似的结果,但是每次都需要根据处理的值范围进行调整。我将不再详细介绍如何找到最佳C值;它可以通过网格搜索轻松确定。结果发现最佳值是0.7。现在,让我们重新运行模拟并检查结果。

动态定价与多臂赌博机:通过实践学习 四海 第11张

这个情节转折很大,不是吗?现在,UCB1显然是最好的算法。即使在反应性方面,它只是与先前的分数相比轻微恶化。

动态定价与多臂赌博机:通过实践学习 四海 第12张

此外,从手臂分配的角度来看,UCB1现在是无可争议的领导者。

动态定价与多臂赌博机:通过实践学习 四海 第13张

得到的教训和下一步

  • 理论 vs. 经验:从基于书籍的学习开始是涉足新主题的基本第一步。然而,您越早地参与实践经验,您就越能将信息转化为知识。当将算法应用于实际用例时所遇到的细微差别和特殊情况将提供远超过您可能阅读的任何数据科学书籍的见解。
  • 了解您的度量标准和基准:如果您无法衡量您的工作,您就无法改进它。在开始任何实施之前,务必了解您打算使用的度量标准。如果我只考虑遗憾曲线,我可能会得出结论“UCB1不起作用”。通过评估其他指标,尤其是手臂分配,很明显算法根本没有足够的探索。
  • 没有一种大小适合所有的解决方案:虽然UCB1在我们的分析中脱颖而出,但这并不意味着它是您动态定价挑战的通用解决方案。在这种情况下,调整是直截了当的,因为我们知道我们寻求的最佳值。在现实生活中,情况从来都没有那么清晰明了。您是否拥有足够的领域知识或测试和调整UCB1算法的探索因子的方法?也许您会倾向于一种可靠有效的选择,比如ε-贪婪,它承诺立即获得结果。或者,您可能正在管理一个繁忙的电子商务平台,每小时展示产品10000次,并且您愿意耐心等待,相信汤普森抽样最终会获得最大的累积奖励。是的,生活并不容易。

最后,让我说一下,如果这个分析看起来令人生畏,那么不幸的是,它已经代表了一个非常简化的情况。在现实的动态定价中,价格和购买概率并不孤立存在-它们实际上存在于不断变化的环境中,并受到各种因素的影响。例如,购买概率在一年中保持一致,在所有客户人口统计数据和地区中都是高度不可能的。换句话说,为了优化定价决策,我们必须考虑我们客户的背景。这个问题将是我下一篇文章的重点,我将在其中通过整合客户信息并讨论情境强化学习方法来更深入地探讨这个问题。所以,请保持关注!

参考资料

  • https://www.amazon.it/Reinforcement-Learning-Introduction-Richard-Sutton/dp/0262039249
  • https://www.geeksforgeeks.org/epsilon-greedy-algorithm-in-reinforcement-learning/
  • https://towardsdatascience.com/multi-armed-bandits-upper-confidence-bound-algorithms-with-python-code-a977728f0e2d
  • https://towardsdatascience.com/thompson-sampling-fc28817eacb8
  • https://www.youtube.com/watch?v=e3L4VocZnnQ
  • https://www.youtube.com/watch?v=e3L4VocZnnQ
  • https://www.youtube.com/watch?v=Zgwfw3bzSmQ&t=2s

您喜欢这篇文章吗?如果您正在寻找人工智能、自然语言处理、机器学习和数据分析在解决现实问题中的应用,您也可能会喜欢我的其他作品。我的目标是创作出能够展示这些变革性技术在实际场景中应用的可行性的实用文章。如果您也是这样的人,请关注我在VoAGI上的最新作品!

Leave a Reply

Your email address will not be published. Required fields are marked *