我们把按照时间次序排列的随机变量序列

\[Y_0,\, Y_1,\, Y_2, \cdots \]

称为时间序列(Time Series)。比如网站的PV、DAU,国家的GDP,股票的价格等。

这种特别的次序给模型提出了特别的挑战,包含数据内的自相关性、不可交换性、以及数据和参数的不平稳性等。

时间序列里面的内容很多,小到接下来要讲的平滑,大到金融里的混沌时间序列预测等。我准备花一些时间认真整理部分理论和应用,第一篇就分享下上手攻略,关键词是 insight。

本文采用的数据集是 Peyton Manning 的 Wikipedia 页面的 PV,下载地址是:https://github.com/facebook/prophet/tree/master/examples ,也可以在公众号后台回复 数据集 下载。

df = pd.read_csv('.\\data\\example_wp_peyton_manning.csv')
df['ds']=pd.to_datetime(df['ds'])
df['y']=np.log(df['y'])# tricks
plt.plot(df['ds'],df['y'],'.')
ax.set_title('Raw Time Series')

1. 手动平滑时间序列和获取趋势项

假设时间序列有周期为 s 的周期性趋势,一种最简单的平滑方式就是移动平均法(moving average),假设窗口设为7,则

\[s_t=\frac{1}{7}(y_t+y_{t-1}+y_{t-2}+\cdots +y_{t-6})\]

其实就是股票中的5日均线、20日均线。

y1=pd.rolling_mean(df['y'],window=7)
# 如果要使得平滑后长度一致,可以设置参数,min_periods=1
y2=pd.rolling_mean(df['y'],window=365)
fig,ax=plt.subplots()
ax.plot(df['ds'],df['y'],'.',alpha=0.4,label='Raw')
ax.plot(df['ds'],y1,'-',label='Win:7')
ax.plot(df['ds'],y2,'-',label='Win:365')
ax.legend()
ax.set_title('Smoothing : Moving Average')

移动平均法只利用了前面n天的数据,而且权重一样。一种更好的方法是指数平滑法(exponentially weighted moving average),越靠近当天的数据权重越高

\[s_0=y_0, \,\, s_t=\alpha y_t +(1-\alpha)y_{t-1}\]

从这个公式看不出指数在哪,但当我们把它展开后就很明显了。

\[s_t=\alpha [y_t+(1-\alpha)y_{t-1} + \cdots + (1-\alpha)^{t-1}y_1] + (1-\alpha)^{t} y_0\]

事实上 EMWA 是一种没有常数项的ARIMA(0,1,1)模型,当把alpha的选取标准设为最小化 s_t 和 y_{t+1} 就是一个很简单的时间序列预测模型。

股票中的MACD指标利用的就是指数平滑,其中的DIF线就是12日的指数平滑值 减去26日的指数平滑值。

y1=pd.ewma(df['y'],span=7)
y2=pd.ewma(df['y'],span=365)
fig,ax=plt.subplots()
ax.plot(df['ds'],df['y'],'.',alpha=0.4,label='Raw')
ax.plot(df['ds'],y1,'-',label='Span:7')
ax.plot(df['ds'],y2,'-',label='Span:365')
ax.legend()
ax.set_title('Smoothing : Exponentially Weighted Moving Average')

除此之外还有一些更好的方法,大家可以试试,比如 Holt-Winter三次指数平滑法等

2. 利用 Prophet 看趋势和周期

时间序列经过合理的函数变换后都可以被认为是由三个部分叠加而成。分别是趋势项部分、周期项部分和噪声项部分

\[y(t) = g(t) +s(t) +\varepsilon_t\]

其中 s(t) 表示周期项,如 weekly seasonality(周一和周二是不一样的)和 yearly seasonality(平时和寒暑假是不一样的等)等。对于一些特别的场景,比如网站的DAU,还需要考虑节假日成分、特殊时间成分等。

我们可以利用 Facebook 开源的包 Prophet 来分解。

# 可以添加节假日参数,这样分解会更准确
m=Prophet()
m.fit(df)
future=m.make_future_dataframe(periods=1)
forecast=m.predict(future)
forecast1=forecast.loc[:,['ds','yhat']]
#m.plot(forecast);
fig=m.plot_components(forecast,weekly_start=1)

Prophet 利用加法模型把序列分成了4个部分(如果给定节假日参数,则是5个部分)。我们可以大概看下它的预测效果,之后我准备花一篇文章专门梳理各个方法(包)的预测效果。

df1=pd.merge(forecast.loc[:,['ds','yhat']],df,on='ds',how='inner')
# 计算RMSE
from sklearn import metrics
rmse=np.sqrt(metrics.mean_squared_error(df1['yhat'],df1['y']))
fig,ax=plt.subplots()
ax.plot(df1['ds'],df1['y'],'.',label='Raw')
ax.plot(df1['ds'],df1['yhat'],'-',alpha=0.8,label='Prophet')
ax.legend()
ax.set_title('Prophet Predict (RMSE= {:.2f})'.format(rmse));
fig.savefig('.\\_images\\prophet_predict.png',dpi=500)

PS: 因为我们用的是训练集,所以这个RMSE并不能用来评估预测的效果。

3. 从频域看可能存在的周期

我们还可以利用Fourier Transform 在频域里看看时间序列。给定一个函数 f(x), 则其 傅里叶变换可以表示为:

\[\hat{f}(x)=\int f(x)e^{-2\pi i x \xi} dx\]

w = np.fft.fft(df['y']-y4)
n=len(w)
w=w[1:]
power = np.abs(w[:int(n/2)])
nyquist = 1/2
freq = np.arange(int(n/2))/(n/2)*nyquist
fig,ax=plt.subplots()
ax.plot(freq,power)
ax.set_xlim(0,0.2)
ax.set_title('Power Spectral');
ax.plot(1/365,power[7],'o',color='red')
ax.text(1/365,power[7],'   Hz: 1/365')
ax.plot(1/7,power[416],'o',color='red')
ax.text(1/7,power[416],'   Hz:1/7')
fig.savefig('.\\_images\\power_spectral.png',dpi=500)

功率谱上的两个峰值就是时间序列存在的周期。

4. 从时频域看异常值

小波变换可以把时间序列直接在时频域进行分解成高频部分和低频部分。低频部分包含了序列的大部分信息,高频部分则包含了一些细节信息。现在的JPEG2000压缩标准就是基于小波变换设计的,如果将一张图片进行小波变换,则低频部分跟原图差别很小,高频部分则大概能看出图片的轮廊,通过一些方法就能进行图片边界的检测了,大家有兴趣可以试试。

首先回顾一下小波变换的相关理论. 详细的我就不讲了,比较复杂。设 \(f(x)\in L^2(\mathbb{R})\),对于任意精度 \(\varepsilon\),我们都能找到一个 \(j\) 使得

\[ \| f-f_j\|_{L^2} \leq \varepsilon,\quad f_j \in V_j, \]

\[ f_j(x)=\sum_{k\in \mathbb{Z}}c_{j,k}\varphi_{j,k}(x) \]

其中 \(\{\varphi_{j,k}(x)\}\) 是具有紧支撑的函数族,比如 db1,db2,...

import pywt
(cA,cD)=pywt.dwt(df['y'],'db4')
n=len(df)
cAn=pywt.upcoef('a',cA,'db4',take=n)
cDn=pywt.upcoef('d',cD,'db4',take=n)
fig,[ax0,ax1,ax2]=plt.subplots(3,1)
ax0.plot(df['ds'],df['y'],'.')
ax0.set_xlabel('Raw')ax1.plot(df['ds'],cAn,'.')
ax1.set_xlabel('Low Frequency')ax2.plot(df['ds'],cDn,'.')
ax2.set_xlabel('High Frequency')fig.tight_layout()
#fig.savefig('.\\_images\\小波分解.png',dpi=500)fig,ax=plt.subplots()
cDn[np.abs(cDn)<3*np.std(cDn)]=0
ax.plot(df['ds'],df['y'],'.')
tmp=df.copy()
tmp['cDn']=cDn
tmp=tmp.loc[tmp['cDn']>0,['ds','y']]
ax.plot(tmp['ds'],tmp['y'],'o',alpha=0.4,color='red')
ax.set_xlabel('outlier mark')
fig.tight_layout()
#fig.savefig('.\\_images\\异常值标记.png',dpi=500)

接下来的计划还没想好,大概率有一篇讲ARIMA系列模型,一篇评估现有各种包的预测效果,一篇讲 Change Point ,一篇将 RNN 和 LSTM。

参考文献

[1]. 指数平滑法, http://connor-johnson.com/2014/02/01/smoothing-with-exponentially-weighted-moving-averages/

[2]. 指数平滑法, https://www.jianshu.com/p/6fb0408b3f54


转载于:https://www.cnblogs.com/gasongjian/p/9060327.html

时间序列(一):上手体验相关推荐

  1. 石头机器人拖地水量调节_石头扫地机器人T7上手体验:电控水箱和超大容量,扫拖一体全能型...

    [微创WEC科技]前段时间,给大家带来了石头扫地机器人P51的体验,今天给大家带来一个更"猛"一点的,就是今年石头机器人的旗舰产品:T7. 石头扫地机器人T7上手体验视频 要知道石 ...

  2. 三星s10android10功能,三星S10系列现场上手体验:“安卓机皇”真的名副其实

    [手机中国评测]在二月的最后一天,三星召开新品发布会,三星S10系列国行版惊艳亮相.作为三星今年的的一款旗舰,可以说集万众宠爱于一身,同时也承载着众多用户的期许.从MWC发布后来看,三星S10可以说是 ...

  3. Face ID 上手体验信息汇总:面部解锁流畅,原理移植AR让人憧憬

    昨天,苹果举行了 iPhone X 试用会,传来了不少上手体验评测,今天52VR就来为大家总结一下 Face ID 和Animoji的表现,并探究其中所用到的技术在未来AR方面更深层次的应用前景. 哦 ...

  4. uos系统不激活能用吗_国产统一操作系统UOS真的能代替window系统吗? UOS上手体验...

    近一段时间,Win10的更新搞得人心惶惶,新功能没见多少,问题却此起彼伏.常常是一个旧Bug搞定了,又带来一堆新Bug.近日,中兴新支点.深度.中国电子集团.诚迈科技等四家国产操作系统厂商,合力推出了 ...

  5. android camera 3a,买相机送手机 pixel 3a 上手体验

    买相机送手机 pixel 3a 上手体验 2019-05-29 08:29:42 23点赞 14收藏 20评论 创作立场声明:独立主观有点方 购买理由 有人说过,人生就是连续的选择题,人们总是在取与舍 ...

  6. IOS基础基于pod上手体验FMDB框架

    IOS基础基于pod上手体验FMDB框架 // // ViewController.m // FMDBSingleOC // // Created by 鲁军 on 2021/3/17. //#imp ...

  7. AFN框架和SDWebImage框架的上手体验

    AFN框架和SDWebImage框架的上手体验 资料来源2015-10-15 ,我曾经尝试安装cocoaPods,并且成功了,但是版本更新太快,api函数封装有所变化,为了保证资料的准确一致,先学习过 ...

  8. 第6讲 | 理解区块链之前,先上手体验一把数字货币

    初次接触到区块链的你,肯定是一头雾水:"区块链是什么,这玩意到底怎么回事". 其实对于区块链的原理,你大可不必着急,咱们可以直接上手体验一下目前区块链的第一大应用:数字货币. 本篇 ...

  9. html5input输入框设置无边框_芯片充电两大改变,无看点的iPad8,上手体验发现并不简单!...

    前不久,苹果召开了秋季新品发布会,但与以往不同的是,往年本该成为"配角"的iPad,没想到此次成为了主角之一,面对着外观不变仅升级芯片新发布的iPad 8,大家好像没有过多的激情, ...

  10. 小米手环无法模拟门卡_颜值与功能得到全面升级,小米手环4 NFC版上手体验

    提到国产智能手环,相信不少人第一时间想到的就是小米手环系列,就在前不久的时候,小米米家正式举办了新品发布会,而小米手环4系列也正式登场. 与前代产品相比,小米手环4系列在很多方面都进行了全面升级,比如 ...

最新文章

  1. 05-常用IOC注解按照作用分类
  2. C# SignalR 即时通讯 聊天室
  3. 组件化的css-module
  4. 关于如何存储便于网上浏览的电子书籍
  5. Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试
  6. 矩形液体包装纸箱行业调研报告 - 市场现状分析与发展前景预测
  7. 如何卸载office201032位_如何卸载流氓版office2010
  8. 微信H5页面ios分享失效
  9. Google Earth Pro v7.3.6.9285 谷歌地球卫星图像专业版
  10. 银河麒麟高级服务器v10 sp1 搭建局域网yum源(同步阿里yum源centos7.9)
  11. abaqus python提取楼层剪力_用Python提取ABAQUS中节点集合的反力
  12. R730服务器内存扩展安装
  13. presenting view controller Vs presented view controller
  14. 程序员接私活的6个网站,你有技术就有钱!
  15. Photoshop使用背景图层的方法
  16. 被中国家长摧残的十种优秀儿童品质
  17. AI绘画能取代设计师吗?
  18. 我的2017,五味杂陈
  19. Ubuntu下的opencv:在图片上加汉字和数字
  20. lsmod,insmod

热门文章

  1. JAVA 实现《五子棋单机版》游戏
  2. Altium Designer 20中创建网络类、隐藏网络连线
  3. 为什么溺水事故无法“清零”?
  4. 研究生工作周报(第十三周)
  5. 用安卓手机控制 HomeKit 智能设备?绿米Aqara设备接入智汀家庭云保姆级教程
  6. 二叉树前、中、后序线索化及遍历
  7. 19蓝桥国赛B组C/C++ I第八大奇迹
  8. 一篇好文,在迷茫时阅读
  9. 10月15python
  10. Single SPI、Dual SPI、Qaud SPI