PyBrain神经网络用于股票预测无法学习

3
我正在尝试编写一个可以预测数据的神经网络,因此我使用Python的PyBrain。我发现SupervisedDataset非常适合这个任务。我选取了一些股票数据,将其中5个值作为输入,第六个值作为目标输出。然后我使用buildNetwork函数构建了一个前馈网络,并使用BackpropTrainer进行训练。

无论如何,误差似乎无法减少。它停留在大约0.6左右,并且似乎在该值周围震荡。我尝试调整动量和学习率,但没有帮助。我做错了什么?

from pybrain.datasets import SupervisedDataSet
DS = SupervisedDataSet(5, 1)

DS.addSample((44.055, 44.54, 44.04, 43.975, 43.49), (42.04,))
DS.addSample((44.54, 44.04, 43.975, 43.49, 42.04), (42.6,))
DS.addSample((44.04, 43.975, 43.49, 42.04, 42.6), (42.46,))
DS.addSample((43.975, 43.49, 42.04, 42.6, 42.46), (41.405,))
DS.addSample((43.49, 42.04, 42.6, 42.46, 41.405), (42.385,))
DS.addSample((42.04, 42.6, 42.46, 41.405, 42.385), (42.655,))
DS.addSample((42.6, 42.46, 41.405, 42.385, 42.655), (41.53,))
DS.addSample((42.46, 41.405, 42.385, 42.655, 41.53), (40.09,))
DS.addSample((41.405, 42.385, 42.655, 41.53, 40.09), (39.8,))
DS.addSample((42.385, 42.655, 41.53, 40.09, 39.8), (40.2,))
DS.addSample((42.655, 41.53, 40.09, 39.8, 40.2), (39.915,))
DS.addSample((41.53, 40.09, 39.8, 40.2, 39.915), (40.21,))
DS.addSample((40.09, 39.8, 40.2, 39.915, 40.21), (40.34,))
DS.addSample((39.8, 40.2, 39.915, 40.21, 40.34), (41.195,))
DS.addSample((40.2, 39.915, 40.21, 40.34, 41.195), (41.595,))
DS.addSample((39.915, 40.21, 40.34, 41.195, 41.595), (41.975,))
DS.addSample((40.21, 40.34, 41.195, 41.595, 41.975), (42.045,))
DS.addSample((40.34, 41.195, 41.595, 41.975, 42.045), (40.13,))
DS.addSample((41.195, 41.595, 41.975, 42.045, 40.13), (38.99,))
DS.addSample((41.595, 41.975, 42.045, 40.13, 38.99), (39.81,))
DS.addSample((41.975, 42.045, 40.13, 38.99, 39.81), (40.23,))
DS.addSample((42.045, 40.13, 38.99, 39.81, 40.23), (40.47,))
DS.addSample((40.13, 38.99, 39.81, 40.23, 40.47), (40.45,))
DS.addSample((38.99, 39.81, 40.23, 40.47, 40.45), (40.01,))
DS.addSample((39.81, 40.23, 40.47, 40.45, 40.01), (40.23,))
DS.addSample((40.23, 40.47, 40.45, 40.01, 40.23), (40.2,))
DS.addSample((40.47, 40.45, 40.01, 40.23, 40.2), (41.605,))
DS.addSample((40.45, 40.01, 40.23, 40.2, 41.605), (42.1,))
DS.addSample((40.01, 40.23, 40.2, 41.605, 42.1), (42.135,))
DS.addSample((40.23, 40.2, 41.605, 42.1, 42.135), (41.95,))
DS.addSample((40.2, 41.605, 42.1, 42.135, 41.95), (41.145,))
DS.addSample((41.605, 42.1, 42.135, 41.95, 41.145), (40.635,))
DS.addSample((42.1, 42.135, 41.95, 41.145, 40.635), (41.25,))
DS.addSample((42.135, 41.95, 41.145, 40.635, 41.25), (41.19,))
DS.addSample((41.95, 41.145, 40.635, 41.25, 41.19), (42.065,))
DS.addSample((41.145, 40.635, 41.25, 41.19, 42.065), (42.025,))
DS.addSample((40.635, 41.25, 41.19, 42.065, 42.025), (42.09,))
DS.addSample((41.25, 41.19, 42.065, 42.025, 42.09), (41.79,))
DS.addSample((41.19, 42.065, 42.025, 42.09, 41.79), (43.11,))


from pybrain.tools.shortcuts import buildNetwork
FNN = buildNetwork(DS.indim, 15, DS.outdim, bias=True)

from pybrain.supervised.trainers import BackpropTrainer
TRAINER = BackpropTrainer(FNN, dataset=DS, learningrate = 0.005, \
    momentum=0.1, verbose=True)

for i in range(1000):
    TRAINER.train()

编辑:一些评论质疑这些数据是否适用于神经网络。因此,我在MATLAB中进行了相同的网络测试,结果非常好。在11次训练迭代后,误差小于0.002。
此外,我尝试使用PyBrain的SupervisedDataset,但也没有成功。现在我已经没有更多想法了。

2
虽然我没有一个明确的答案来回答你的问题,但我想指出的是,你并不一定做错了什么。你的数据可能只是没有足够的信息来进行预测 - 如果你可以使用FFNN来预测你特定的股票市场以赚取利润,那么其他人早就已经这样做了。如果你对你的代码有疑问,我的建议是先在更简单的数据上测试你的网络,然后再从那里开始。 - loopbackbee
谢谢。这只是为了学习目的。事实上,我只是想获得比使用前一天的值更好的预测结果。我将尝试使用更简单的数据测试网络。 - Gizmo
1
您还可以改变输入的前几天的数量。我不确定神经网络是否是用于预测具有绝对值的时间序列的正确工具。您可能还想尝试其他目标。也许只需要使用加号和减号来预测股票价格是上涨还是下跌。 - Max Linke
这是一本书,解释了为什么你的误差可能会保持在较高水平:http://www.amazon.com/Random-Walk-Down-Wall-Street/dp/0393330338 - John Zwinck
1
如果你坚持使用股票数据,可以使用历史上倾向于一起上涨和下跌的股票(例如来自同一行业的六只股票)。但几十年来,人们一直在尝试使基本神经网络预测股票价格,我记得在90年代初读过相关文章。如果它能够奏效,那么这种方法就会变得普遍化,这将意味着它不再奏效。即使是人类大脑中的神经网络也不能始终如一地完成这个任务,而它们比软件神经网络规模要大得多。 - rossdavidh
显示剩余2条评论
1个回答

3
我找到了一个解决方案。原来股票数据必须先进行归一化处理。所以我编写了这个函数:
def normalization(data, new_max, new_min):
    old_max = 0
    old_min = 0

    # Finde altes Max- und Minimum
    for i in range(len(data)):
        if old_max < data[i]:
            old_max = data[i]
        elif old_min > data[i]:
            old_min = data[i]

    old_range = (old_max - old_min)

    for i in range(len(data)):
        if old_range == 0:
            data[i] = new_min
        else:
            new_range = (new_max - new_min)
            data[i] = (((data[i] - old_min) * new_range) / old_range) + new_min

我将数据缩放在0到1之间,然后网络就终于能够学习了。


你还需要吗? - Gizmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接