博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 时间序列分析_时间序列数据的定义,读取与指数平滑(Java)
阅读量:4579 次
发布时间:2019-06-08

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

应上头的要求,需要实现以下指数平滑进行资源调度负载的预测,那就是用我最喜欢的Java做一下吧。

引用《计量经济学导论》的一句话:时间序列数据区别于横截面数据的一个明显特点是,时间序列数据集是按照时间顺序排列的。

显然,横截面数据被视为随机的结果,也就是说在总体中随机抽取样本。时间序列数据和横截面数据区别较为微妙,虽然它也满足随机性,但是这个序列标有时间脚标,依照时间有序,而不可以让时间随机排列导致错乱,我们不能让时间逆转重新开始这个过程。对于这样的序列我们称之为随机过程,或者时间序列过程。

对于时间序列,经常研究的一个问题就是预测,而指数平滑法是非常常见也常用的方法之一。这里对于二次指数平滑进行Java的实现(一次指数平滑包含在二次指数平滑之内)。其原理参照: https://cloud.tencent.com/developer/article/1058557 。这里就不再赘述。

数据也是参照我国1981年至1983年度平板玻璃月产量数据,以下文件保存为data2.txt

我国1981年至1983年度平板玻璃月产量数据1,240.3

2,222.8

3,243.1

4,222.2

5,222.6

6,218.7

7,234.5

8,248.6

9,261

10,275.3

11,269.4

12,291.2

13,301.9

14,285.5

15,286.6

16,260.5

17,298.5

18,291.8

19,267.3

20,277.9

21,303.5

22,313.3

23,327.6

24,338.3

25,340.37

26,318.51

27,336.85

28,326.64

29,342.9

30,337.53

31,320.09

32,332.17

33,344.01

34,335.79

35,350.67

36,367.37

对于以上数据,时间是int类型,而产量是double类型,为了便于读取,对于以上数据定义行数据类

packagetimeSeries;public classRowData {private inttime;private doublevalue;publicRowData() {//TODO Auto-generated constructor stub

}public RowData(int time, doublevalue) {super();this.time =time;this.value =value;

}public intgetTime() {returntime;

}public void setTime(inttime) {this.time =time;

}public doublegetValue() {returnvalue;

}public void setValue(doublevalue) {this.value =value;

}

}

然后定义文件读取类,读取所得数据为RowData数组

packageutilFile;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;importjava.util.ArrayList;importtimeSeries.RowData;public classFileOpts {public static ArrayList loadTxt(String dataPath, booleanishead) {

File file= newFile(dataPath);

FileReader fr;

ArrayList datas = new ArrayList();try{

fr= newFileReader(file);

BufferedReader br= newBufferedReader(fr);

String line= "";

String[] splitdata;if(ishead) {

br.readLine();

}while ((line = br.readLine()) != null) {

splitdata= line.split(",");

datas.add(new RowData(Integer.parseInt(splitdata[0]), Double.parseDouble(splitdata[1])));

}

br.close();

fr.close();

}catch(FileNotFoundException e) {//TODO Auto-generated catch block

e.printStackTrace();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}returndatas;

}

}

然后定义时间序列分析类,其实就是一个函数

packagetimeSeries;importjava.util.ArrayList;importjava.util.Iterator;public classExponentialSmoothing2 {public static double[][] expSmoothOrder2(int[] time, double[] values, double alpha, intpreNum) {int len =time.length;//返回一个汇总表

double[][] result = new double[len + preNum][7];//第一列时间,第二列实际观察值

for (int i = 0; i < len; i++) {

result[i][0] =time[i];

result[i][1] =values[i];

}

result[0][2] = values[0];

result[0][3] = result[0][2];//第三列一次指数平滑值,第四列二次指数平滑值//S1, S2 2, 3

for (int i = 1; i < len; i++) {

result[i][2] = alpha*values[i] + (1-alpha)*result[i-1][2];

result[i][3] = alpha*result[i][2] + (1-alpha)*result[i-1][3];

}//第五列a,第六列b//a, b 4, 5

for (int i = 1; i < len; i++) {

result[i][4] = 2*result[i][2] - result[i][3];

result[i][5] = alpha/(1-alpha) * (result[i][2] - result[i][3]);

}//第七列预测值F//F 6

for (int i = 1; i < len; i++) {

result[i+preNum][6] = result[i][4] + result[i][5] *preNum;

}returnresult;

}public static voidmain(String[] args) {//获取数据

ArrayList data = utilFile.FileOpts.loadTxt("src/timeSeries/data2.txt", true);int len =data.size();int[] time = new int[len];double[] values = new double[len];

Iterator it =data.iterator();int index = 0;while(it.hasNext()) {

RowData rowData=(RowData) it.next();

time[index]=rowData.getTime();

values[index]=rowData.getValue();

index++;

}//-------------------数据准备完毕---------------//System.out.println(Arrays.toString(time));//System.out.println(Arrays.toString(values));//------------------二次指数平滑---------------------

double[][] pre2= expSmoothOrder2(time, values, 0.5, 1);

System.out.printf("%6s, %6s, %6s, %6s, %6s, %6s, %6s\n", "time", "y", "s1", "s2", "a", "b", "F");for (int i = 0; i < values.length; i++) {

System.out.printf("%6.2f, %6.2f, %6.2f, %6.2f, %6.2f, %6.2f, %6.2f \n", pre2[i][0], pre2[i][1], pre2[i][2],

pre2[i][3], pre2[i][4], pre2[i][5], pre2[i][6]);

}//System.out.printf("%6d, %6d, %6d, %6d, %6d, %6d, %6.2f \n", 37, 0, 0, 0, 0, 0, pre2[values.length][3]);//System.out.printf("%6d, %6d, %6d, %6d, %6d, %6d, %6.2f \n", 38, 0, 0, 0, 0, 0, pre2[35][1] + pre2[35][2] * 2);//误差分析

double MSE = 0;double MAPE = 0;doubletemp;//System.out.println("pre2.length = "+pre2.length);

for (int i = 2; i < pre2.length-1; i++) {

MSE+= (pre2[i][1]-pre2[i][6])*(pre2[i][1]-pre2[i][6])/(pre2.length-2);

temp= (pre2[i][1]-pre2[i][6])/pre2[i][1];if (temp < 0) {

MAPE-= temp/(pre2.length-2);

}else{

MAPE+= temp/(pre2.length-2);

}//System.out.printf("iter: %d, y = %6.2f, F = %6.2f, MSE = %6.2f, MAPE = %6.5f\n", i, pre2[i][1], pre2[i][6], MSE, MAPE);

}

System.out.printf("MSE = %6.2f, MAPE = %6.5f\n", MSE, MAPE);if (MAPE < 0.05) {

System.out.println("百分误差小于0.05,预测精度较高");

}else{

System.out.println("预测误差超过了0.05");

}

}

}

执行结果:

51ac79f0cb5e7782e8bc77d16b729b65.png

1bf1fba093ad83bfdfec8cd37b44b12a.png

时间关系,温特线性和季节性指数平滑法闲了再补上,其实处理时间序列,用SPSS或R语言是很方便的,或者Matlab。

事实上还可以使用Java进行时间序列图像绘制,毕竟Java跑完python或matlab绘图还挺麻烦,Java也是可以实现的,只不过为了方便需要写一个庞大的API,日后闲下来再写一篇博客细说。

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

你可能感兴趣的文章
STL学习笔记(关联式容器)
查看>>
Android生成xml
查看>>
python入到到实战--第十章----文件
查看>>
FMDataBase 打开sqlite的外键约束功能
查看>>
Nmap 7.70新增功能——扫描主机所有IP
查看>>
二分图
查看>>
UVA10559&POJ1390 Blocks 区间DP
查看>>
《Linux内核》读书笔记 第十八章
查看>>
【AS3代码】擦窗户效果(也就是流行的妄撮游戏)
查看>>
[bzoj 3289] Mato的文件管理
查看>>
Flutter学习笔记(五)
查看>>
Linux zip命令详解
查看>>
vSphere的exsi root密码忘记了
查看>>
svn的安装过程
查看>>
pure的bug记录2
查看>>
NSCopying简析
查看>>
python抓取51CTO博客的推荐博客的全部博文,对标题分词存入mongodb中
查看>>
oracle 用户 角色 权限
查看>>
P2083 找人
查看>>
MySQL 分区知识点(三)
查看>>