冰冰点灯,照亮我家门前~
欢迎进入nnetinfo
用户名:
密码:
深圳学习数据分析,数据挖掘,请联系yahushuxue@163.com~
nnetinfo : 本网发布神经网络相关的学习与研讨内容。
当前位置:教学区
神经网络在时间序列上的应用
作者:xiaoH   日期:2015-11-16 19:20:10.0

假如有一组时间序列数据:

时间 1999 2000 2001 2002 2003 2004 2005 2006 2007
价格 3000 3252 3358 3252 2852  2752 2752 3000 3200

现在希望通过历史价格走势,预测下一年的价格。

 

为什么预测不准确?----------------------------------------------------------------------------------------

       曾经不只一次见过,有人这样使用神经网络处理这类型的时间序列问题:

                          网络输入:1999,2000,2001,2002,2003...2007

                          目标输出:3000,3252,3358,3252,2852.....3200

       然后运用matlab神经网络工具箱,设置几个隐节点,点击训练,很快就把神经网络模型建好了,在训练数据

上的拟合效还也很不错。但一旦输入2008、2009的时候,发现预测出来的数据根本不靠谱。

 

为什么预测出来的数据不靠谱?

      对神经网络算法了解较深入的话就会知道,用于预测的神经网络的输入,一般需要在训练数据的范围(2008,

2009明显不在[1999,2007]之间,而且之后的2010,2011…等等会偏离更远。)。所以这样构建出来的模型是不

适合于预测未来几年的价格的。

 

   既然无法用时间作为输入,那要怎么才能用神经网络预测未来的走势?

好了,进入正题。

 

使用过去,预测未来!----------------------------------------------------------------------------------------

    时间序列的最大的特点就是,后面的数据与前面的数据紧密相关。

    因此,抓住这个特点,当我们要用神经网络来预测时间序列的时候,只需要将前几个时间点上的数据做为输入变

量,来预测下一个时间点的数据就可以了(例如用Xt1,Xt2,Xt3预测Xt4)。

 

      例如,文章开篇提到的数据,我们可以转换成

  2002 2003 2004 2005 2006 2007
Xt-3 3000 3252 3358 3252 2852 2752
Xt-2 3252 3358 3252 2852 2752 2752
Xt-1 3358 3252 2852 2752 2752 3000
Xt 3252 2852 2752 2752 3000 3200

   再用 Xt-1,Xt-2,Xt-3 作为网络的输出,来预测 Xt 就可以了。

 

一起来看代码实例^ ^--------------------------------------------------------------------------------------------

下面是用matlab的神经网络工具箱实现的一个例子(已在matlab2012b上通过测试,):

% time series:神经网络在时间序列上的应用
% 本代码出自《神经网络之家》--www.nnetinfo.com------

timeList = 0 :0.01 : 2*pi;   %生成时间点
X   = sin(timeList);            %生成时间序列信号

%利用x(t-5),x(t-4),x(t-3),x(t-2),x(t-1)作为输入预测x(t),将x(t)作为输出数据
inputData  = [X(1:end-5);X(2:end-4);X(3:end-3);X(4:end-2);X(5:end-1)];
outputData = X(6:end);

%使用用输入输出数据(inputData、outputData)建立网络,
%隐节点个数设为3.其中隐层、输出层的传递函数分别为tansig和purelin,使用trainlm方法训练。
net = newff(inputData,outputData,3,{'tansig','purelin'},'trainlm');

%设置一些常用参数
net.trainparam.goal = 0.0001; %训练目标:均方误差低于0.0001
net.trainparam.show = 400;    %每训练400次展示一次结果
net.trainparam.epochs = 1500;  %最大训练次数:15000.

[net,tr] = train(net,inputData,outputData);%调用matlab神经网络工具箱自带的train函数训练网络

simout = sim(net,inputData); %调用matlab神经网络工具箱自带的sim函数得到网络的预测值

figure;  %新建画图窗口窗口
t=1:length(simout);
plot(t,outputData,t,simout,'r')%画图,对比原来的输出和网络预测的输出

%------------------附加:抽取数学表达式----------------------------top
%希望脱离matlab的sim函数来使用训练好网络的话,可以抽取出数学的表达式,|
%这样在任何软件中,只需要按表达式计算即可。                          |
%============抽取数学表达式==================
%抽取出网络的权值和阈值

w12 = net.iw{1,1}; %第1层(输入层)到第2层(隐层)的权值
b2  = net.b{1};    %第2层(隐层)的阈值

w23 = net.lw{2,1}; %第2层(隐层)到第3层(输出层)的权值
b3  = net.b{2};    %第3层(输出层)的阈值


%由于有归一化,必须先将归一化信息抓取出来
iMax = max(inputData,[],2);
iMin = min(inputData,[],2);
oMax = max(outputData,[],2);
oMin = min(outputData,[],2);

%方法1:归一化--->计算输出--->反归一化
normInputData=2*(inputData -repmat(iMin,1,size(inputData,2)))./repmat(iMax-iMin,1,size(inputData,2)) -1;
tmp = w23*tansig( w12 *normInputData + repmat(b2,1,size(normInputData,2))) + repmat(b3,1,size(normInputData,2));
myY = (tmp+1).*repmat(oMax-oMin,1,size(outputData,2))./2 + repmat(oMin,1,size(outputData,2));


%方法2:用真正的权值和阈值进行计算
%公式请参考《提取对应原始数据的权重和阈值》http://nnetinfo.com/nninfo/showText.jsp?id=32

W12 = w12 * 2 ./repmat(iMax' -iMin',size(w12,1),1);
B2  = -w12* (2*iMin ./(iMax - iMin) + 1) + b2;

W23 = w23 .*repmat((oMax -oMin),1,size(w23,2))/2;
B3  = (oMax -oMin) .*b3 /2 + (oMax -oMin)/2 + oMin;

%最终的数学表达式:
myY2 = W23 *tansig( W12 *inputData + repmat(B2,1,size(inputData,2))) + repmat(B3,1,size(inputData,2));

 

结束语

      神经网络的应用,建立在对神经网络算法和原理的深入理解的基础上。但另一方面,需要结合业务知识,设计好网

络的输出和输出,只有合理的输入和输出,才能使神经网络算法发挥出我们所想要的效果。《神经网络之家》祝大家学

习愉快!

 

==============<原创文章,转载请说明来自神经网络之家www.nnetinfo.com>     ================