博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ARIMA模型 预测时间序列 JAVA实现
阅读量:4283 次
发布时间:2019-05-27

本文共 11613 字,大约阅读时间需要 38 分钟。

最近要用ARIMA模型预测用户的数量变化,所以调研了一下ARIMA模型,最后用JAVA实现了ARIMA算法。

一、ARIMA原理

ARIMA的原理主要参考的是。

二、JAVA实现

弄懂了原理,用JAVA进行了实现,主要参考的步骤是, 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

(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
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
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
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
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
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
(0.3+fanwei)) { thresvalue++; System.out.println("thresvalue="+thresvalue); //重新训练和预测 //模型训练 Vector
trainResult2=this.Train(dataArray); //预测数据初始化 int tempPredict=0; for(int i=0;i
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

(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
0;j--) {
toplizeMatrix[i-1][j-1]=atuocorr[k++]; } toplizeMatrix[i-1][i-1]=1; int kk=1; for(int j=i;j
0) {
temp=0; for(int i=1;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

(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

完整代码托管在gitHub:

转载地址:http://midgi.baihongyu.com/

你可能感兴趣的文章
Windows共享权限和相关管理
查看>>
页面制作HTML+CSS基础乱炖
查看>>
验证最小化可行产品(MVP)的15种方法
查看>>
JVM实用参数系列
查看>>
系统运维(灰度发布)
查看>>
几款强大的PPT制作辅助软件
查看>>
程序员应该常问常思考
查看>>
谈谈高并发系统的限流
查看>>
大数据计算框架与平台--深入浅出分析
查看>>
图像语义分割技术-深度卷积网络图像识别
查看>>
浅谈Windows共享网络热点开发
查看>>
前端代码日常收集与监控
查看>>
任务,行动,目标、绩效管理,计划
查看>>
大数据和机器学习等基本概念
查看>>
从url到页面展现,这之中发生了什么?
查看>>
不用写一行代码,可视化ssh登录攻击来源
查看>>
Python入门深度学习完整指南
查看>>
使用 Log4j 将日志记录到远程系统
查看>>
JS与多线程
查看>>
Java Spring中同时访问多种不同数据库
查看>>