时间序列分析之 ARIMA 模型的JAVA实现

来源:互联网 发布:软件项目验收清单 编辑:程序博客网 时间:2024/05/18 03:53

最近要用ARIMA模型预测用户的数量变化,所以调研了一下ARIMA模型,最后用JAVA实现了ARIMA算法。


一、ARIMA原理

ARIMA的原理主要参考的是ARIMA原理。


二、JAVA实现

弄懂了原理,用JAVA进行了实现,主要参考的步骤是ARIMA实现步骤,JAVA代码如下

(1)AR类,用于构建AR模型
package arima;import java.util.*;public class AR {double[] stdoriginalData={};int p;ARMAMath armamath=new ARMAMath();/** * AR模型 * @param stdoriginalData * @param p //p为MA模型阶数 */public AR(double [] stdoriginalData,int p){this.stdoriginalData=new double[stdoriginalData.length];System.arraycopy(stdoriginalData, 0, this.stdoriginalData, 0, stdoriginalData.length);this.p=p;}/** * 返回AR模型参数 * @return */public Vector<double[]> ARmodel(){Vector<double[]> v=new Vector<double[]>();v.add(armamath.parcorrCompute(stdoriginalData, p, 0));return v;//得到了自回归系数}}
(2)MA类,用于构建MA模型
package arima;import java.util.Vector;import arima.ARMAMath;
public class MA {double[] stdoriginalData={};int q;ARMAMath armamath=new ARMAMath();/** MA模型 * @param stdoriginalData //预处理过后的数据 * @param q //q为MA模型阶数 */public MA(double [] stdoriginalData,int q){this.stdoriginalData=new double[stdoriginalData.length];System.arraycopy(stdoriginalData, 0, this.stdoriginalData, 0, stdoriginalData.length);this.q=q;}/** * 返回MA模型参数 * @return */public Vector<double[]> MAmodel(){Vector<double[]> v=new Vector<double[]>();v.add(armamath.getMApara(armamath.autocorGrma(stdoriginalData,q), q));return v;//拿到MA模型里面的参数值}}
(3)ARMA类,用于构建ARMA模型
package arima;import java.util.*;public class ARMA {double[] stdoriginalData={};int p;int q;ARMAMath armamath=new ARMAMath();/** * ARMA模型 * @param stdoriginalData * @param p,q //p,q为MA模型阶数 */public ARMA(double [] stdoriginalData,int p,int q){this.stdoriginalData=new double[stdoriginalData.length];System.arraycopy(stdoriginalData, 0, this.stdoriginalData, 0, stdoriginalData.length);this.p=p;this.q=q;}public Vector<double[]> ARMAmodel(){double[] arcoe=armamath.parcorrCompute(stdoriginalData, p, q);double[] autocorData=getautocorofMA(p, q, stdoriginalData, arcoe);double[] macoe=armamath.getMApara(autocorData, q);//得到MA模型里面的参数值Vector<double[]> v=new Vector<double[]>();v.add(arcoe);v.add(macoe);return v;}/** * 得到MA的自相关系数 * @param p * @param q * @param stdoriginalData * @param autoCordata * @return */public double[] getautocorofMA(int p,int q,double[] stdoriginalData,double[] autoRegress){int temp=0;double[] errArray=new double[stdoriginalData.length-p];int count=0;for(int i=p;i<stdoriginalData.length;i++){temp=0;for(int j=1;j<=p;j++)temp+=stdoriginalData[i-j]*autoRegress[j-1];errArray[count++]=stdoriginalData[i]-temp;//保存估计残差序列}return armamath.autocorGrma(errArray, q);}}
(4)ARIMA类,用于构建ARIMA模型
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<double[]> armaARMAcoe=new Vector<double[]>();Vector<double[]> bestarmaARMAcoe=new Vector<double[]>();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=7double []tempData=new double[originalData.length-7];for(int i=0;i<originalData.length-7;i++){tempData[i]=originalData[i+7]-originalData[i];}return tempData;}/** *  */public double[] preFirDif(double[] originalData) {// Difference:Peroid=1double []tempData=new double[originalData.length-1];for(int i=0;i<originalData.length-1;i++){tempData[i]=originalData[i+1]-originalData[i];}return tempData;}/** * 原始数据标准化处理:Z-Score归一化 * @param 待处理数据 * @return 归一化过后的数据 */public double[] preDealNor(double[] tempData){//Z-ScoreavgsumData=armamath.avgData(tempData);stderrDara=armamath.stderrData(tempData);for(int i=0;i<tempData.length;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<model.length;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<minAIC){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<double[]> para,double[] stdoriginalData,int type){double temp=0;double temp2=0;double sumerr=0;int p=0;//ar1,ar2,...,sig2int 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<n;k++){temp=0;for(int i=1;i<q;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<n;k++){temp=0;for(int i=0;i<p-1;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<n;k++){temp=0;temp2=0;for(int i=0;i<p-1;i++){temp+=arPara[i]*stdoriginalData[k-i-1];}for(int i=1;i<q;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]);elsetemp=(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<double[]> 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<originalDatafirDif.length;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<n;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<n;k++){temp=0;for(int i=0;i<p;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<n;k++){temp=0;temp2=0;for(int i=0;i<p;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<double[]> para;public modelandpara(int[] model,Vector<double[]> para){this.model=model;this.para=para;}}
(5)ARIMAiFlex类,用于构建AR模型
package arima;import java.util.Hashtable;import java.util.*;public class ARIMAiFlex {int             count=0;int []          model=new int[2];int[][]      modelOri=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}};modelandpara       mp=null;int  predictValuetemp=0;int   avgpredictValue=0;int[]       bestmodel=new int[2];double[][] predictErr=new double[7][modelOri.length];double  minpreDicterr=9999999;int  bestpreDictValue=0;int           bestDif=0;int            memory=10;double[] traindataArray=null;double         validate=0;double[]   predataArray=null;double[]     dataArrayPredict=null;Hashtable<String,Integer>  ht=new Hashtable<String,Integer>();Hashtable<String,Integer> ht2=new Hashtable<String,Integer>();double thresvalue=0;public ARIMAiFlex(double []dataArray){//模型训练System.out.println("begin to train...");Vector<int[]> trainResult=this.Train(dataArray);//预测数据初始化int tempPredict=0;System.out.println("begin to predict...");for(int i=0;i<trainResult.size();i++){thresvalue=0;System.out.println("predict..."+i+"/"+trainResult.size());tempPredict+=this.Predict(dataArray,memory,trainResult.get(i),0);}tempPredict=tempPredict/trainResult.size();System.out.println("tempPredict="+tempPredict);}public void preData(double[] dataArray,int type,int memory){//      ++//**********  //**********this.traindataArray=new double[dataArray.length-memory];System.arraycopy(dataArray, type, traindataArray, 0, traindataArray.length);this.validate=dataArray[traindataArray.length+type];//最后一个值作为训练时候的验证值。}public int Predict(double[] dataArray,int memory,int[] trainResult,double fanwei){if(memory<0)return (int)(dataArray[dataArray.length-1]+dataArray[dataArray.length-2])/2;this.predataArray=new double[dataArray.length-memory];System.arraycopy(dataArray, memory, predataArray, 0, predataArray.length);ARIMA arima=new ARIMA(predataArray,trainResult[0]); //对原始数据做几阶差分处理0,1,2,7//参数初始化int count=100;int predictValuetemp=0;//统计每种模型的预测平均值while(count-->0){mp=arima.getARIMAmodel(modelOri[trainResult[1]]);predictValuetemp+=arima.aftDeal(arima.predictValue(mp.model[0],mp.model[1],mp.para));}predictValuetemp/=100;//System.out.println("Predict value is:"+predictValuetemp);if(Math.abs(predictValuetemp-predataArray[predataArray.length-1])/predataArray[predataArray.length-1]>(0.3+fanwei)){thresvalue++;System.out.println("thresvalue="+thresvalue);//重新训练和预测//模型训练Vector<int[]> trainResult2=this.Train(dataArray);//预测数据初始化int tempPredict=0;for(int i=0;i<trainResult2.size();i++){tempPredict+=this.Predict(dataArray,(memory-5),trainResult2.get(i),0.1*thresvalue);}tempPredict=tempPredict/trainResult2.size();//System.out.println("tempPredict="+tempPredict);return tempPredict;}else{return predictValuetemp;}}public Vector<int[]> Train(double[] dataArray){int memory=60;//训练的时候预测的值的个数for(int datai=0;datai<memory;datai++){//System.out.println("train... "+datai+"/"+memory);this.preData(dataArray, datai,memory);//准备训练数据for(int diedai=0;diedai<7;diedai++){ARIMA arima=new ARIMA(traindataArray,diedai); //对原始数据做几阶差分处理0,1,2,7//统计每种模型的预测平均值for(int modeli=0;modeli<modelOri.length;modeli++){//参数初始化count=100;predictValuetemp=0;while(count-->0){mp=arima.getARIMAmodel(modelOri[modeli]);predictValuetemp+=arima.aftDeal(arima.predictValue(mp.model[0],mp.model[1],mp.para));//System.out.println("predictValuetemp"+predictValuetemp);}predictValuetemp/=100;//计算训练误差predictErr[diedai][modeli]+=Math.abs(100*(predictValuetemp-validate)/validate);}}}double minvalue=10000000;int tempi=0;int tempj=0;Vector<int[]> bestmodelVector=new Vector<int[]>();int[][] flag=new int[7][modelOri.length];for(int ii=0;ii<5;ii++){minvalue=10000000;for(int i=0;i<predictErr.length;i++) {for(int j=0;j<predictErr[i].length;j++){if(flag[i][j]==0){if(predictErr[i][j]<minvalue){minvalue=predictErr[i][j];tempi=i;tempj=j;flag[i][j]=1;}}}}bestmodelVector.add(new int[]{tempi,tempj});//System.out.println("best model:Dif="+tempi+"..."+"index of model="+tempj);System.out.println("ARIMAAvgPredictErr="+minvalue/memory);}//for(int i=0;i<predictErr.length;i++)//for(int j=0;j<predictErr[i].length;j++)//{//System.out.println("Dif "+i+" Model index"+j+"= "+predictErr[i][j]/memory);//}//System.out.println("--tempi="+tempi+"~~~"+"tempj="+tempj);System.out.println("----------------------------------------");return bestmodelVector;}}


(6)ARMAMath类,常见的数据计算任务
package arima;import Jama.Matrix;public class ARMAMath{public double avgData(double[] dataArray){return this.sumData(dataArray)/dataArray.length;}public double sumData(double[] dataArray){double sumData=0;for(int i=0;i<dataArray.length;i++){sumData+=dataArray[i];}return sumData;}public double stderrData(double[] dataArray){return Math.sqrt(this.varerrData(dataArray));}public double varerrData(double[] dataArray){double variance=0;double avgsumData=this.avgData(dataArray);for(int i=0;i<dataArray.length;i++){dataArray[i]-=avgsumData;variance+=dataArray[i]*dataArray[i];}return variance/dataArray.length;//variance error;}/** * 计算自相关的函数 Tho(k)=Grma(k)/Grma(0) * @param dataArray 数列 * @param order 阶数 * @return */public double[] autocorData(double[] dataArray,int order){double[] autoCor=new double[order+1];double varData=this.varerrData(dataArray);//标准化过后的方差for(int i=0;i<=order;i++){autoCor[i]=0;for(int j=0;j<dataArray.length-i;j++){autoCor[i]+=dataArray[j+i]*dataArray[j];}autoCor[i]/=(dataArray.length-i);autoCor[i]/=varData;}return autoCor;}/** * Grma * @param dataArray * @param order * @return 序列的自相关系数 */public double[] autocorGrma(double[] dataArray,int order){double[] autoCor=new double[order+1];for(int i=0;i<=order;i++){autoCor[i]=0;for(int j=0;j<dataArray.length-i;j++){autoCor[i]+=dataArray[j+i]*dataArray[j];}autoCor[i]/=(dataArray.length-i);}return autoCor;}/** * 求偏自相关系数 * @param dataArray * @param order * @return */public double[] parautocorData(double[] dataArray,int order){double parautocor[]=new double[order];for(int i=1;i<=order;i++)    {parautocor[i-1]=this.parcorrCompute(dataArray, i,0)[i-1];    }return parautocor;}/** * 产生Toplize矩阵 * @param dataArray * @param order * @return */public double[][] toplize(double[] dataArray,int order){//返回toplize二维数组double[][] toplizeMatrix=new double[order][order];double[] atuocorr=this.autocorData(dataArray,order);for(int i=1;i<=order;i++){int k=1;for(int j=i-1;j>0;j--){toplizeMatrix[i-1][j-1]=atuocorr[k++];}toplizeMatrix[i-1][i-1]=1;int kk=1;for(int j=i;j<order;j++){toplizeMatrix[i-1][j]=atuocorr[kk++];}}return toplizeMatrix;}/** * 解MA模型的参数 * @param autocorData * @param q * @return */public double[] getMApara(double[] autocorData,int q){double[] maPara=new double[q+1];//第一个存放噪声参数,后面q个存放ma参数sigma2,ma1,ma2...double[] tempmaPara=new double[q+1];double temp=0;boolean iterationFlag=true;//解方程组//迭代法解方程组maPara[0]=1;//初始化int count=10000;while(iterationFlag&&count-->0){temp=0;for(int i=1;i<maPara.length;i++){temp+=maPara[i]*maPara[i];}tempmaPara[0]=autocorData[0]/(1+temp);for(int i=1;i<maPara.length;i++){temp=0;for(int j=1;j<maPara.length-i;j++){temp+=maPara[j]*maPara[j+i];}tempmaPara[i]=-(autocorData[i]/tempmaPara[0]-temp);}iterationFlag=false;for(int i=0;i<maPara.length;i++){if(Math.abs(maPara[i]-tempmaPara[i])>0.00001){iterationFlag=true;break;}}System.arraycopy(tempmaPara, 0, maPara, 0, tempmaPara.length);}return maPara;}/** * 计算自回归系数 * @param dataArray * @param p * @param q * @return */public double[] parcorrCompute(double[] dataArray,int p,int q){double[][] toplizeArray=new double[p][p];//p阶toplize矩阵;double[] atuocorr=this.autocorData(dataArray,p+q);//返回p+q阶的自相关函数double[] autocorrF=this.autocorGrma(dataArray, p+q);//返回p+q阶的自相关系数数for(int i=1;i<=p;i++){int k=1;for(int j=i-1;j>0;j--){toplizeArray[i-1][j-1]=atuocorr[q+k++];}toplizeArray[i-1][i-1]=atuocorr[q];int kk=1;for(int j=i;j<p;j++){toplizeArray[i-1][j]=atuocorr[q+kk++];}}    Matrix toplizeMatrix = new Matrix(toplizeArray);//由二位数组转换成二维矩阵    Matrix toplizeMatrixinverse=toplizeMatrix.inverse();//矩阵求逆运算    double[] temp=new double[p];    for(int i=1;i<=p;i++)    {    temp[i-1]=atuocorr[q+i];    }    Matrix autocorrMatrix=new Matrix(temp, p);Matrix parautocorDataMatrix=toplizeMatrixinverse.times(autocorrMatrix); //  [Fi]=[toplize]x[autocorr]';//矩阵计算结果应该是按照[a b c]'  列向量存储的//System.out.println("row="+parautocorDataMatrix.getRowDimension()+"  Col="+parautocorDataMatrix.getColumnDimension());//parautocorDataMatrix.print(p, 2);//(输出几行,小数点后保留位数)//System.out.println(parautocorDataMatrix.get(p-1,0));double[] result=new double[parautocorDataMatrix.getRowDimension()+1];for(int i=0;i<parautocorDataMatrix.getRowDimension();i++){result[i]=parautocorDataMatrix.get(i,0);}//估算sigmat2double sum2=0;for(int i=0;i<p;i++)for(int j=0;j<p;j++){sum2+=result[i]*result[j]*autocorrF[Math.abs(i-j)];}result[result.length-1]=autocorrF[0]-sum2; //result数组最后一个存储干扰估计值return result;   //返回0列的最后一个就是k阶的偏自相关系数 pcorr[k]=返回值}}
(7)test1,用于导入数据进行测试
package arima;import java.io.*;import java.util.ArrayList;import java.util.Scanner;
public class test1 {public static void main(String args[]){Scanner ino=null;try {/*********************************************************/ArrayList<Double> arraylist=new ArrayList<Double>();ino=new Scanner(new File("E:\\work\\Arima\\Arima\\Data\\ceshidata.txt"));while(ino.hasNext()){arraylist.add(Double.parseDouble(ino.next()));}double[] dataArray=new double[arraylist.size()]; for(int i=0;i<dataArray.length;i++)dataArray[i]=arraylist.get(i);ARIMAiFlex myarima=new ARIMAiFlex(dataArray);currentAlgorithm cc=new currentAlgorithm(dataArray);/*********************************************************/} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ino.close();}}}

PS:
附上一个代码的链接,希望能够对需要的朋友有一点点帮助,收取了一分的资源下载分,算是对作者的一点鼓励,ARIMA JAVA实现,如有问题,可以在我的资料中找到联系方式,望不吝赐教!

另外,完整的代码已经托管到了gitHub:     ARIMA github

9 0
原创粉丝点击