arma模型 java_时间序列分析之 ARIMA 模型的JAVA实现
最近要用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 ARmodel()
{
Vector v=new Vector();
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 MAmodel()
{
Vector v=new Vector();
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 ARMAmodel()
{
double[] arcoe=armamath.parcorrCompute(stdoriginalData, p, q);
double[] autocorData=getautocorofMA(p, q, stdoriginalData, arcoe);
double[] macoe=armamath.getMApara(autocorData, q);//得到MA模型里面的参数值
Vector v=new Vector();
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
{
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 armaARMAcoe=new Vector();
Vector bestarmaARMAcoe=new Vector();
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=7
double []tempData=new double[originalData.length-7];
for(int i=0;i
{
tempData[i]=originalData[i+7]-originalData[i];
}
return tempData;
}
/**
*
*/
public double[] preFirDif(double[] originalData)
{
// Difference:Peroid=1
double []tempData=new double[originalData.length-1];
for(int i=0;i
{
tempData[i]=originalData[i+1]-originalData[i];
}
return tempData;
}
/**
* 原始数据标准化处理:Z-Score归一化
* @param 待处理数据
* @return 归一化过后的数据
*/
public double[] preDealNor(double[] tempData)
{
//Z-Score
avgsumData=armamath.avgData(tempData);
stderrDara=armamath.stderrData(tempData);
for(int i=0;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
{
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
{
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 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=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
{
temp=0;
for(int i=1;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
{
temp=0;
for(int i=0;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
{
temp=0;
temp2=0;
for(int i=0;i
{
temp+=arPara[i]*stdoriginalData[k-i-1];
}
for(int i=1;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]);
else
temp=(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 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
//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
{
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
{
temp=0;
for(int i=0;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
{
temp=0;
temp2=0;
for(int i=0;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 para;
public modelandpara(int[] model,Vector 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 ht=new Hashtable();
Hashtable ht2=new Hashtable();
double thresvalue=0;
public ARIMAiFlex(double []dataArray)
{
//模型训练
System.out.println("begin to train...");
Vector trainResult=this.Train(dataArray);
//预测数据初始化
int tempPredict=0;
System.out.println("begin to predict...");
for(int i=0;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 trainResult2=this.Train(dataArray);
//预测数据初始化
int tempPredict=0;
for(int i=0;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 Train(double[] dataArray)
{
int memory=60;//训练的时候预测的值的个数
for(int datai=0;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
{
//参数初始化
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 bestmodelVector=new Vector();
int[][] flag=new int[7][modelOri.length];
for(int ii=0;ii<5;ii++)
{minvalue=10000000;
for(int i=0;i
{
for(int j=0;j
{
if(flag[i][j]==0)
{
if(predictErr[i][j]
{
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
//for(int j=0;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
{
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[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
{
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
{
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
{
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
{
temp+=maPara[i]*maPara[i];
}
tempmaPara[0]=autocorData[0]/(1+temp);
for(int i=1;i
{
temp=0;
for(int j=1;j
{
temp+=maPara[j]*maPara[j+i];
}
tempmaPara[i]=-(autocorData[i]/tempmaPara[0]-temp);
}
iterationFlag=false;
for(int i=0;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
{
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
{
result[i]=parautocorDataMatrix.get(i,0);
}
//估算sigmat2
double sum2=0;
for(int i=0;i
for(int j=0;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 arraylist=new ArrayList();
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[i]=arraylist.get(i);
ARIMAiFlex myarima=new ARIMAiFlex(dataArray);
currentAlgorithm cc=new currentAlgorithm(dataArray);
/*********************************************************/
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ino.close();
}
}
}
原文:http://blog.csdn.net/u010691898/article/details/43151171
arma模型 java_时间序列分析之 ARIMA 模型的JAVA实现相关推荐
- arima模型_时间序列分析(R)‖ARIMA模型预测实例
背景 十九大报告,对教育方面做出了详细说明.近年来,随着研究生招生规模的逐渐扩大,报名参加硕士研究生考试的人数也逐年增加.大多数关于研究生的文章是以研究生的现状.研究生的教育.研究生的就业等方面为主题 ...
- R语言时间序列分析之ARIMA模型预测
R语言时间序列分析之ARIMA模型预测 今天学习ARIMA预测时间序列. 指数平滑法对于预测来说是非常有帮助的,而且它对时间序列上面连续的值之间相关性没有要求.但是,如果你想使用指数平滑法计算出预测区 ...
- SPSS分析技术:时间序列分析的ARIMA模型;考虑各种促销因素的服装销售额预测
基础准备 学习积累的过程,是量变到质变的过程.草堂君在前面介绍了时间序列分析的多篇文章,这些文章的安排都是按照循序渐进学习时间序列分析的过程来安排的,大家可以点击下方的链接回顾: 数据分析技术:时间序 ...
- 时间序列分析方法——ARIMA模型案例
目录 一.方法简介 数据示例 二.ARIMA模型python建模过程[^2] 1 添加基础库 2 读取数据 3 绘制时间序列图 4 自相关 5 平稳性检验 6 时间序列的差分d 7 合适的p,q 8 ...
- r语言没有forecast这个函数_R语言学习日记——时间序列分析之ARIMA模型预测
指数平滑法对于预测来说是非常有帮助的,而且它对时间序列上面连续的值之间相关性没有要求.但是,如果你想使用指数平滑法计算出预测区间,那么预测误差必须是不相关的, 而且必须是服从零均值. 方差不变的正态分 ...
- Eviews7.2模型建模与预测时间序列分析(ARIMA 模型的建立与预测)
1.模型识别 (1)数据录入 打开 Eviews 软件,选择―File菜单中的―New–Workfile|选项,在"Workfile structure type" 栏选择&quo ...
- Python通过ARIMA模型进行时间序列分析预测
ARIMA模型预测 时间序列分析预测就是在已有的和时间有关的数据序列的基础上构建其数据模型并预测其未来的数据,例如航空公司的一年内每日乘客数量.某个地区的人流量,这些数据往往具有周期性的规律.如下图所 ...
- R语言ARIMA集成模型预测时间序列分析
全文链接:http://tecdat.cn/?p=18493 本文我们使用4个时间序列模型对每周的温度序列建模.第一个是通过auto.arima获得的,然后两个是SARIMA模型,最后一个是Buys- ...
- 【机器学习】数据挖掘实战:金融贷款分类模型和时间序列分析
今天给大家带来一个企业级数据挖掘实战项目,金融贷款分类模型和时间序列分析,文章较长,建议收藏! 如果本文对你有所帮助,记得文末点赞和在看,也可分享给你需要的朋友- 项目背景 银行和其他金融贷款机构经常 ...
最新文章
- CSS3 Box-shadow 阴影效果用法
- keras-vis可视化特征
- 攻防世界-web-unfinish-从0到1的解题历程writeup
- http 测试工具_20+最好的开源自动化测试工具
- 【转】pacs定位线_C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法
- 华为新系统鸿蒙能互通吗,「连接」万物的鸿蒙,能拯救华为手机吗?
- MS SQL 监控数据/日志文件增长
- UVa1368 - DNA Consensus String
- IntelliJ IDEA个人许可证赠品报告和获奖者
- CC学iOS杂记 001_Device
- JAVA RMI远程方法调用简单实例
- 关于JavaScript中apply与call的用法意义及区别(转)
- Activity设置竖屏显示
- OpenCV中出现“Microsoft C++ 异常: cv::Exception,位于内存位置 0x0000005C8ECFFA80 处。”的异常
- 2022-2028年中国SPA水疗行业市场深度分析及投资前景展望报告
- mysql sql 列变成横向_SQL 统计 字段 竖向转横向 (行转列)显示
- mysql修改配置文件进行优化
- WPS添加下划线,文字尾部不显示下划线问题解决(一个So stupid问题)
- 【Redis】Redis的五大数据类型
- L1 正则化和L2正则化