当前位置: 首页 > 编程日记 > 正文

时序预测的三种方式:统计学模型、机器学习、循环神经网络

de1023aa16105461b63b2a5451669aa9.gif

作者 | luanhz

来源 | 小数志

导读

时序预测是一类经典的问题,在学术界和工业界都有着广泛的研究和应用。甚至说,世间万物加上时间维度后都可抽象为时间序列问题,例如股票价格、天气变化等等。关于时序预测问题的相关理论也极为广泛,除了经典的各种统计学模型外,当下火热的机器学习以及深度学习中的循环神经网络也都可以用于时序预测问题的建模。今天,本文就来介绍三种方式的简单应用,并在一个真实的时序数据集上加以验证。

1739a7dfa959e2eec5c472d453d94b48.png

时间序列预测,其主要任务是基于某一指标的历史数据来预测其在未来的取值,例如上图中的曲线记录了1949年至1960年共12年144个月份的每月航班乘客数(具体单位未经考证),那么时序预测要解决的问题就是:给定前9年的历史数据,例如1949-1957,那么能否预测出1958-1960两年间的乘客数量的问题。

为了解决这一问题,大概当前主流的解决方式有4种:

  • 统计学模型,较为经典的AR系列,包括AR、MA、ARMA以及ARIMA等,另外Facebook(准确的讲,现在应该叫Meta了)推出的Prophet模型,其实本质上也是一种统计学模型,只不过是传统的趋势、周期性成分的基础上,进一步细化考虑了节假日、时序拐点等因素的影响,以期带来更为精准的时序规律刻画;

  • 机器学习模型,在有监督机器学习中,回归问题主要解决的是基于一系列Feature来预测某一Label的可能取值的问题,那么当以历史数据作为Feature时其实自然也就可以将时序预测问题抽象为回归问题,从这一角度讲,所有回归模型都可用于解决时序预测。关于用机器学习抽象时序预测,推荐查看这篇论文《Machine Learning Strategies for Time Series Forecasting》;

  • 深度学习模型,深度学习主流的应用场景当属CV和NLP两大领域,其中后者就是专门用于解决序列问题建模的问题,而时间序列当然属于序列数据的一种特殊形式,所以自然可以运用循环神经网络来建模时序预测;

  • 隐马尔科夫模型,马尔科夫模型是用于刻画相邻状态转换间的经典抽象,而隐马尔科夫模型则在其基础上进一步增加了隐藏状态,来以此丰富模型的表达能力。但其一大假设条件是未来状态仅与当前状态有关,而不利于利用多个历史状态来共同参与预测,较为常用的可能就是天气预报的例子了。

本文主要考虑前三种时序预测建模方法,并分别选取:1)Prophet模型,2)RandomForest回归模型,3)LSTM三种方案加以测试。

首先在这个航班乘客真实数据集上进行测试,依次对比三个所选模型的预测精度。该数据集共有12年间每个月的乘客数量,以1958年1月作为切分界面划分训练集和测试集,即前9年的数据作为训练集,后3年的数据作为测试集验证模型效果。数据集切分后的示意图如下:

df = pd.read_csv("AirPassengers.csv", parse_dates=["date"]).rename(columns={"date":"ds", "value":"y"})
X_train = df[df.ds<"19580101"]
X_test = df[df.ds>="19580101"]plt.plot(X_train['ds'], X_train['y'])
plt.plot(X_test['ds'], X_test['y'])

4a2d6d8e57d794781cb78ae52ca0aa5b.png

1.Prophet模型预测。Prophet是一个高度封装好的时序预测模型,接受一个DataFrame作为训练集(要求有ds和y两个字段列),在预测时也接受一个DataFrame,但此时只需有ds列即可,关于模型的详细介绍可参考其官方文档:https://facebook.github.io/prophet/。模型训练及预测部分核心代码如下:

from prophet import Prophet
pro = Prophet()
pro.fit(X_train)
pred = pro.predict(X_test)pro.plot(pred)

训练后的结果示意图如下:

cd80f0f4e522116fda4d1f5670f8330f.png

当然,这是通过Prophet内置的可视化函数给出的结果,也可通过手动绘制测试集真实标签与预测结果间的对比:

bda741bf0d8a33561bb463855ed4cac3.png

易见,虽然序列的整体走势上具有良好的拟合结果,但在具体取值上其实差距还是比较大的。

2.机器学习模型,这里选用常常用作各种baseline的RandomForest模型。在使用机器学习实现时序预测时,通常需要通过滑动窗口的方式来提取特征和标签,而后在实现预测时实际上也需滑动的截取测试集特征实现单步预测,参考论文《Machine Learning Strategies for Time Series Forecasting》中的做法,该问题可大致描述如下:

f0c2af913704953b27b0072b0a6921b6.png

据此,设置特征提取窗口长度为12,构建训练集和测试集的方式如下:

data = df.copy()
n = 12
for i in range(1, n+1):data['ypre_'+str(i)] = data['y'].shift(i)
data = data[['ds']+['ypre_'+str(i) for i in range(n, 0, -1)]+['y']]# 提取训练集和测试集
X_train = data[data['ds']<"19580101"].dropna()[['ypre_'+str(i) for i in range(n, 0, -1)]]
y_train = data[data['ds']<"19580101"].dropna()[['y']]
X_test = data[data['ds']>="19580101"].dropna()[['ypre_'+str(i) for i in range(n, 0, -1)]]
y_test = data[data['ds']>="19580101"].dropna()[['y']]# 模型训练和预测
rf = RandomForestRegressor(n_estimators=10, max_depth=5)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)# 结果对比绘图
y_test.assign(yhat=y_pred).plot()

56b9a48df8c97a39667691b12968f13f.png

可见,预测效果也较为一般,尤其是对于最后两年的预测结果,与真实值差距还是比较大的。用机器学习模型的思维很容易解释这一现象:随机森林模型实际上是在根据训练数据集来学习曲线之间的规律,由于该时序整体呈现随时间增长的趋势,所以历史数据中的最高点也不足以cover住未来的较大值,因而在测试集中超过历史数据的所有标签其实都是无法拟合的。

3.深度学习中的循环神经网络,其实深度学习一般要求数据集较大时才能发挥其优势,而这里的数据集显然是非常小的,所以仅设计一个最为简单的模型:1层LSTM+1层Linear。模型搭建如下:

class Model(nn.Module):def __init__(self):super().__init__()self.rnn = nn.LSTM(input_size=1, hidden_size=10, batch_first=True)self.linear = nn.Linear(10, 1)def forward(self, x):x, _ = self.rnn(x)x = x[:, -1, :]x = self.linear(x)return x

数据集构建思路整体同前述的机器学习部分,而后,按照进行模型训练炼丹,部分结果如下:

# 数据集转化为3D
X_train_3d = torch.Tensor(X_train.values).reshape(*X_train.shape, 1)
y_train_2d = torch.Tensor(y_train.values).reshape(*y_train.shape, 1)
X_test_3d = torch.Tensor(X_test.values).reshape(*X_test.shape, 1)
y_test_2d = torch.Tensor(y_test.values).reshape(*y_test.shape, 1)# 模型、优化器、评估准则
model = Model()
creterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters())# 训练过程
for i in range(1000):out = model(X_train_3d)loss = creterion(out, y_train_2d)optimizer.zero_grad()loss.backward()optimizer.step()if (i+1)%100 == 0:y_pred = model(X_test_3d)loss_test = creterion(y_pred, y_test_2d)print(i, loss.item(), loss_test.item())# 训练结果
99 65492.08984375 188633.796875
199 64814.4375 187436.4375
299 64462.09765625 186815.5
399 64142.70703125 186251.125
499 63835.5 185707.46875
599 63535.15234375 185175.1875
699 63239.39453125 184650.46875
799 62947.08203125 184131.21875
899 62657.484375 183616.203125
999 62370.171875 183104.671875

通过上述1000个epoch,大体可以推断该模型不会很好的拟合了,所以果断放弃吧!

当然必须指出的是,上述测试效果只能说明3种方案在该数据集上的表现,而不能代表这一类模型在用于时序预测问题时的性能。实际上,时序预测问题本身就是一个需要具体问题具体分析的场景,没有放之四海而皆准的好模型,就像“No Free Lunch”一样!

本文仅是作为时序预测系列推文的一个牛刀小试,后续将不定期更新其他相关心得和总结。

98d04aeff3fbdb119bd20d95fae2246a.gif

资讯

Meta开发AI语音助手,助力元宇宙

技术

10个超级常用的Python方法总结

技术

5分钟速通 AI 计算机视觉发展应用

资讯

M2芯片终于要来了?全线换新

42264c8a9aea2210e4ecec657f90a7f1.png

分享

0215b2925c39ff5c03726a595ee66bd3.png

点收藏

6be6579201bf429e3c843808a1adae45.png

点点赞

9ae1996f3d4bed2293d2f0c3755eb1ce.png

点在看

相关文章:

Python 爬虫练手项目—酒店信息爬取

from bs4 import BeautifulSoup import requests import time import reurl http://search.qyer.com/hotel/89580_4.html urls [http://search.qyer.com/hotel/89580_{}.html.format(str(i)) for i in range(1,10)] # 最多157页 infos [] # print(urls)# 批量爬取数据 def g…

应用交换技术的负载均衡算法

原文出处是&#xff1a;http://hi.baidu.com/ruijievideo/blog/item/5959be1f3c1621ff1bd576d2.html 应用交换技术的负载均衡算法应用交换技术里主要包括四项关键的技术&#xff1a;◆截获和检查流量◆服务器监控健康检查◆负载均衡算法◆会话保持截获和检查流量保证只有合适的…

平民架构的春天——UCloud数据方舟实战记

LNMP是最亲民的网页服务架构&#xff0c;整合了优秀的开源软件&#xff0c;想必大家再熟悉不过了&#xff0c;随着云计算的落地&#xff1b;大众创业&#xff0c;万众创新的倡导&#xff0c;为了更好的服务和安全&#xff0c;LNMP也迁入了云平台&#xff0c;比如像UCloud这样优…

用 Python 制作可视化报表,这也太快了!

作者 | 小F来源 | 法纳斯特在数据展示中使用图表来分享自己的见解&#xff0c;是个非常常见的方法。这也是Tableau、Power BI这类商业智能仪表盘持续流行的原因之一&#xff0c;这些工具为数据提供了精美的图形解释。当然了&#xff0c;这些工具也有着不少缺点&#xff0c;比如…

Django 错误汇总

1、 解决&#xff1a;python manage.py migrate sessions 2、转载于:https://blog.51cto.com/jacksoner/2130665

几种负载均衡算法

几种负载均衡算法 本地流量管理技术主要有一下几种负载均衡算法&#xff1a; 静态负载均衡算法包括&#xff1a;轮询&#xff0c;比率&#xff0c;优先权 动态负载均衡算法包括: 最少连接数,最快响应速度&#xff0c;观察方法&#xff0c;预测法&#xff0c;动态性能分配&#…

cassandra命令

压力测试&#xff1a;cassandra-stress [command] -node [nodes] -mode thrift user[user] password[password] example: cassandra-stress write n10 -node 192.168.0.105 -mode thrift usercassandra passwordcassandra

《2022产业互联网安全十大趋势》发布,专家学者透析产业安全新变化

2月28日&#xff0c;在中国产业互联网发展联盟指导下&#xff0c;人民邮电报、中国信息安全、腾讯安全联合实验室、腾讯研究院联合推出《2022产业互联网安全十大趋势》。该报告由《中国信息安全》杂志出品人温哲、腾讯副总裁丁珂、腾讯研究院院长司晓等20余位行业顶级专家、学者…

slurm用户快速入门手册

1. 概述2. 架构3. 命令3.1 sacct3.2 sattach3.4 sbatch3.5 sbcast3.6 scancel3.7 scontrol3.8 sinfo3.9 smap3.10 squeue3.11 srun3.12 strigger3.13 sview1. 概述 Slurm 是一个开源、容错、高可伸缩的集群管理和大型小型 Linux 集群作业调度系统。slurm不需要对操作系统内核进…

什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?

原文地址&#xff1a;http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/什么是CGICGI全称是“公共网关接口”(Common Gateway Interface)&#xff0c;HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具&#xff0c;其程序须运行在网络服务器上…

5个短小精悍的 Python 趣味脚本,太赞了,非常适合小白上手!

作者 | 菜鸟哥来源 | 菜鸟学Python今天特地为大家准备了几个简单的“开胃小菜”。希望大家能够通过这几个简单而实用的小案例&#xff0c;活跃一下自己的思维&#xff0c;为接下来的工作和学习做好准备。话不多说&#xff0c;我们接下来就开始介绍。1、图片尺寸缩小所需库&…

AjaxFileUpload文件上传组件(php+jQuery+ajax)

jQuery插件AjaxFileUpload可以实现ajax文件上传&#xff0c;下载地址&#xff1a;http://www.phpletter.com/contents/ajaxfileupload/ajaxfileupload.js 主要参数说明&#xff1a;1&#xff0c;url表示处理文件上传操作的文件路径&#xff0c;可以测试URL是否能在浏览器中直接…

Hadoop生态圈-Flume的组件之自定义拦截器(interceptor)

Hadoop生态圈-Flume的组件之自定义拦截器&#xff08;interceptor&#xff09; 作者&#xff1a;尹正杰 版权声明&#xff1a;原创作品&#xff0c;谢绝转载&#xff01;否则将追究法律责任。 本篇博客只是举例了一个自定义拦截器的方法&#xff0c;测试字节传输速度。 1>.自…

Pandas 重复数据处理大全

作者 | 东哥起飞来源 | Python数据科学本次来介绍重复值处理的常用方法。重复值处理主要涉及两个部分&#xff0c;一个是找出重复值&#xff0c;第二个是删除重复值&#xff0c;也就是根据自己设定的条件进行删除操作。定位重复值对于重复值&#xff0c;我们首先需要查看这些重…

DEDECMS教程:上/下一篇文章标题长度的截取方法

对dedecms了解的朋友们&#xff0c;想必对如何获取上一篇、下一篇文章的标签也是非常熟悉。dedecms获取上一篇、下一篇文章的标签分别为&#xff1a;{dede:prenext getpre/}、{dede:prenext getnext}。 在这个标签里&#xff0c;并没有设置上一篇、下一篇文章标题字数的功能&am…

以太网帧最小字节数以及以太网碰撞

说明&#xff1a;本文源自多个网页&#xff0c;原文链接已经不可寻 以太网是无连接的&#xff0c;不可靠的服务&#xff0c;采用尽力传输的机制。以太网CSMA/CD我就不多讲了&#xff0c;我相信大家都了解这个原理。以太网是不可靠的&#xff0c;这意味着它并不知道对方有没有收…

lodash 提取前N个元素 take

_.take(array, [n1])从数组的起始元素开始提取 N 个元素。 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><…

JavaScript 中的有限状态机

http://www.ibm.com/developerworks/cn/web/wa-finitemach/JavaScript 中的有限状态机Page navigation系列文章有限状态机很早就已用作设计和实现事件驱动的程序&#xff08;比如网络适配器和编译器&#xff09;内复杂行为的组织原则。现在&#xff0c;可编程的 Web 浏览器为新…

健身也内卷?这届网友用 Python 掌握了做标准俯卧撑的秘诀

自己在家锻炼时&#xff0c;我们很难知道自己的动作是否标准。本文作者用Python写了一个可以检测俯卧撑动作是否标准的程序&#xff0c;一起来看看他是怎么做的。 译者 | 章雨铭 出品 | CSDN 在新加坡军队中&#xff0c;有一种测试叫做IPPT&#xff08;个人身体素质测试&#x…

Linux下配置SNMP

SNMP&#xff08;Simple NetworkManagement Protocol &#xff09;&#xff1a;简单网络管理协议本案列为Linux环境搭建&#xff08;CentOS-6&#xff09;使用yum进行安装&#xff1a;yum install -y net-snmp安装完成后先查看网络配置&#xff1a;netstat -anupl确认161端口被…

重磅!MaxCompute助力阿里开源自研语音识别模型DFSMN,准确率高达96.04%

阿里开源语音识别模型DFSMN 在近期举行的云栖大会武汉峰会上&#xff0c;装有DFSMN语音识别模型的“AI收银员”在与真人店员的PK中&#xff0c;在嘈杂环境下准确识别了用户的语音点单&#xff0c;在短短49秒内点了34杯咖啡。此外&#xff0c;装备这一语音识别技术的自动售票机也…

全球网络拓扑图

原文出自海外一个论坛&#xff1a;http://board.us.ikariam.com/board16-miscellaneous/board205-discussion-board/67724-internet/InternetSo, I always take a look at these maps and also information on the workings of the internetAnd I have questions:Are there map…

Python 实现 PD 文字识别、提取并写入 CSV 文件脚本分享

作者 | 一只河马h来源 | 简说Python一、前言二、需求描述三、开始动手动脑3.1 安装相关第三方包3.2 导入需要用到的第三方库3.3 读取pdf文件&#xff0c;并识别内容3.4 对识别的数据进行处理&#xff0c;写入csv文件总结前言扫描件一直受大众青睐&#xff0c;任何纸质资料在扫描…

根据listObject中的某个字段排序

compareTo必须是两个对象之间的比较(比如Long,Integer...),以下例子是升序排序 private void businessSort(List<WxDailyBusinessInfo> wxDailyBusinessInfo) { //排序前for (int i 0; i < wxDailyBusinessInfo.size(); i) {System.out.println(new Gson(…

CC国内厂商现状

&#xff08;1&#xff09;阿里云的产品 CC攻击 攻击者攻击服务器的认证页面、登录页面、游戏论坛等。还是用饭馆的例子&#xff0c;CC攻击相当于&#xff0c;坏人霸占收银台结账、霸占服务员点菜&#xff0c;导致正常的客人无法享受到服务。 游戏盾如何防御CC攻击&#xff1f;…

网络模型 - 随机网络,无标度网络,分层网络

转自&#xff1a; http://www.flickr.com/photos/caseorganic/4510691991/in/set-72157624621620243小图大图Network Models - Random network, Scale-free network, Hierarchical network随机网络The Erds–Rnyi (ER) model of a random network14 (see figure, part A) start…

一文介绍机器学习中的三种特征选择方法

作者 | luanhz来源 | 小数志导读机器学习中的一个经典理论是&#xff1a;数据和特征决定了机器学习的上限&#xff0c;而模型和算法只是逼近这个上限。也正因如此&#xff0c;特征工程在机器学习流程中占有着重要地位。广义的特征工程一般可分为三个环节&#xff1a;特征提取、…

[转化率预估-1]引言

原文&#xff1a;hhttp://www.flickering.cn/ads/2014/06/%E8%BD%AC%E5%8C%96%E7%8E%87%E9%A2%84%E4%BC%B0%E2%80%94%E2%80%94%E5%BC%95%E8%A8%80/ 最近几年&#xff0c;“计算广告学”的概念风生水起&#xff0c;让我们这些从事在线广告匹配技术的程序猿着实荣耀了一把。这在参…

reportNG定制化之失败截图及日志

先从github上拉下 reportNg的源代码 reportng 拉下源码后我们使用IDEA进行导入 1、reportng.properties 增加部分类表项 这里我们直接在末尾添加 logLog Info screenshotScreen Shot durationDuration2、results.html.vm 修改结果的html&#xff0c;我们目前只修改fail的情况下…

基于 OpenCV 的手掌检测和手指计数

作者 | 努比 来源 | 小白学视觉 利用余弦定理使用OpenCV-Python实现手指计数与手掌检测。 手检测和手指计数 接下来让我们一起探索以下这个功能是如何实现的。 OpenCV OpenCV&#xff08;开源计算机视觉库&#xff09;是一个开源计算机视觉和机器学习软件库。OpenCV的构建旨在为…