应上头的要求,需要实现以下指数平滑进行资源调度负载的预测,那就是用我最喜欢的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类型,为了便于读取,对于以上数据定义行数据类

package timeSeries;

public class RowData {

    private int time;
private double value; public RowData() {
// TODO Auto-generated constructor stub
} public RowData(int time, double value) {
super();
this.time = time;
this.value = value;
} public int getTime() {
return time;
} public void setTime(int time) {
this.time = time;
} public double getValue() {
return value;
} public void setValue(double value) {
this.value = value;
} }

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

package utilFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList; import timeSeries.RowData; public class FileOpts { public static ArrayList<RowData> loadTxt(String dataPath, boolean ishead) {
File file = new File(dataPath);
FileReader fr;
ArrayList<RowData> datas = new ArrayList<RowData>();
try {
fr = new FileReader(file);
BufferedReader br = new BufferedReader(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();
} return datas;
} }

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

package timeSeries;

import java.util.ArrayList;

import java.util.Iterator;

public class ExponentialSmoothing2 {

    public static double[][] expSmoothOrder2(int[] time, double[] values, double alpha, int preNum) {
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;
}
return result;
} public static void main(String[] args) {
// 获取数据
ArrayList<RowData> data = utilFile.FileOpts.loadTxt("src/timeSeries/data2.txt", true);
int len = data.size();
int[] time = new int[len];
double[] values = new double[len];
Iterator<RowData> 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;
double temp;
// 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");
}
} }

执行结果:

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

时间序列数据的定义,读取与指数平滑(Java)的更多相关文章

  1. 时间序列挖掘-预测算法-三次指数平滑法(Holt-Winters)——三次指数平滑算法可以很好的保存时间序列数据的趋势和季节性信息

    from:http://www.cnblogs.com/kemaswill/archive/2013/04/01/2993583.html 在时间序列中,我们需要基于该时间序列当前已有的数据来预测其在 ...

  2. Holt Winter 指数平滑模型

    1 指数平滑法 移动平均模型在解决时间序列问题上简单有效,但它们的计算比较难,因为不能通过之前的计算结果推算出加权移动平均值.此外,移动平均法不能很好的处理数据集边缘的数据变化,也不能应用于现有数据集 ...

  3. OpenStack/Gnocchi简介——时间序列数据聚合操作提前计算并存储起来,先算后取的理念

    先看下 http://www.cnblogs.com/bonelee/p/6236962.html 这里对于环形数据库的介绍,便于理解归档这个操作! 转自:http://blog.sina.com.c ...

  4. R语言与数据分析之九:时间内序列--HoltWinters指数平滑法

    今天继续就指数平滑法中最复杂的一种时间序列:有增长或者减少趋势而且存在季节性波动的时间序列的预測算法即Holt-Winters和大家分享.这样的序列能够被分解为水平趋势部分.季节波动部分,因此这两个因 ...

  5. geotrellis使用(二十三)动态加载时间序列数据

    目录 前言 实现方法 总结 一.前言        今天要介绍的绝对是华丽的干货.比如我们从互联网上下载到了一系列(每天或者月平均等)的MODIS数据,我们怎么能够对比同一区域不同时间的数据情况,采用 ...

  6. 使用excel计算指数平滑和移动平均

      指数平滑法 原数数据如下: 点击数据——数据分析 选择指数平滑 最一次平滑 由于我们选择的区域是B1:B22,第一个单元格“钢产量”,被当做标志,所以我们应该勾选标志.当我们勾选了标志后,列中的第 ...

  7. Unity3D学习(二):使用JSON进行对象数据的存储读取

    前言 前段时间完成了自己的小游戏Konster的制作,今天重新又看了下代码.原先对关卡解锁数据的存储时用了Unity自带的PlayerPref(字典式存储数据). 读取关卡数据的代码: void Aw ...

  8. mysql 生成时间序列数据 - 存储过程

    由于时间自动转换为int值, 做一步转化,也可在调用时处理 use `test`; CREATE table test.test1 as SELECT state, id, `规格条码`, `色号条码 ...

  9. C# 结构体和List<T>类型数据转Json数据保存和读取

    C#  结构体和List<T>类型数据转Json数据保存和读取 一.结构体转Json public struct FaceLibrary { public string face_name ...

随机推荐

  1. 1.入门篇十分钟了解Spring Cloud

    文章目录 Spring Cloud入门系列汇总 为什么需要学习Spring Cloud 什么是Spring Cloud 设计目标与优缺点 设计目标 优缺点 Spring Cloud发展前景 整体架构 ...

  2. 关于IPA文件重签名后如何跟踪管理APP的技术探讨和实践演示

    前言:开发iOS的朋友都知道,在功能开发完成后,我们就会用申请的苹果账号在后台做证书配置,然后提交到AppStore,但是也有部分APP我们不需要提交到AppStore,比如内部测试用的APP.定制给 ...

  3. axio跨域请求,vue中的config的配置项。

    这是我用 vue cli 脚手架搭建的跨域.以上是可以请求到的.

  4. JS关闭chorme页面

    百度到的很多答案都失效了,这是收集一位博主的(https://www.jianshu.com/p/9dc2752194b8),目前可以使用. 代价是打开一个空白页面,能实现无提示关闭当前页面.不需要是 ...

  5. php 数组与URL相互转换

    php为了数组与url参数相互转换提供了两个函数: 1,数组转换为带&的URL的字符串 例如: $arr =['title'=>'我是小白','name'=>'真的很白','tex ...

  6. docker19.03制作一个基于centos8的带有nfs4服务的镜像

    一,下载centos的image 1,下载centos最新image [root@localhost ~]# docker pull centos 2,查看是否成功下载到本地image [root@l ...

  7. PHP-fpm启动后没有查询到9000端口的问题

    Nginx与php-fpm通信的两种方式:tcp socket 和 Unix socket. Unix socket 是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信.这种方式需要再ng ...

  8. Spring Boot入门系列(二十一)如何优雅的设计 Restful API 接口版本号,实现 API 版本控制!

    前面介绍了Spring Boot 如何快速实现Restful api 接口,并以人员信息为例,设计了一套操作人员信息的接口.不清楚的可以看之前的文章:https://www.cnblogs.com/z ...

  9. 【机器学习 Azure Machine Learning】使用VS Code登录到Linux VM上 (Remote-SSH), 及可直接通过VS Code编辑VM中的文件

    问题描述 在平常的工作习惯中,如果使用VS Code做脚本的开发,是一个非常好用的工具,现在也可以通过VS Code的不同方式来连接到Linux VM中(ssh), 第一种是VS Code的Termi ...

  10. Baolu CSV Data Set Config

    1.背景 大家在平常使用JMeter测试工具时,对CSV Data Set Config 配置元件肯定不会陌生.如果我们的压测场景涉及到数据库更新操作(如:转账接接口)则需要对参数化数据进行分块,可就 ...