理论基础
(1)输入与输出样本存在某种特定的函数关系
(2)输入与输出样本的函数关系是一种平滑的数学映射。
(3)样本数量充足,包含给定仿真系统的基本特征,
但在实际使用中,常常存在如下的问题:1.输入的维数过高,一方面导致神经网络的收敛时间呈指数级数增长,甚至不收敛的情况,即所谓的维数灾难;另一方面大量的输入变量对输出事实上影响极小,甚至可以不考虑,造成了大量的运算浪费。2.输入变量之间常常相关性很强,也会导致出现输入维数增加的情况。
针对以上情况,主成分分析神经网络应运而生,起作用体现在两个方面。第一,去相关性;第二,减少无关变量的影响,对神经网络而言体现为降维,进而大大地减少计算量。
主成分分析的原理
主成分分析(Principle Components Analysis,简称 PCA),它主要是把分散在一组变量上的信息集中到某几个综合指标(也就是说主成分)上,每个主成分都是原始变量的线性组合,主成分之间互为正交关系,继而可以缩减多变量时间序列的维数,去除冗余信息,减少包含在多变量时间序列中的部分噪声,并且可以反映不同变量之间的相关性。当样本数据维数较多和结构复杂的时候,采用主成分分析的方法可以简化输入样本,减少训练时间,提高训练的效率,达到提高神经网络泛化能力的目的。
1.主成分分析的数学模型
设有p个指标组成的p维随机向量:
得到的综合指标为:
······
其中对于k=1,...,p,有:
y1是线性组合中方差最大的,其他变量的方差按序号依次递减且都互不相关。设λ1>=λ2>=···>=λp是协方差阵D(X)的特征值,则第k个主成分的贡献率为:
前m个主成分的累计贡献了最大,数据的信息损失就越小。通常m所取标准时使得累积贡献率达到80%以上。
2.主成分分析计算步骤
(1)数据标准化。
设有一样本集,含有p个变量,n个样本和t个连续目标量。样本集用自变量矩阵X(n×p)和目标矩阵Y(n×t)表示。
标准化后的自变量为:
其中,X1ij是原始矩阵X0中变量Xij经过标准化的第i个样本的第j个变量的数据:M j,S j 分别是第j个变量的算术平均值和标准(偏)差。
(2)计算标准化自变量矩阵X的协方差矩阵R。
(3)计算协方差矩阵R的特征值矩阵L和特征向量矩阵A。
(4)根据特征值矩阵L和特征向量A计算变量的主成分贡献率及累计贡献率。
(5)选择主成分代替原始样本数据。
3.主成分分析的意义
(1)对于主成分Y=XA,Y的各列一定是正交的,且各列的平方和即为对应的特征值。
(2)Y各列的均值为0,方差为所对应的特征值,便于对数据进行统计分析,而且有利于神经网络的数据预处理。
(3)特征值矩阵L的所有特征值一定是正实数,特征向量矩阵A一定是单位正交矩阵,即ATA=I,有利于数学公式的推导,也从根据上保证了主成分分析方法的正确行。
主元神经网络与股票预测
神经网络具有自学习和自适应等特性,并且又具有很强的非线性逼近功能,所以它不用建立复杂的非线性系统的显含关系和数学模型就可以避免许多人为因素的影响,也可以传统定量预测方法的许多局限及面临的困难。因此,用人工神经网络来预测股票,在建立合理性和适用性的预测模型中具有独特的优势,将为解决股票这种非线性系统的预测提供有效的方法。
(1)指标体系。开盘x1,收盘x2,涨跌额x3,涨跌幅x4,最低价x5,最高价x6,成交量x7,成交金额x8。
(2)股票历史数据。
(3)指标处理。指定指标的识别与处理,所有指标的无量纲化。
(4)输入数据的预处理。对无量纲化后的指标数据进行主成分分析。
(5)BP神经网络的设计。
(6)BP神经网络的训练。用150组数据作为训练组。
(7)检验。用50组数据作为检验组,以验证模型的正确性。
(8)结果分析。
预测方法(matlab)
>>%第一步,得到数据
>> [n,m]=size(index)
>> X0=index(n:-1:1,:);
>> Time=(1:n)';
>> figure('name','open and close','numbertitle','off')
>> plot(Time,X0(:,1),Time,X0(:,2),'linewidth',1.5);
>> grid on;
>> h=legend('开盘价','收盘价');
>> set(h,'fontsize',16);
>> title('开盘与收盘价格随时间的变化情况','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>> ylabel('开盘与收盘价格','fontsize',16);
>> set(gca,'fontsize',16);
>> figure('name','涨跌额与涨跌幅随时间的变化情况','numbertitle','off')
>> [AX,H1,H2]=plotyy(Time,X0(:,3),Time,X0(:,4),'plot');
>> grid on;
>> set(get(AX(1),'Ylabel'),'String','涨跌额','fontsize',16)
>> set(get(AX(2),'Ylabel'),'String','涨跌幅','fontsize',16)
>> title('涨跌额与涨跌幅随时间的变化情况','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>> figure('name','最高与最低价随时间的变化情况','numbertitle','off')
>> plot(Time,X0(:,5),Time,X0(:,6),'linewidth',1.5);
>> grid on;
>> h=legend('最高价','最低价');
>> set(h,'fontsize',16);
>> title('最高与最低价随时间的变化情况','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>> ylabel('价格','fontsize',16);
>> set(h,'fontsize',16);
>> figure('name','成交量与成交金额随时间的变化情况','numbertitle','off')
>> [AX,H1,H2]=plotyy(Time,X0(:,7),Time,X0(:,8),'plot');
>> grid on;
>> set(get(AX(1),'Ylabel'),'String','成交量','fontsize',16)
>> set(get(AX(2),'Ylabel'),'String','成交金额','fontsize',16)
>> title('成交量与成交金额随时间的变化情况','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>>%第二步,对样本进行标准化,得到标准样本集
>> Time0=1:150;
>> nT0=length(Time0);
>> StdX0=std(X0(Time0,:));
>> MeanX0=mean(X0(Time0,:));
>> X=(X0(Time0,:)-ones(nT0,1)*MeanX0)./(ones(nT0,1)*StdX0);
>> %第三步,求原标准样本集的特征协方差矩阵
>> R=cov(X);
>> %第四步,求协方差矩阵R的全部特征值和对应的特征向量,并根据特征值由大至小进行排序
>> [A,L]=eig(R);
>> Lambda=diag(L);
>> [Lambda,Numl]=sort(Lambda,'descend');
>> A=A(:,Numl);
>>%第五步,得到方差由大至小排序的主成分,其中方差的大小即为特征值
>> Y=X*A
>> %第六步,计算超过0.85的方差累积序号
>> cumEnergy=cumsum(Lambda);
>> Energy=cumEnergy(m);
>> nE=find(cumEnergy/Energy>0.85,1);
>> %第七步,利用BP神经网络进行训练
>> YChoose=X*A(:,1:nE);
>> P=YChoose(Time0,:)'; %得到输入量
>> T=[X(Time0(2:end),4)',(X0(nT0,4)-MeanX0(4))/StdX0(4)]; %得到输出量
>> %创建一个BP神经网络
>> net=newff(minmax(P),[nE,20,1],{'tansig','tansig','tansig'},'trainlm','learngdm','msereg');
>> net=init(net); %对神经网络进行初始化,初始化的目的是使神经网络的权值和阈值等参数达到一个较好的初始状态
>> %对神经网络进行训练
>> net.performFcn='sse'; %设置性能函数
>> net.trainParam.goal=0.01; %训练目标,默认值为0
>> net.trainParam.show=20; %两次显示之间的训练次数,默认值为25
>> net.trainParam.epochs=5000; %神经网络的最大训练次数,默认值为100
>> net.trainParam.mc=0.95; %神经网络的动量因子
>> [net,tr]=train(net,P,T); %设置好训练参数后,对神经网络进行训练
>> YOut=sim(net,P); %输出训练后神经网络的输出
>> %对输出进行反归一化
>> x4=StdX0(4)*YOut+MeanX0(4);
>> figure('name','实际涨跌幅与预测涨跌幅的比较','numbertitle','off')
>> plot(Time0+1,X0(Time0+1,4),Time0+1,x4,'linewidth',1.5);
>> grid on;
>> h=legend('实际涨跌幅','预测涨跌幅');
>> set(h,'fontsize',16);
>> title('实际涨跌幅与预测涨跌幅的比较','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>> ylabel('涨跌幅','fontsize',16);
>> set(gca,'fontsize',16);
>> %对后面50组数据进行预测
>> Time1=150:199;
>> nT1=length(Time1);
>> X1=(X0(Time1,:)-ones(nT1,1)*MeanX0)./(ones(nT1,1)*StdX0);
>> YChoose1=X1*A(:,1:nE);
>> P1=YChoose1(1:nT1,:)';
>> YOut1=sim(net,P1);
>> x41=StdX0(4)*YOut1+MeanX0(4);
>> figure('name','测试集实际涨跌幅与预测涨跌幅的比较','numbertitle','off')
>> plot(Time1+1,X0(Time1+1,4),Time1+1,x41,'linewidth',1.5);
>> grid on;
>> h=legend('实际涨跌幅','预测涨跌幅');
>> set(h,'fontsize',16);
>> title('测试集实际涨跌幅与预测涨跌幅的比较','fontsize',16);
>> xlabel('时间序列','fontsize',16);
>> ylabel('涨跌幅','fontsize',16);
>> set(gca,'fontsize',16);
OH~怎么会这样😂