java 时间序列预测_ARIMA模型 预测时间序列 JAVA实现

该博客介绍了如何使用Java实现ARIMA模型来处理时间序列预测。ARIMA类包含了预处理方法如一阶差分、归一化以及ARIMA模型的构建。通过对不同差分类型的处理,例如一阶普通差分和季节性差分,进行数据预处理,然后通过计算AIC值选择最佳模型参数,从而进行预测。
摘要由CSDN通过智能技术生成

package arima;

import arima.ARMAMath;

import java.util.*;

public class ARIMA {

double[] originalData={};

double[] originalDatafirDif={};

double[] originalDatasecDif={};

double[] originalDatathiDif={};

double[] originalDataforDif={};

double[] originalDatafriDif={};

ARMAMath armamath=new ARMAMath();

double stderrDara=0;

double avgsumData=0;

Vector armaARMAcoe=new Vector();

Vector bestarmaARMAcoe=new Vector();

int typeofPredeal=0;

/**

* 构造函数

* @param originalData 原始时间序列数据

*/

public ARIMA(double [] originalData,int typeofPredeal)

{

this.originalData=originalData;

this.typeofPredeal=typeofPredeal;//数据预处理类型 1:一阶普通查分7:季节性差分

}

/**

* 原始数据标准化处理:一阶季节性差分

* @return 差分过后的数据

*/

public double[] preDealDif(double[] originalData)

{

//seasonal Difference:Peroid=7

double []tempData=new double[originalData.length-7];

for(int i=0;i

{

tempData[i]=originalData[i+7]-originalData[i];

}

return tempData;

}

/**

*

*/

public double[] preFirDif(double[] originalData)

{

// Difference:Peroid=1

double []tempData=new double[originalData.length-1];

for(int i=0;i

{

tempData[i]=originalData[i+1]-originalData[i];

}

return tempData;

}

/**

* 原始数据标准化处理:Z-Score归一化

* @param 待处理数据

* @return 归一化过后的数据

*/

public double[] preDealNor(double[] tempData)

{

//Z-Score

avgsumData=armamath.avgData(tempData);

stderrDara=armamath.stderrData(tempData);

for(int i=0;i

{

tempData[i]=(tempData[i]-avgsumData)/stderrDara;

}

return tempData;

}

public modelandpara getARIMAmodel(int[] bestmodel)

{

double[] stdoriginalData=null;

if(typeofPredeal==0)

{

stdoriginalData=new double[originalData.length];

System.arraycopy(originalData, 0, stdoriginalData, 0,originalData.length);

}

else if(typeofPredeal==1) //原始数据一阶普通差分处理

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

stdoriginalData=new double[originalDatafirDif.length];

System.arraycopy(originalDatafirDif, 0, stdoriginalData, 0,originalDatafirDif.length);

}

else if (typeofPredeal==2)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

stdoriginalData=new double[originalDatasecDif.length];

System.arraycopy(originalDatasecDif, 0, stdoriginalData, 0,originalDatasecDif.length);

}

else if(typeofPredeal==3)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

stdoriginalData=new double[originalDatathiDif.length];

System.arraycopy(originalDatathiDif, 0, stdoriginalData, 0,originalDatathiDif.length);

}

else if(typeofPredeal==4)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

originalDataforDif=new double[this.preFirDif(originalDatathiDif).length];

System.arraycopy(this.preFirDif(originalDatathiDif), 0, originalDataforDif, 0,originalDataforDif.length);

stdoriginalData=new double[originalDataforDif.length];

System.arraycopy(originalDataforDif, 0, stdoriginalData, 0,originalDataforDif.length);

}

else if(typeofPredeal==5)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

originalDataforDif=new double[this.preFirDif(originalDatathiDif).length];

System.arraycopy(this.preFirDif(originalDatathiDif), 0, originalDataforDif, 0,originalDataforDif.length);

originalDatafriDif=new double[this.preFirDif(originalDataforDif).length];

System.arraycopy(this.preFirDif(originalDataforDif), 0, originalDatafriDif, 0,originalDatafriDif.length);

stdoriginalData=new double[originalDatafriDif.length];

System.arraycopy(originalDatafriDif, 0, stdoriginalData, 0,originalDatafriDif.length);

}

else//原始数据季节性差分处理

{

stdoriginalData=new double[this.preDealDif(originalData).length];

System.arraycopy(this.preDealDif(originalData), 0, stdoriginalData, 0,this.preDealDif(originalData).length);

}

armaARMAcoe.clear();

bestarmaARMAcoe.clear();

if(bestmodel[0]==0)

{

MA ma=new MA(stdoriginalData, bestmodel[1]);

armaARMAcoe=ma.MAmodel(); //拿到ma模型的参数

}

else if(bestmodel[1]==0)

{

AR ar=new AR(stdoriginalData, bestmodel[0]);

armaARMAcoe=ar.ARmodel(); //拿到ar模型的参数

}

else

{

ARMA arma=new ARMA(stdoriginalData, bestmodel[0], bestmodel[1]);

armaARMAcoe=arma.ARMAmodel();//拿到arma模型的参数

}

bestarmaARMAcoe=armaARMAcoe;

modelandpara mp=new modelandpara(bestmodel, bestarmaARMAcoe);

return mp;

}

/**

* 得到ARMA模型=[p,q]

* @return ARMA模型的阶数信息

*//*

public modelandpara getARIMAmodel()

{

double[] stdoriginalData=null;

if(typeofPredeal==0)

{

stdoriginalData=new double[originalData.length];

System.arraycopy(originalData, 0, stdoriginalData, 0,originalData.length);

}

else if(typeofPredeal==1) //原始数据一阶普通差分处理

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

stdoriginalData=new double[originalDatafirDif.length];

System.arraycopy(originalDatafirDif, 0, stdoriginalData, 0,originalDatafirDif.length);

}

else if (typeofPredeal==2)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

stdoriginalData=new double[originalDatasecDif.length];

System.arraycopy(originalDatasecDif, 0, stdoriginalData, 0,originalDatasecDif.length);

}

else if(typeofPredeal==3)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

stdoriginalData=new double[originalDatathiDif.length];

System.arraycopy(originalDatathiDif, 0, stdoriginalData, 0,originalDatathiDif.length);

}

else if(typeofPredeal==4)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

originalDataforDif=new double[this.preFirDif(originalDatathiDif).length];

System.arraycopy(this.preFirDif(originalDatathiDif), 0, originalDataforDif, 0,originalDataforDif.length);

stdoriginalData=new double[originalDataforDif.length];

System.arraycopy(originalDataforDif, 0, stdoriginalData, 0,originalDataforDif.length);

}

else if(typeofPredeal==5)

{

originalDatafirDif=new double[this.preFirDif(originalData).length];//原始数据一阶普通差分处理

System.arraycopy(this.preFirDif(originalData), 0, originalDatafirDif, 0,originalDatafirDif.length);

originalDatasecDif=new double[this.preFirDif(originalDatafirDif).length];

System.arraycopy(this.preFirDif(originalDatafirDif), 0, originalDatasecDif, 0,originalDatasecDif.length);

originalDatathiDif=new double[this.preFirDif(originalDatasecDif).length];

System.arraycopy(this.preFirDif(originalDatasecDif), 0, originalDatathiDif, 0,originalDatathiDif.length);

originalDataforDif=new double[this.preFirDif(originalDatathiDif).length];

System.arraycopy(this.preFirDif(originalDatathiDif), 0, originalDataforDif, 0,originalDataforDif.length);

originalDatafriDif=new double[this.preFirDif(originalDataforDif).length];

System.arraycopy(this.preFirDif(originalDataforDif), 0, originalDatafriDif, 0,originalDatafriDif.length);

stdoriginalData=new double[this.preFirDif(originalDatafriDif).length];

System.arraycopy(this.preFirDif(originalDatafriDif), 0, stdoriginalData, 0,originalDatafriDif.length);

}

else//原始数据季节性差分处理

{

stdoriginalData=new double[this.preDealDif(originalData).length];

System.arraycopy(this.preDealDif(originalData), 0, stdoriginalData, 0,this.preDealDif(originalData).length);

}

int paraType=0;

double minAIC=9999999;

int bestModelindex=0;

int[][] model=new int[][]{{0,1},{1,0},{1,1},{0,2},{2,0},{2,2},{1,2},{2,1},{3,0},{0,3},{3,1},{1,3},{3,2},{2,3},{3,3}};

//对模型进行迭代,选出平均预测误差最小的模型作为我们的模型

for(int i=0;i

{

if(model[i][0]==0)

{

MA ma=new MA(stdoriginalData, model[i][1]);

armaARMAcoe=ma.MAmodel(); //拿到ma模型的参数

paraType=1;

}

else if(model[i][1]==0)

{

AR ar=new AR(stdoriginalData, model[i][0]);

armaARMAcoe=ar.ARmodel(); //拿到ar模型的参数

paraType=2;

}

else

{

ARMA arma=new ARMA(stdoriginalData, model[i][0], model[i][1]);

armaARMAcoe=arma.ARMAmodel();//拿到arma模型的参数

paraType=3;

}

double temp=getmodelAIC(armaARMAcoe,stdoriginalData,paraType);

if (temp

{

bestModelindex=i;

minAIC=temp;

bestarmaARMAcoe=armaARMAcoe;

}

}

modelandpara mp=new modelandpara(model[bestModelindex], bestarmaARMAcoe);

return mp;

}*/

/**

* 计算ARMA模型的AIC

* @param para 装载模型的参数信息

* @param stdoriginalData 预处理过后的原始数据

* @param type 1:MA;2:AR;3:ARMA

* @return 模型的AIC值

*/

public double getmodelAIC(Vector para,double[] stdoriginalData,int type)

{

double temp=0;

double temp2=0;

double sumerr=0;

int p=0;//ar1,ar2,...,sig2

int q=0;//sig2,ma1,ma2...

int n=stdoriginalData.length;

Random random=new Random();

if(type==1)

{

double[] maPara=new double[para.get(0).length];

System.arraycopy(para.get(0), 0, maPara, 0, para.get(0).length);

q=maPara.length;

double[] err=new double[q]; //error(t),error(t-1),error(t-2)...

for(int k=q-1;k

{

temp=0;

for(int i=1;i

{

temp+=maPara[i]*err[i];

}

//产生各个时刻的噪声

for(int j=q-1;j>0;j--)

{

err[j]=err[j-1];

}

err[0]=random.nextGaussian()*Math.sqrt(maPara[0]);

//估计的方差之和

sumerr+=(stdoriginalData[k]-(temp))*(stdoriginalData[k]-(temp));

}

//return (n-(q-1))*Math.log(sumerr/(n-(q-1)))+(q)*Math.log(n-(q-1));//AIC 最小二乘估计

return (n-(q-1))*Math.log(sumerr/(n-(q-1)))+(q+1)*2;

}

else if(type==2)

{

double[] arPara=new double[para.get(0).length];

System.arraycopy(para.get(0), 0, arPara, 0, para.get(0).length);

p=arPara.length;

for(int k=p-1;k

{

temp=0;

for(int i=0;i

{

temp+=arPara[i]*stdoriginalData[k-i-1];

}

//估计的方差之和

sumerr+=(stdoriginalData[k]-temp)*(stdoriginalData[k]-temp);

}

return (n-(q-1))*Math.log(sumerr/(n-(q-1)))+(p+1)*2;

//return (n-(p-1))*Math.log(sumerr/(n-(p-1)))+(p)*Math.log(n-(p-1));//AIC 最小二乘估计

}

else

{

double[] arPara=new double[para.get(0).length];

System.arraycopy(para.get(0), 0, arPara, 0, para.get(0).length);

double[] maPara=new double[para.get(1).length];

System.arraycopy(para.get(1), 0, maPara, 0, para.get(1).length);

p=arPara.length;

q=maPara.length;

double[] err=new double[q]; //error(t),error(t-1),error(t-2)...

for(int k=p-1;k

{

temp=0;

temp2=0;

for(int i=0;i

{

temp+=arPara[i]*stdoriginalData[k-i-1];

}

for(int i=1;i

{

temp2+=maPara[i]*err[i];

}

//产生各个时刻的噪声

for(int j=q-1;j>0;j--)

{

err[j]=err[j-1];

}

//System.out.println("predictBeforeDiff="+1);

err[0]=random.nextGaussian()*Math.sqrt(maPara[0]);

//估计的方差之和

sumerr+=(stdoriginalData[k]-(temp2+temp))*(stdoriginalData[k]-(temp2+temp));

}

return (n-(q-1))*Math.log(sumerr/(n-(q-1)))+(p+q)*2;

//return (n-(p-1))*Math.log(sumerr/(n-(p-1)))+(p+q-1)*Math.log(n-(p-1));//AIC 最小二乘估计

}

}

/**

* 对预测值进行反差分处理

* @param predictValue 预测的值

* @return 反差分过后的预测值

*/

public int aftDeal(int predictValue)

{

int temp=0;

//System.out.println("predictBeforeDiff="+predictValue);

if(typeofPredeal==0)

temp=((int)predictValue);

else if(typeofPredeal==1)

temp=(int)(predictValue+originalData[originalData.length-1]);

else if(typeofPredeal==2)

temp=(int)(predictValue+originalDatafirDif[originalDatafirDif.length-1]+originalData[originalData.length-1]);

else if(typeofPredeal==3)

temp=(int)(predictValue+originalDatasecDif[originalDatasecDif.length-1]+originalDatafirDif[originalDatafirDif.length-1]+originalData[originalData.length-1]);

else if(typeofPredeal==4)

temp=(int)(predictValue+originalDatathiDif[originalDatathiDif.length-1]+originalDatasecDif[originalDatasecDif.length-1]+originalDatafirDif[originalDatafirDif.length-1]+originalData[originalData.length-1]);

else if(typeofPredeal==5)

temp=(int)(predictValue+originalDataforDif[originalDataforDif.length-1]+originalDatathiDif[originalDatathiDif.length-1]+originalDatasecDif[originalDatasecDif.length-1]+originalDatafirDif[originalDatafirDif.length-1]+originalData[originalData.length-1]);

else

temp=(int)(predictValue+originalData[originalData.length-7]);

return temp>0?temp:0;

}

/**

* 进行一步预测

* @param p ARMA模型的AR的阶数

* @param q ARMA模型的MA的阶数

* @return 预测值

*/

public int predictValue(int p,int q,Vector bestpara)

{

double[] stdoriginalData=null;

if (typeofPredeal==0)

{

stdoriginalData=new double[originalData.length];

System.arraycopy(originalData, 0, stdoriginalData, 0, originalData.length);

}

else if(typeofPredeal==1)

{

stdoriginalData=new double[originalDatafirDif.length];

System.arraycopy(originalDatafirDif, 0, stdoriginalData, 0, originalDatafirDif.length);

}

else if(typeofPredeal==2)

{

stdoriginalData=new double[originalDatasecDif.length];//普通二阶差分处理

System.arraycopy(originalDatasecDif, 0, stdoriginalData, 0, originalDatasecDif.length);

}

else if(typeofPredeal==3)

{

stdoriginalData=new double[originalDatathiDif.length];//普通三阶差分处理

System.arraycopy(originalDatathiDif, 0, stdoriginalData, 0, originalDatathiDif.length);

}

else if(typeofPredeal==4)

{

stdoriginalData=new double[originalDataforDif.length];//普通四阶差分处理

System.arraycopy(originalDataforDif, 0, stdoriginalData, 0, originalDataforDif.length);

}

else if(typeofPredeal==5)

{

stdoriginalData=new double[originalDatafriDif.length];//普通五阶差分处理

System.arraycopy(originalDatafriDif, 0, stdoriginalData, 0, originalDatafriDif.length);

}

else

{

stdoriginalData=new double[this.preDealDif(originalData).length];//季节性一阶差分

System.arraycopy(this.preDealDif(originalData), 0, stdoriginalData, 0, this.preDealDif(originalData).length);

}

//System.out.println("typeofPredeal= "+typeofPredeal+typeofPredeal);

// for(int i=0;i

// System.out.println(originalDatafirDif[i]);

//

int predict=0;

int n=stdoriginalData.length;

double temp=0,temp2=0;

double[] err=new double[q+1];

Random random=new Random();

if(p==0)

{

double[] maPara=bestpara.get(0);

for(int k=q;k

{

temp=0;

for(int i=1;i<=q;i++)

{

temp+=maPara[i]*err[i];

}

//产生各个时刻的噪声

for(int j=q;j>0;j--)

{

err[j]=err[j-1];

}

err[0]=random.nextGaussian()*Math.sqrt(maPara[0]);

}

predict=(int)(temp); //产生预测

//System.out.println("predict=q "+predict);

}

else if(q==0)

{

double[] arPara=bestpara.get(0);

for(int k=p;k

{

temp=0;

for(int i=0;i

{

temp+=arPara[i]*stdoriginalData[k-i-1];

}

}

predict=(int)(temp);

//System.out.println("predict= p"+predict);

}

else

{

double[] arPara=bestpara.get(0);

double[] maPara=bestpara.get(1);

err=new double[q+1]; //error(t),error(t-1),error(t-2)...

for(int k=p;k

{

temp=0;

temp2=0;

for(int i=0;i

{

temp+=arPara[i]*stdoriginalData[k-i-1];

}

for(int i=1;i<=q;i++)

{

temp2+=maPara[i]*err[i];

}

//产生各个时刻的噪声

for(int j=q;j>0;j--)

{

err[j]=err[j-1];

}

err[0]=random.nextGaussian()*Math.sqrt(maPara[0]);

}

predict=(int)(temp2+temp);

//System.out.println("predict=p,q "+predict);

}

return predict;

}

}

class modelandpara

{

int[] model;

Vector para;

public modelandpara(int[] model,Vector para)

{

this.model=model;

this.para=para;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值