提交 1c807f51 编写于 作者: 瀚海小松's avatar 瀚海小松

ARIMA is a open

上级
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="exlib/Jama-1.0.2.jar"/>
<classpathentry kind="lib" path="exlib/jdmp-complete-0.1.1-apidocs.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ARIMA</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
1156535
1291442
1359713
1374810
1416035
1528192
1521013
1455094
1371776
1369609
1392741
1455568
1534559
1517461
1384346
1405234
1413308
1425039
1470182
1516333
1542575
1416539
1377720
1358558
1400223
1458195
1543368
1501977
1357366
1369052
1447046
1676666
1628102
1605383
1530729
1471185
1466896
1487514
1501739
1562044
1689814
1725907
1503980
1506300
1494398
1493466
1540286
1653948
1654839
1527258
1566723
1517780
1518362
1559158
1659617
1657210
1490064
1484474
1462345
1480193
1518520
1620768
1760712
1803999
1510895
1507146
1557876
1552917
1686550
\ No newline at end of file
文件已添加
文件已添加
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=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 arima;
import arima.ARMAMath;
import java.util.*;
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归一化
* @param 待处理数据
* @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;
}
}
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=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 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);
}
}
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;
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 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=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 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(System.getProperty("user.dir")+"/data/ceshidata.txt"));
while(ino.hasNext())
{
arraylist.add(Double.parseDouble(ino.next()));
}
double[] dataArray=new double[arraylist.size()-1];
for(int i=0;i<arraylist.size()-1;i++)
dataArray[i]=arraylist.get(i);
//System.out.println(arraylist.size());
ARIMA arima=new ARIMA(dataArray);
int []model=arima.getARIMAmodel();
System.out.println("Best model is [p,q]="+"["+model[0]+" "+model[1]+"]");
System.out.println("Predict value="+arima.aftDeal(arima.predictValue(model[0],model[1])));
System.out.println("Predict error="+(arima.aftDeal(arima.predictValue(model[0],model[1]))-arraylist.get(arraylist.size()-1))/arraylist.get(arraylist.size()-1)*100+"%");
// String[] str = (String[])list1.toArray(new String[0]);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ino.close();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册