基于神经网络的价格回归及其分析

1.生猪价格影响因素

生猪价格往往受到众多因素的影响,从生猪行业的专业知识来看,其影响因素可以归结于以下几点:

  • 母猪存栏量
  • 季节性特征:生猪生产季节性,猪肉消费的季节性
  • 周期性素:也即猪周期,猪价因为供需不均衡而产生的周期性变动
  • 养猪成本因素:饲料原料价格波动;饲料原料主要有豆粕、玉米等
  • 国家政策:环保政策、养猪补贴政策等
  • 不确定的进口猪肉
  • 不确定的失控疾病率:非洲猪瘟等重大疫情
  • 猪肉以外的肉类产品的消费量

2.生猪价格预测的难点
生猪价格受到众多影响因素影响,生猪价格的预测因此变得比较困难,个人认为其难点有以下几点:

  • 数据来源:目前能做到日尺度数据的只有每日的生猪价格,包括温氏价、当地市场价;母猪存栏量、屠宰量、消费量等往往因为数据统计的路径不同、数据统计的难度等因素无法获得相对及时、准确、可靠的数据;
  • 突发重大失控疾病率:生猪市场是一个比较复杂的市场,堪比股市,疫情等重大事件的爆发往往会在较长时间内影响生猪的供应和需求,而这些影响因素往往无法量化;

3.数据准备
基于以上认知,我们认为生猪价格的预测还是以历史生猪价格数据来作为基础,更为可行和可靠,为此我们收集了至2017年以来的生猪价格—温氏定价,作为国内养猪业的老大,其市场份额、人员的专业性,可以认为温氏价比较能反应市场的普遍情况。下图是2017年以来温氏价的走势图:
基于神经网络的价格回归及其分析
同时考虑到生猪价格的定价策略一般基于前n日历史价格来定,因此我们把模型的输入量定为前6日生猪价格的历史数据;同时前600组数据作为模型的训练集,后257组数据作为测试集

load input.txt
for i=1:600;
    data_train(i,:)=input(i,:);
end
for i=601:857;
    data_test(i-600,:)=input(i,:);
end

inputn1=data_train(:,1:7);  
outputn1=data_train(:,8);
inputn_test=data_test(:,1:7);
outputn_test=data_test(:,8);`

4.模型构建
本例采用matlab的BP神经网络模型库来作为基础网络模型,同时采用遗传算法来寻找最优的网络层的权值和阈值,即 iw和b;

  • 调用bp神经网络模型
net=newcf(inputn,outputn,[s1,s2],{'tansig','purelin'},'trainlm')
  • 网络结构为
%网络参数
inputnum=7;
hiddennum=15;
outputnum=1;
%节点总数
numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;

下图为构建的模型结构图
基于神经网络的价格回归及其分析

  • 采用遗传算法寻优
%初始化种群
for i=1:sizepop;
    %随机产生一个种群
    individuals.chrom(i,:)=Code(lenchrom,bound);    %编码(binary和grey的编码结果为一个实数,float的编码结果为一个实数向量)
    x=individuals.chrom(i,:);
    %计算适应度
    individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   %染色体的适应度
end

%找最好的染色体
[bestfitness bestindex]=min(individuals.fitness);
bestchrom=individuals.chrom(bestindex,:);  %最好的染色体
avgfitness=sum(individuals.fitness)/sizepop; %染色体的平均适应度
% 记录每一代进化中最好的适应度和平均适应度
trace=[avgfitness bestfitness]; 
 
%% 迭代求解最佳初始阀值和权值
% 进化开始
for i=1:maxgen
    i
    % 选择
    individuals=Select(individuals,sizepop); 
    avgfitness=sum(individuals.fitness)/sizepop;
    %交叉
    individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
    % 变异
    individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,i,maxgen,bound);
    
    % 计算适应度 
    for j=1:sizepop
        x=individuals.chrom(j,:); %解码
        individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);   
    end
    
  %找到最小和最大适应度的染色体及它们在种群中的位置
    [newbestfitness,newbestindex]=min(individuals.fitness);
    [worestfitness,worestindex]=max(individuals.fitness);
    % 代替上一次进化中最好的染色体
    if bestfitness>newbestfitness
        bestfitness=newbestfitness;
        bestchrom=individuals.chrom(newbestindex,:);
    end
    individuals.chrom(worestindex,:)=bestchrom;
    individuals.fitness(worestindex)=bestfitness;
    
    avgfitness=sum(individuals.fitness)/sizepop;
    
    trace=[trace;avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度

end

关于遗传算法的具体介绍可参考相关文献
基于神经网络的价格回归及其分析
遗传算法的寻优过程

  • 模型训练与测试
% 网络进化参数
net.trainParam.epochs=1000;  %迭代次数
net.trainParam.lr=0.01;  % 自适应lr的梯度下降法
net.trainParam.goal=0.00001; % 误差值

% 网络训练
net=train(net,inputn,outputn);
save net net;

% BP网络预测;
% 数据归一化
p1_test=mapminmax('apply',inputn_test',inputns);
outputn_test_simu=sim(net,p1_test);
outputn_test_simu1=mapminmax('reverse',outputn_test_simu,outputns);

5.结果
下图是模型的预测结果基于神经网络的价格回归及其分析
从模型预测的结果来看,模型的预测值与实际值的相关性可达99.88%,然而从实际值与预测值的散点对比图来看,其中的问题不少:

  • 出现欠拟合的现象:在生猪价格出现“暴涨”或“暴跌”的现象时。模型的预测结果欠佳;
  • 当前模型的输入量为前6日生猪价格的历史数据,从散点图的对比可以看出模型的预测值往往出现滞后的情况;
  • 该模型只能用来预测时隔一天的价格,若要预测未来一个月甚至更长时间段的价格,则需要将模型的预测值当做模型的输入值,比如已有5月17日的预测值p17,需预测5月18日的价格,则改模型的输入量为[p17 p16 p15 p14 p13 p12],其中p17为预测值;但是前述说道模型的预测值具有滞后性。

基于神经网络的价格回归及其分析
6.思考

  • 生猪价格的预测需要考虑众多数据来支撑,但是目前的数据来源较为困难;

  • 基于历史价格的预测模型往往具有滞后性,而需要排除此种滞后性,恐怕需要更多的数据,如母猪存栏量、猪肉消费情况、不可定量分析的因素如何转换成可定量分析;

  • 重大突发事件的影响导致生猪价格在短期内暴涨暴跌的情况下,模型的预测往往失效,是否考虑加入对突发事件的定量分析?