如何优化时间相关的隐藏函数——神奇的糖果机

数据挖掘 回归 优化 游戏
2022-02-10 12:08:26

假设我们有这个神奇的糖果机,它以糖果为输入,并再次提供糖果作为输出。

  1. 对于任何给定的时间 t,它会选择一个随机函数,该函数严格增加到一个点,例如 f(2) = 6,然后严格减小。它喜欢挑战,但如果你变得贪婪,它会像生活中的大多数事情一样惩罚你。

    f(1) = 5

    f(2) = 6

    f(3) = 4

    f(4) = 2

    f(100) = 0

  2. 棘手的一点是,这个函数一直在变化,但仍然与时间高度相关。所以 f() 在 t(1) 和 t(2) 之间是相似的,但在 t(1) 和 t(100) 之间非常不同。

我想编写一个程序来使用这个神奇的糖果机最大化我的糖果。我知道 ML 的基础知识,但我不确定哪种方法最适合这里。有任何想法吗?

注意:您每分钟只能玩一次。

2个回答

这听起来像是随机优化算法的一个用例:由于您的奖励函数没有被观察到但在时间上高度相关,我希望随机优化算法能够快速收敛到奖励函数的最大值,并在它缓慢变化时密切跟踪它。

正因为如此,我希望您可以使用简单的随机优化算法获得相当不错的结果,而无需使用诸如强化学习之类的复杂模型。此外,轻松开始总是好的。

注意:随机优化算法能否收敛到奖励函数的最大值取决于奖励函数变化的快慢。


编辑,例如请求后:

我将从Random Search开始。基本上这个想法是

  1. 随机选择一个位置
  2. 随机选择一个新位置
  3. 选择奖励最高的位置
  4. 重复步骤 2-3

诀窍在于生成好的候选点(第 2 步),以加速收敛到最大值。我有一些基本的想法可以提供帮助:

  1. 通过从均值等于当前位置和标准差以某种方式与当前奖励成反比的随机分布(例如高斯)中抽取来选择随机位置Ft(就像是αe(βFt)) 这样,如果我们接近奖励函数的最大值,我们就会选择一个靠近当前位置的新候选者,如果我们的奖励较低,我们可以探索离当前位置更远的地方。这两种策略通常被称为“开发”和“探索”

  2. 上面的想法具有“无记忆”的缺点,这使得它不考虑梯度。事实上,从高斯分布中绘制可以使您更接近或远离最大值,机会均等,即围绕均值的高斯对称。一种可能的解决方法是从偏态正态分布中绘制新的随机候选位置,偏态参数在某种程度上取决于上一步的奖励函数梯度的符号。

我认为在您的情况下,您不需要太多更高级的算法,因为-如果我理解正确-您的奖励函数不是多模式的,因此我们不会冒险陷入局部最大值。

想法#1

根据您给出的简短描述,并假设您有一些数据(或可以合成它),我会尝试训练一个隐马尔可夫模型。在这里查看一个很棒的视觉入门直观地说,HMM 会按照您的描述进行操作。

有一些可观察的:

  1. 你在机器里放了多少糖果,
  2. 多少出来,和
  3. 我们在哪个时间步

有某些状态(这里只是离散状态):

  1. 分发的糖果数量增加(严格增加)
  2. 分发的糖果量减少(严格减少)

最后,有一个转换:在这些状态之间,给定输入。就您而言,这些是可观察的。

然而,对于 HMM,我们假设有更多的东西。有一些隐藏状态(潜在状态)是无法观察到的。该模型跟踪这些并将它们与上面的 observables 列表结合使用来决定如何行动——它具有完整的映射功能。下面是这样一个模型的示意图:

在此处输入图像描述

这仅显示了几个状态,以及转换到其他状态或处于相同状态的概率。查看源代码以获取图表的详细说明。人们已经可以想象为您的问题绘制这张图。

有关 HMM 理论的更多信息,我推荐Jeff Bilmes 的这个基于文本的演练,以及mathmonk的这个 YouTube 系列(播放列表的第 14 章)如果你走这条路,你可能会考虑尝试Pomegranate library (in Python)

决定做什么、采取什么行动的最终逻辑是您可以硬编码或使用模型为您执行的操作。例如,硬编码方法类似于:

if current_state == 'normal':
    take_lots_of_candy()
elif current_state == 'unsure':
    take_some_candy()
elif current_State == 'dangerous':
    pause_taking_candy()
else:
    catch_other_states()

对于基于模型的方法,您可以进一步扩展下面概述的想法。


想法#2

当然,您本质上只是将一些输入映射到一些输出。几乎任何机器学习算法都会有很好的表现——取决于你的魔法机器内部工作的复杂性——会更好或更差。诸如提升(例如通过梯度下降)之类的算法通常需要您将某种信息放入模型中,例如通过指定回归方程,将输入映射到输出。一个好的实现是R中的mboost一个很棒的教程可以帮助决定什么可能是重要的。


想法#3

回到仅将输入映射到输出的问题:来自 Scikit-Learn 的简单多层感知器 (MLP) - 也称为前馈神经网络 - 从理论上讲,它应该能够灵活地逼近您可能抛出的任何函数(使用几个假设)。如果您的MLP不能满足要求,您也可以使用各种深度学习框架之一来实现这一点


最后的想法

最后我想强调的是,您的最终模型可能只会与您提供的数据一样好,并且虽然它可能在您的合成训练数据上运行良好,但不能保证泛化,无需更多考虑具体问题以及从中采样数据的特定分布。

如果您采用马尔可夫模型的方式,那么您也许可以将它们的状态预测用作进一步模型的输入;从而创建一个合奏。

如果您想真正了解序列分析中当前最先进的模型,您可以冒险进入循环神经网络的世界,例如利用 LSTM 单元,它保持内部状态表示,包括新信息和选择性地丢弃旧信息。这可能是在一个大型模型中考虑所有观点的好方法。这里的问题是,您通常需要大量数据来训练这样的模型。