简单的机器学习问题。可能有很多方法可以解决这个问题:
有4个可能事件的无限流:
'event_1', 'event_2', 'event_4', 'event_4'
事件不是以完全随机的顺序进入的。我们假设大多数事件都有一些复杂的模式,其余的事件只是随机的。我们提前不知道这些模式。
收到每个事件后,我想根据事件过去的顺序预测下一个事件的内容。所以我的问题是:我应该为这个预测器使用什么机器学习算法?
然后会告诉预测器实际上是下一个事件:
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)
问题在于预测者应该保持多长时间的历史,因为保持无限的历史是不可能的。我会把这个留给你回答。但实际上,答案不可能是无足轻重的。
所以我相信预测必须在某种滚动的历史中完成。因此,添加新事件并使旧事件过期应该相当有效,并且不需要重建整个预测模型,例如。
特定代码,而不是研究论文,会为您的回复添加巨大的价值。 Python或C库很不错,但任何事情都可以。
更新:如果在每轮中同时发生多个事件,该怎么办?这会改变解决方案吗?
答案 0 :(得分:22)
这本质上是一个序列预测问题,因此您需要递归神经网络或隐马尔可夫模型。
如果您只有固定的时间回顾,时间窗口方法可能就足够了。您获取序列数据并将其拆分为长度为n的重叠窗口。 (例如,您将序列ABCDEFG分成ABC,BCD,CDE,DEF,EFG)。然后训练函数逼近器(例如神经网络或线性回归)将该窗口的前n-1个部分映射到第n个部分。
您的预测器无法及时回顾超过窗口大小的时间。 RNN和HMM可以在理论上这样做,但很难调整,有时甚至不起作用。
(最先进的RNN实现可以在PyBrain中找到http://pybrain.org)
更新:这是您的问题的pybrain代码。 (我没有测试它,可能会有一些拼写错误和东西,但整体结构应该有用。)
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个纪元,并在每个纪元后打印出错误。之后你可以检查这样的正确预测:
net.reset()
for i in sequence:
next_item = net.activate(i) > 0.5
print next_item
这将为每个事件打印一系列布尔值。
答案 1 :(得分:11)
不是保留完整的历史记录,而是可以保留关于过去的 聚合信息 (以及相对较短的滑动历史记录,以用作Predictor逻辑的输入) )。
暂时的实施可能是这样的:上述一般逻辑可能存在几种变体。特别是在用于“评定”各个N-Gram长度的预测质量的特定度量的选择中。
关于检测和适应事件分布中可能的变化(上面假设一般为遍历事件源),应该考虑其他因素。一种可能的方法是使用两组表(相应地组合概率),并周期性地丢弃其中一组的所有表的内容。为这些重置选择正确的时间段是一件棘手的事情,基本上平衡了对统计上显着的历史数量的需求以及对足够短的时间的需求,以免错过较短的调制...
答案 2 :(得分:0)
问题在于预测者应该保持多长时间的历史
唯一的答案是“它取决于”。
这取决于这需要多么准确。即使有无限的历史,我也不相信这种策略可以100%准确。尝试10的历史,你会得到x%的准确度,然后尝试100,你会得到y%准确度等等...
最终你应该发现系统和你想要的一样准确,或者你会发现准确度的提高不值得历史长度的增加(以及增加的内存使用,处理时间等......)。此时要么已完成工作,要么需要找到新策略。
对于它的价值,我认为研究一个简单的“软”神经网络可能是一个更好的计划。
答案 3 :(得分:0)
我们刚刚研究了计算机体系结构中的branch-predictors(因为处理器需要很长时间来实际评估条件,如果(表达式),它会尝试“猜测”并节省一些时间)。我相信在这方面已经做了更多的研究,但这是我现在所能想到的。
我没有看到像您这样的独特设置,所以我认为您可能需要自己做一些初步实验。尝试使用N个插槽的历史记录运行解决方案X秒,正确率是多少?并将其与相同的固定X和不同的N个历史时段进行比较,以尝试找到最佳的内存历史比率(将其绘制出来)。
如果不止一个事件同时发生......这有点弯曲,那里必须有一些约束:如果一次发生无数次事件怎么办?呃,这对你来说在计算上是不可能的。我尝试的方法与一次只有一个事件相同,除非启用预测器一次预测多个事件。
答案 4 :(得分:0)
处理器使用一些非常轻量级的技巧来预测分支语句是否会分支。这有助于他们高效的管道衬里。例如,它们可能不像马尔可夫模型那样通用,但由于它们的简单性,它们很有趣。 Here is the Wikipedia article on branch prediction。请参阅饱和计数器和两级自适应预测器