看着已经存在的曲线图数据,想预估下后面曲线图的数据。
import java.util.Vector;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=stdoriginalData;this.p=p;}/*** 返回AR模型参数* @return*/public Vector<double[]> ARmodel(){Vector<double[]> v=new Vector<double[]>();v.add(armamath.parcorrCompute(stdoriginalData, p, 0));return v;//得到了自回归系数//还要估计方差项吗?}}
package com.xxx.xxx.xxx.util.arima;import com.alibaba.fastjson.JSON;import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;public class ARIMA {double[] originalData={};ARMAMath armamath=new ARMAMath();double stderrDara=0;double avgsumData=0;Vector<double[]> armaARMAcoe=new Vector<double[]>();Vector<double[]> bestarmaARMAcoe=new Vector<double[]>();/*** 构造函数* @param originalData 原始时间序列数据*/public ARIMA(double [] originalData){this.originalData=originalData;}/*** 原始数据标准化处理:一阶季节性差分* @return 差分过后的数据*/public double[] preDealDif(){//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;}/*** 原始数据标准化处理:Z-Score归一化* 待处理数据* @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;}/*** 得到ARMA模型=[p,q]* @return ARMA模型的阶数信息*/public int[] getARIMAmodel(){double[] stdoriginalData=this.preDealDif();//原始数据差分处理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}};//,{4,0},{0,4},{4,1},{1,4},{4,2},{2,4},{4,3},{3,4},{4,4}};//对8种模型进行迭代,选出AIC值最小的模型作为我们的模型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);//System.out.println("AIC of these model="+temp);if (temp<minAIC){bestModelindex=i;minAIC=temp;bestarmaARMAcoe=armaARMAcoe;}}return model[bestModelindex];}/*** 计算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=para.get(0);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=para.get(0);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=para.get(0);double[] maPara=para.get(1);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){//System.out.println("predictBeforeDiff="+predictValue);return (int)(predictValue+originalData[originalData.length-7]);}/*** 进行一步预测* @param p ARMA模型的AR的阶数* @param q ARMA模型的MA的阶数* @return 预测值*/public int predictValue(int p,int q){int predict=0;double[] stdoriginalData=this.preDealDif();int n=stdoriginalData.length;double temp=0,temp2=0;double[] err=new double[q+1];Random random=new Random();if(p==0){double[] maPara=bestarmaARMAcoe.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); //产生预测}else if(q==0){double[] arPara=bestarmaARMAcoe.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);}else{double[] arPara=bestarmaARMAcoe.get(0);double[] maPara=bestarmaARMAcoe.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);}return predict;}/*** 计算MA模型的参数* @param autocorData 自相关系数Grma* @param q MA模型的阶数* @return 返回MA模型的参数*/public double[] getMApara(double[] autocorData,int q){double[] maPara=new double[q+1];//第一个存放噪声参数,后面q个存放ma参数sigma2,ma1,ma2...double[] tempmaPara=maPara;double temp=0;boolean iterationFlag=true;//解方程组//迭代法解方程组//System.out.println("autocorData[0]"+autocorData[0]);while(iterationFlag){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(maPara[i]!=tempmaPara[i]){iterationFlag=true;break;}}maPara=tempmaPara;}return maPara;}public static int[] generator(int size, List<Double> arraylist){int[] returnArray=new int[size];for (int i = 0; i <size ; i++) {double[] dataArray=new double[arraylist.size()];for(int j=0;j<arraylist.size()-1;j++) {dataArray[j] = arraylist.get(j);}//使用当前数据训练ARIMA模型ARIMA arima=new ARIMA(dataArray);//获得ARIM模型int []model=arima.getARIMAmodel();//System.out.println("Best model is [p,q]="+"["+model[0]+" "+model[1]+"]");//System.out.println("最佳模型是[p,q]="+"["+model[0]+" "+model[1]+"]");int deal = arima.aftDeal(arima.predictValue(model[0], model[1]));//System.out.println("Predict value="+deal);//System.out.println("预测值="+deal);//System.out.println("Predict error="+(deal-arraylist.get(arraylist.size()-1))/arraylist.get(arraylist.size()-1)*100+"%");//System.out.println("预测差值="+(deal-arraylist.get(arraylist.size()-1))/arraylist.get(arraylist.size()-1)*100+"%");arraylist.add(deal+0.0);returnArray[i]=deal;}//System.out.println(JSON.toJSON(arraylist));//System.out.println(JSON.toJSON(returnArray));return returnArray;}public static int[] arimaLists(List<Double> arraylist) {if (arraylist.size()<10){System.out.println("创建ARIMA模型数据最少10条");return new int[]{0,0,0,0,0,0,0};}int[] ints = generator(7, arraylist);return ints;}
}
package com.xxx.xxx.xxx.util.arima;import java.util.ArrayList;
import java.util.Vector;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=stdoriginalData;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模型里面的参数值
// for(int i=0;i<macoe.length;i++)
// {
// System.out.println(macoe[i]);
// }
// System.out.println();Vector<double[]> v=new Vector<double[]>();v.add(arcoe);v.add(macoe);return v;}/*** 得到MA的自相关系数* @param p* @param q* @param stdoriginalData* @param autoRegress* @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);}}
package com.xxx.xxx.xxx.util.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;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=maPara;double temp=0;boolean iterationFlag=true;//解方程组//迭代法解方程组maPara[0]=1;//初始化while(iterationFlag){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]/maPara[0]-temp);}iterationFlag=false;for(int i=0;i<maPara.length;i++){if(maPara[i]!=tempmaPara[i]){iterationFlag=true;break;}}maPara=tempmaPara;}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]=返回值}}
package com.xxx.xxx.xxx.util.arima;import java.util.Vector;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=stdoriginalData;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模型里面的参数值}}
package com.xxx.xxx.xxx.util.arima;import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;import static com.alibaba.druid.sql.ast.SQLPartitionValue.Operator.List;public class Test1 {public static void main(String args[]) {
// extracted();ArrayList<Double> arraylist = new ArrayList<Double>();arraylist.add(1.0d);arraylist.add(2.0d);arraylist.add(3.0d);arraylist.add(4.0d);arraylist.add(5.0d);arraylist.add(6.0d);arraylist.add(7.0d);arraylist.add(8.0d);arraylist.add(8.0d);arraylist.add(8.0d);arraylist.add(8.0d);arraylist.add(8.0d);int[] ints = ARIMA.arimaLists(arraylist);System.err.println(Arrays.toString(ints));}}
以上是示例,传入已有的参数预估后面的值
当前时间为7.2号,后面一周的数据是根据之前一个月的数据预估的趋势。
页面上的趋势图只显示前后一周。