时间序列分析之 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,用于导入数据进行测试
PS:
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
另外,完整的代码已经托管到了gitHub: ARIMA github
9 0
- 时间序列分析之 ARIMA 模型的JAVA实现
- 时间序列分析之ARIMA模型预测
- 时间序列分析--ARIMA模型
- R语言时间序列分析之ARIMA模型预测
- 时间序列分析之ARIMA模型预测__R篇
- R语言 时间序列分析之ARIMA模型预测
- ARIMA时间序列分析
- ARIMA时间序列分析
- [python] 时间序列分析之ARIMA
- [python] 时间序列分析之ARIMA
- 时间序列分析之ARIMA上手-Python
- [python] 时间序列分析之ARIMA
- 时间序列分析之holtwinters和ARIMA
- [python] 时间序列分析之ARIMA
- python 时间序列分析之ARIMA
- 时间序列的分析和预测ARIMA
- 时间序列ARIMA模型相关
- 数据分析技术:时间序列分析的AR/MA/ARMA/ARIMA模型体系
- iOS学习:调用相机,选择图片上传,带预览功能 ,修改界面为中文
- 开发环境错误(很不注意就会出现的错误)
- HDOJ 1671 Phone List(字典树)
- 100个iOS开发/设计面试题汇总,你将如何作答?
- java概念
- 时间序列分析之 ARIMA 模型的JAVA实现
- LeetCode 3Sum
- STRUTS框架(web.xml,struts.xml,XXXvalidation.xml配置信息)个人心得
- android activity(通过一个按钮打开另一个acticity总结)
- Jsoncpp的使用
- 回调函数和接口回调的理解,有图更给力!
- 解决Ubuntu中update的问题(Reading package lists... Error!)
- MFC 视图类(CView)介绍
- 常用的Java代码汇总