我怎么能找到下一个值?

时间:2016-08-06 15:26:14

标签: algorithm machine-learning

给定一个0和1的数组,例如array[] = {0, 1, 0, 0, 0, 1, ...},如何以最佳准确度预测下一个值是什么?

哪种方法最适合此类任务?

4 个答案:

答案 0 :(得分:3)

预测方法取决于数据的解释。

然而,在这种特殊情况下,我们可以做出一些可能证明使用某些机器学习技术的一般假设。

  1. 按时间顺序依次生成值
  2. 值取决于某些(可能是不可观察的)外部状态。如果状态重复,那么值也是如此。
  3. 在许多机器学习环境中,这是一种非常常见的情况。一个例子是基于历史预测股票价格。

    现在,要构建预测模型,您需要定义训练数据集。假设我们的模型查看最后k个值。如果是k=1,我们最终可能会得到与Markov chain模型类似的内容。

    我们的训练数据集将包含k维数据点及其各自的依赖值。例如,假设k=3我们有以下输入数据

    0,0,1,1,0,1,0,1,1,1,1,0,1,0,0,1...
    

    我们将提供以下培训数据:

    (0,0,1) -> 1
    (0,1,1) -> 0
    (1,1,0) -> 1
    (1,0,1) -> 0
    (0,1,0) -> 1
    (1,0,1) -> 1
    (0,1,1) -> 1
    (1,1,1) -> 1
    (1,1,1) -> 0
    (1,1,0) -> 1
    (1,0,1) -> 0
    (0,1,0) -> 0
    (1,0,0) -> 1
    

    现在,假设您要预测序列中的下一个值。最后3个值为0,0,1,因此模型必须根据训练数据预测函数的值(0,0,1)。

    一种流行且相对简单的方法是在k维数据空间上使用多变量linear regression。或者,如果线性回归不适合训练数据集,请考虑使用神经网络。

    您可能需要尝试k的不同值并针对您的验证集进行测试。

答案 1 :(得分:3)

您可以使用maximum likelihood估算器进行伯努利分布。实质上你会:

  • 查看所有观察到的值并估算参数p
  • 然后使用p确定下一个值

Python中,这可能如下所示:

#!/usr/bin/env python

from __future__ import division

signal = [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0]

def maximum_likelihood(s, last=None):
    """
    The maximum likelihood estimator selects the parameter value which gives
    the observed data the largest possible probability.

    http://mathworld.wolfram.com/MaximumLikelihood.html

    If `last` is given, only use the last `n` values.
    """
    if not last:
        return sum(s) / len(s)
    return sum(s[:-last]) / last

if __name__ == '__main__':
    hits = []

    print('p\tpredicted\tcorrect\tsignal')
    print('-\t---------\t-------\t------')

    for i in range(1, len(signal) - 1):
        p = maximum_likelihood(signal[:i]) # p = maximum_likelihood(signal[:i], last=2)
        prediction = int(p >= 0.5)
        hits.append(prediction == signal[i])
        print('%0.3f\t%s\t\t%s\t%s' % (
            p, prediction, prediction == signal[i], signal[:i]))

    print('accuracy: %0.3f' % (sum(hits) / len(hits)))

输出结果如下:

# p       predicted  correct signal
# -       ---------  ------- ------
# 1.000   1          False   [1]
# 0.500   1          True    [1, 0]
# 0.667   1          True    [1, 0, 1]
# 0.750   1          False   [1, 0, 1, 1]
# 0.600   1          False   [1, 0, 1, 1, 0]
# 0.500   1          True    [1, 0, 1, 1, 0, 0]
# 0.571   1          False   [1, 0, 1, 1, 0, 0, 1]
# 0.500   1          True    [1, 0, 1, 1, 0, 0, 1, 0]
# 0.556   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1]
# 0.600   1          False   [1, 0, 1, 1, 0, 0, 1, 0, 1, 1]
# 0.545   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0]
# 0.583   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1]
# 0.615   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]
# 0.643   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1]
# 0.667   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1]
# 0.688   1          False   [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1]
# 0.647   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0]
# 0.667   1          False   [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1]
# 0.632   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0]
# 0.650   1          True    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1]
# accuracy: 0.650

您可以出于性能原因或最近的事件来改变窗口大小。

在上面的例子中,如果我们仅通过查看最后3个观察值来估计下一个值,我们可以将精度提高到0.7。

更新:灵感来自Narek's answer我在gist添加了逻辑回归分类器示例。

答案 2 :(得分:2)

你可以通过计算0和1的概率进行预测并得出它们的概率范围,然后绘制一个介于0和1之间的随机数来预测......

答案 3 :(得分:1)

如果这些是每次重置事件后生成的一系列数字,并且下一个数字与之前的数字有某种关系,那么您可以创建一个树(在您的案例中每个节点有两个分支的二叉树)并输入来自根的这样的历史系列,调整您遵循的每个分支上的权重(比如计数)。

可以将这些计数除以您在使用之前输入的系列数,或者在每个节点上保留一个数字,在选择分支之前增加。这样,根节点包含输入的系列数。

然后,当你给它一个新的序列时,你可以看到哪个分支是更热的" (将使热图/树btw的可视化效果很好),特别是如果序列足够长的话。也就是说,假设顺序中的项目顺序在下一步发挥作用。