看着已经存在的曲线图数据,想预估下后面曲线图的数据。
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=7
double []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-Score
avgsumData=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,...,sig2
int 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);
}
//估算sigmat2
double 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号,后面一周的数据是根据之前一个月的数据预估的趋势。
页面上的趋势图只显示前后一周。