用于预测事件顺序的机器学习algorithm?

简单的机器学习问题。 可能有很多方法来解决这个问题:

有4个可能的事件的无限stream:

'event_1', 'event_2', 'event_4', 'event_4'

事件不是以完全随机的顺序进来的。 我们将假设大多数事件的顺序都有一些复杂的模式,其余事件都是随机的。 我们不知道提前模式。

在收到每个事件之后,我想根据事件发生的顺序来预测下一个事件。 所以我的问题是: 什么机器学习algorithm应该用于这个预测?

然后告诉预测者下一个事件实际上是什么:

 Predictor=new_predictor() prev_event=False while True: event=get_event() if prev_event is not False: Predictor.last_event_was(prev_event) predicted_event=Predictor.predict_next_event(event) 

问题出现在预测者应该维持多久的历史,因为保持无限的历史将是不可能的。 我会留给你回答。 答案虽然是实用的,但是不能被解释。

所以我相信这个预言必须用某种滚动历史来完成。 因此,添加新事件并过期旧事件应该是相当有效的,并且不要求重build整个预测器模型。

具体的代码,而不是研究论文,将增加我的巨大的价值 ,你的回应。 Python或C库很好,但任何事情都可以。

更新:如果每轮都能同时发生多个事件,那该怎么办? 这是否改变了解决scheme?

这本质上是一个序列预测问题,所以你需要Recurrentneural network或隐马尔可夫模型。

如果你只有一个固定的时间回顾,时间窗口方法就足够了。 你把序列数据分成长度为n的重叠窗口。 (例如,将ABCDEFG序列分为ABC,BCD,CDE,DEF,EFG)。 然后你训练一个函数逼近器(例如neural network或线性回归),将该窗口的前n-1个部分映射到第n个部分。

你的预测器将无法回顾时间超过你的窗口的大小。 RNN和HMM可以在理论上这样做,但是很难调整或者有时候不起作用。

(最先进的RNN实现可以在PyBrain http://pybrain.orgfind);

更新:这是您的问题的pybrain代码。 (我没有testing过,可能会有一些错别字和东西,但总体结构应该可以工作。)

 from pybrain.datasets import SequentialDataSet from pybrain.supervised.trainers import BackpropTrainer from pybrain.tools.shortcuts import buildNetwork from pybrain.structure import SigmoidLayer INPUTS = 4 HIDDEN = 10 OUTPUTS = 4 net = buildNetwork(INPUTS, HIDDEN, OUTPUTS, hiddenclass=LSTMLayer, outclass=SigmoidLayer, recurrent=True) ds = SequentialDataSet(INPUTS, OUTPUTS) # your_sequences is a list of lists of tuples which each are a bitmask # indicating the event (so 1.0 at position i if event i happens, 0.0 otherwise) for sequence in your_sequences: for (inpt, target) in zip(sequence, sequence[1:]): ds.newSequence() ds.appendLinked(inpt, target) net.randomize() trainer = BackpropTrainer(net, ds, learningrate=0.05, momentum=0.99) for _ in range(1000): print trainer.train() 

这将训练1000个周期的经常性networking,并在每个时期后打印出错误。 之后,你可以检查这样的正确的预测:

 net.reset() for i in sequence: next_item = net.activate(i) > 0.5 print next_item 

这将为每个事件打印一组布尔值。

与其保持完整的历史logging,不如保留关于过去的汇总信息 (以及相对较短的滑动历史logging,作为预测器逻辑的input)。

暂时的实施可能是这样的:
简而言之: pipe理一系列递增顺序的马尔可夫链,并对他们的预测进行评分平均

  • 保留个人事件计数表,目的是计算4个不同事件中的任何事件的概率,而不考虑任何序列。
  • 保留一个双精度表的计数表,即累计计数观察到的事件[到目前为止]
    表开始是空的,在第二个事件观察的时候,我们可以存储第一个二元组,计数为1. upond第三个事件,由第二个和第三个事件组成的二元组“加”到表中:或者增加作为一个新的(从未见过的)二元论,现有的二元论或增加了原来的数1。 等等
    同时,在表格中保留两列的总数。
    这个表格和总计可以根据前一个事件计算给定事件的概率。
  • 以类似的方式,保留一个三元组的计数表,并观察总三元组的运行情况(注意,这将等于二元组的数量减一,因为第一个三元组在第一个二元组之后添加了一个事件,之后每个新事件都添加一个)。 这个三字节表允许基于前面两个事件来计算给定事件的概率。
  • 同样,保留N-gram的表格,例如10克(algorithm会告诉我们是否需要增加或减less)。
  • 保持滑动窗口进入最后的10个事件。
  • 上表提供了预测的基础。 总体思路是:
    • 使用表示下一个事件的概率作为基于不同的N-gram的各个概率的加权平均的公式。
    • 通过增加公式中的相应权重来奖励更好的个体N-gram长度; 以相反的方式惩罚更糟的长度。 (注意个体事件的边际概率需要考虑,以免我们倾向于预测最频繁事件的N-gram,而不pipe与它们相关的预测值相对较差)
    • 一旦系统“看到”了足够多的事件,就可以看到与长N-gram有关的权重的当前值,如果这些值相对较高,可以考虑添加表来保留有关更大N-gram的总计信息。 (不幸的是,这在空间和时间上都会伤害到algorightm)

上述通用逻辑可以有多种变化 。 特别是在select用于“评级”单个N-Gram长度的预测质量的特定度量时。
检测和适应事件分布可能发生的变化方面,应该考虑其他因素(上面假定一个通常的遍历事件源)。 一种可能的方法是使用两组表格(结合相应的概率),并周期性地删除其中一组的所有表格的内容。 为这些重置select正确的时间是一件棘手的事情,基本上平衡了统计上显着的历史数量的需要,并且需要足够短的时间以免我错过较短的调制。

问题出现在预测指标应保持多久的历史

唯一的答案是“这取决于”。

这取决于这需要多准确。 即使有无限的历史,我也不相信这个策略是完全准确的。 尝试10的历史,你会得到X%的准确性,然后尝试100,你会得到Y%的准确性,等等等等…

最终你会发现系统的精确度与你所期望的相当,或者你会发现精度的提高不值得历史长度的增加(以及增加内存使用,处理时间等)。 在这一点上,要么完成任务,要么你需要find一个新的策略。

对于我认为寻求一个简单的“软”neural network可能是一个更好的计划是值得的。

我们刚刚研究了计算机体系结构中的分支预测器 (因为如果(expression式)处理器花费太长时间来实际评估条件,它试图“猜测”并且以这种方式节省一些时间)。 我相信在这个领域已经做了更多的研究,但是现在我只能想到了。

我还没有看到像你这样的独特设置,所以我想你可能需要自己做一些初步的实验。 尝试运行您的解决schemeX秒的历史loggingN槽,正确率是多less? 并将其与固定的X和不同的N个历史槽进行比较,试图find最佳的记忆 – 历史比率(绘制出来)。

如果不止一个事件可以同时发生……这是一个小小的弯曲,那么在那里必须有一些限制:如果一次发生无数的事件会发生什么? Uhoh,这在你的计算上是不可能的。 我一次只尝试一个事件的方法,除了启用预测器的地方一次预测多个事件。

处理器使用一些真正轻量级的技巧来预测分支语句是否会分支。 这有助于他们高效的pipe道衬里。 他们可能不像马尔可夫模型一般,但他们很有趣,因为他们的简单性。 这里是关于分支预测的维基百科文章 。 参见饱和计数器两级自适应预测器