看著已經存在的曲線圖數據,想預估下后面曲線圖的數據。
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號,后面一周的數據是根據之前一個月的數據預估的趨勢。
頁面上的趨勢圖只顯示前后一周。