Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >跨站数据测试

来了来了!趋势预测算法大PK!

作者 | 王哲

责编 | Carol

头图 | CSDN 付费下载自视觉中国

趋势预测在很多应用场景中都会起到至关重要的作用,比如淘宝商家会考虑库存量应该保持在多少才能够满足客户需求,商场希望得知假期会迎来多大的客流量以安排系列活动,机场想要预测五一黄金周会有多大的客运量来做相应的应急部署等。在智能运维领域,趋势预测同样具有一定的理论意义和实际应用价值。

趋势预测在运维场景中的应用背景

在实时监控系统中会采集到大量的数据,有些数据具有周期性等时间特征,也称之为时间序列。如果能挖掘出时间序列中所蕴含的信息,实现辅助人工决策,甚至是自动决策,都会为运维工作带来事半功倍的效果。

比如KPI异常检测可以衡量服务的健康程度,分析出CPU、交易量、响应时间等指标的历史规律后,设置动态阈值,得到更加准确的异常报警,减少漏报误报情况的发生,提高应急响应效率;通过对历史事件单的分析,预测出下次系统告警可能发生的时间或者指定时间内可能发生告警的系统等,就可以根据分析结果做出相应的响应措施,为后续运维工作带来极大的指导意义。类似这样的应用场景还有很多,如何充分挖掘出时间序列中所蕴含的信息,成为智能运维领域研究中的一大热点。

那么时间序列一般会有哪些比较明显的特征呢?

一般来讲具有趋势性、季节性、周期性随机性四种特征。但是对于时间序列预测,想要找到一个适用所有场景的通用模型几乎是不可能的,因为现实中每个预测问题的背景不同,影响预测值的因素与程度也往往不同,针对不同的问题就要采用不同的方法和模型进行统计分析,这都会给建模人员和数据分析师带来极大的难度,也使得时间序列预测问题变得复杂。

不同的模型会有各自的优势和劣势,本文将对传统时间序列预测模型ARIMA、经典神经网络模型LSTM以及Prophet模型展开具体介绍,并在事件单数据集上做了初步的探索。

常用的趋势预测算法

2.1、ARIMA模型

ARIMA模型,全称为自回归积分滑动平均模型(Autoregressive Integrated Moving Average Model),是由博克思(Box)和詹金斯(Jenkins)于20世纪70年代初提出的一种时间序列预测方法。ARIMA模型并不是一个特定的模型,而是一类模型的总称。通常用p,d,q值来确定,记做ARIMA(p,d,q)。其中p代表自回归模型阶数,d代表差分阶数,q代表移动平均阶数。

ARIMA模型的建模步骤如下:

首先对时间序列数据进行平稳性检测,若不通过,则采取对数、差分等相应的变换将其变为平稳序列。通过平稳性检测之后,进行白噪声检测,当序列不是白噪声序列时,即可选择合适的ARIMA模型进行拟合。如果误差值通过白噪声检测,就可以采用拟合出的模型对时序数据进行预测了。

虽然ARIMA模型已经在很多个场景中得以应用,但是它存在的缺陷是不可忽视的:要求时序数据具有稳定性,或者通过差分化后是稳定的;对于数据中存在缺失值的情况,需要先进行缺失值填补,这很大程度上损害了数据的可靠性。

2.2 神经网络模型

2.2.1 网络模型初探

在人工智能领域,DNN(Deep Neural Networks,深度神经网络)的应用极其广泛,在图像分类、目标检测等领域已经取得了优异的成绩。但是在DNN中,当前网络层只和上一层神经网络有连接,没有考虑样本出现的时间顺序,只能进行逐层进行训练。

为了将时间因素包含在内,出现了RNN(循环神经网络模型),可以将神经元的输出在下一个时间戳直接作用到自身。具体来讲,就是在t时刻接收到输入之后,隐藏层的值是,输出值是。关键点在于,的值不仅仅取决于,还取决于也就是说当前层的输出值不仅与当前时间点的输入有关,还要结合上一个时间点的输出值共同参与模型的训练。这样RNN就成为了一个在时间上传递的神经网络了。

但RNN也存在一定的弊端,RNN只能够接受上一个节点的输出,随着网络层次的加深,可能会发生梯度消失或者梯度爆炸,通俗来讲,就是当前节点无法对距离自己较远节点的信息进行“记忆”。为了解决该问题,研究人员提出了很多解决办法,其中最为经典的一个网络模型是长短时间记忆模型(Long Short-Term Memory,LSTM)。

LSTM与RNN主要的区别在于,它在模型中加入了一个判断信息是否有用的“处理器”,这个处理器被称为“记忆单元”(Memory Cell)。在一个Cell中放置了三扇门,分别是输入门、遗忘门和输出门。也就是说,当一个信息进入到LSTM中后,可以根据规则来判断其是否有用,只有符合要求的信息才会被留下,不符合的信息会被直接“遗忘”。这样序列数据在训练过程中的“记忆”问题就迎刃而解了。

采用神经网络的方法虽然能够达到较好的效果,但是模型不够灵活,很难让使用者引入问题的背景知识,或者一些有用的假设;训练模型还需要大量的数据,数量不够多很可能会产生过拟合,影响训练效果;除此之外,LSTM是单步预测,只能预测出下一个时间点的值,对于未来任意时间段的预测很不友好。

2.3 Prophet模型

facebook发布了prophet(“先知”)项目,它以更简单、灵活的预测方式获得与经验丰富的分析师相媲美的预测结果。Prophet是Facebook发布的基于可分解(趋势+季节+节假日)模型的开源库。它让我们可以用更加简单、直观的参数进行高精度的时间序列预测,并且支持自定义季节和节假日因素的影响。

prophet的整体框架分为四部分:Modeling、Forecast Evaluation、Surface Problems以及Visually Inspect Forecasts。从整体上看,这是一个循环结构,而这个结构又可以根据虚线分为分析师操纵部分与自动化部分。因此,整个过程就是分析师与自动化过程相结合的循环体系,也是一种将问题背景知识与统计分析融合起来的过程,这种结合大大的增加了模型的适用范围,提高了模型的准确性。

首先Modeling:建立时间序列模型;然后进行Forecast Evaluation,也就时模型评估,对参数进行多种尝试,根据仿真效果评估出更加合适的模型;接着是Surface Problems:呈现问题,将误差较大的潜在原因呈现给分析师进行人工干预;最后一部分是Visually Inspect Forecasts:以可视化的方式反馈整个预测结果,将问题反馈给分析师后,由分析师考虑是否进一步调整和构建模型。

针对不同的应用场景,Prophet也有相应的模型:

  1. 增长趋势的模型:有几个月(最好是一年)的每小时、每天或每周观察的历史数据;

  2. 季节趋势的模型(seasonality模型):有较强的季节性趋势;

  3. 有事先知道的以不定期的间隔发生的重要节假日(holiday模型),比如国庆节等。

整体来讲,Prophet模型可以根据前一段时间的序列数据,结合专家的经验,预测出期望时间段的输出值,以较小的模型训练成本获得较好的训练结果。

趋势预测算法小试牛刀

3.1 数据采集

本文采集了一些系统工单数据,通过LSTM和prophet模型分别对系统产生的工单数量的趋势进行预测。

首先对对提取到的数据进行预处理,提取出时间(ds)和事件单数(y)两列数据,部分数据可视化结果如下图所示:

import numpy as np
import pandas as pd
#读入数据
sales_df = pd.read_csv('false.csv')
sales_df.head()

3.2 数据实验

1)LSTM模型构建与实验

本文采用keras框架,构建有一个LSTM和一个全连接层的网络,采用MSE损失函数,用adam来优化损失函数,并将数据以7:3的比例划分为训练集和测试集。具体代码如下:

# create and fit the LSTM network
model = Sequential()
model.add(LSTM(4, input_shape=(1, look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=240, batch_size=1, verbose=2)

在数据集上的实验结果如下图所示,左图展现了LSTM模型在数据集上的拟合情况,横轴为时间,纵轴为事件单数,黄色线为真实值,绿色实现代表训练集上的预测结果,绿色虚线表示测试集上的结果。可以看到模型基本可以拟合出变化趋势,但是在具体的数量预测还有改进的空间。右图展现了在验证集和测试集上的loss趋势图。

2)Prophet模型构建与实验

from fbprophet import Prophet

## 拟合模型
m = Prophet()
m.fit(sales_df)
# # 构建待预测日期数据框,periods = 10 代表除历史数据的日期外再往后推 10 天
future = m.make_future_dataframe(periods=10)
# 预测数据集
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

通过fit()方法拟合Prophet()模型,make_future_dataframe()可以对未来日期的数据趋势进行预测,periods = 10 代表预测10天的结果,并计算出预测值(yhat),预测最小值(yhat_lower),预测最大值(yhat_upper)。具体趋势预测图如曲线图所示,黑点代表真实值,浅蓝色部分代表预测区间,可以看到模型基本可以拟合出较好的时间预测效果。

还能够通过plot_components(forecast)方法预测出数据的整体趋势和周效应:

趋势--整体趋势:

趋势--周效应:

 

除了预测每天产生的工单数量,本文还对某些系统每天发生的工单数进行了分析和预测,希望能够在预测的基础上,我们可以根据工单的预测数辅助运维工作的安排和开展。如某系统产生的工单数如下图:

小结

趋势预测算法在众多场景中都有重要的应用价值。本文对比较主流的ARIMA模型、LSTM神经网络模型和facebook发布的Prophet模型进行介绍,并在系统工单数据集上进行了初步探索。

虽然由于数据量的原因以及模型调参上还没有达到最佳的训练结果,但是模型对于趋势预测的有效性已经初步展现。之后,还会对趋势预测算法作进一步的探索和更深层次的研究,相信趋势预测算法在智能运维领域的应用也会更加广泛和可靠。

作者简介:

王哲,中国农业银行软件研发中心,从事运维支持工作的90后mm。目前承担新一代运维工具的研发,致力于研究人工智能算法,为实现智能运维、提升应用支持效率做出不懈努力。希望寻找业界同仁,共同对智能运维展开探讨:583283841@qq.com。

推荐阅读

上一篇: 平安科技王健宗:所有AI前沿技术,都能在联邦学习中大展身手

下一篇: 搞机器学习,Python和R哪个更合适?

精华推荐