⼿把⼿教你⽤Python进⾏时间序列分解和预测
预测是⼀件复杂的事情,在这⽅⾯做得好的企业会在同⾏业中出类拔萃。时间序列预测的需求不仅存在于各类业务场景当中,⽽且通常需要对未来⼏年甚⾄⼏分钟之后的时间序列进⾏预测。如果你正要着⼿进⾏时间序列预测,那么本⽂将带你快速掌握⼀些必不可少的概念。
⽬录
什么是时间序列?
如何在Python中绘制时间序列数据?
时间序列的要素是什么?
如何分解时间序列?
经典分解法
如何获得季节性调整值?
STL分解法
时间序列预测的基本⽅法:
Python中的简单移动平均(SMA)
为什么使⽤简单移动平均?
Python中的加权移动平均(WMA)
Python中的指数移动平均(EMA)
什么是时间序列?
顾名思义,时间序列是按照固定时间间隔记录的数据集。换句话说,以时间为索引的⼀组数据是⼀个时间序列。请注意,此处的固定时间间隔(例如每⼩时,每天,每周,每⽉,每季度)是⾄关重要的,意味着时间单位不应改变。别把它与序列中的缺失值混为⼀谈。我们有相应的⽅法来填充时间序列中的缺失值。
在开始使⽤时间序列数据预测未来值之前,思考⼀下我们需要提前多久给出预测是尤其重要的。你是否应该提前⼀天,⼀周,六个⽉或⼗年来预测(我们⽤“界限”来表述这个技术术语)?需要进⾏预测的频率是什么?在开始预测未来值的详细⼯作之前,与将要使⽤你的预测结果的⼈谈⼀谈也不失为⼀个好主意。
如何在Python中绘制时间序列数据?
可视化时间序列数据是数据科学家了解数据模式,时变性,异常值,离值以及查看不同变量之间的关系所要做的第⼀件事。从绘图查看中获得的分析和见解不仅将有助于建⽴更好的预测,⽽且还将引导我们到最合适的建模⽅法。这⾥我们将⾸先绘制折线图。折线图也许是时间序列数据可视化最通⽤的⼯具。
这⾥我们⽤到的是AirPassengers数据集。该数据集是从1949年到1960年之间的每⽉航空旅客⼈数的集合。下⾯是⼀个⽰例数据,以便你对数据信息有个⼤概了解。
#Reading Time Series Data
Airpassenger = pd.read_csv("AirPassengers.csv")
Airpassenger.head(3)
现在,我们使⽤折线图绘制数据。在下⾯的⽰例中,我们使⽤set_index()将date列转换为索引。这样就会⾃动在x轴上显⽰时间。接下来,我们使⽤rcParams设置图形⼤⼩,最后使⽤plot()函数绘制图表。
Airpassenger = Airpassenger.set_index('date')
Airpassenger.plot()
pyplot.show()
1949-1960年间,乘飞机旅⾏的乘客⼈数稳定增长。规律性间隔的峰值表明增长似乎在有规律的时间间隔内重复。
让我们看看每个季度的趋势是怎样的。为了便于理解,从不同的维度观察信息是个好主意。为此,我们需要使⽤Python中的datetime包从date变量中得出季度和年份。在进⾏绘图之前,我们将连接年份和季度信息,以了解旅客数量在季节维度上如何变化。
from datetime import datetime
# Airpassenger["date"] = Airpassenger["date"].apply(lambda x: datetime.strptime(x, "%d-%m-%Y"))
Airpassenger["year"] = Airpassenger["date"].apply(lambda x: x.year)
Airpassenger["qtr"] = Airpassenger["date"].apply(lambda x: x.quarter)
Airpassenger["yearQtr"]=Airpassenger['year'].astype(str)+'_'+Airpassenger['qtr'].astype(str)
airPassengerByQtr=Airpassenger[["passengerCount", "yearQtr"]].groupby(["yearQtr"]).sum()
准备好绘制数据后,我们绘制折线图,并确保将所有时间标签都放到x轴。x轴的标签数量⾮常多,因此我们决定将标签旋转呈现。
pyplot.plot(airPassengerByQtr)
这幅图⾮常有趣,它清晰地表明,在1949-1960年之间的所有年份中,航空旅客⼈数每季度都在显著增加。
时间序列的要素是什么?
时间序列数据包含4个主要元素:
1.趋势性–趋势性表⽰数据随时间增加或减少的⼀般趋势。这很容易理解。例如,1949年⾄1960年之间航空旅客数量呈增加趋势,或者可以说呈上升趋势。
2.季节性–如同⼀年四季,数据模式出现在有规律的间隔之后,代表了时间序列的季节性组成部分。它们在特定的时间间隔(例如⽇,周,⽉,年等)之后重复。有时我们很容易弄清楚季节性,有时则未必。通常,我们可以绘制图表并直观检验季节性元素的存在。但是有时,我们可能不得不依靠统计⽅法来检验季节性。
3.周期性–可被视为类似季节性,但唯⼀的区别是周期性不会定期出现。这个属性使得它很难被辨识。例如,地震可以在我们知道将要发⽣的任何时间发⽣,但是我们其实不知道何时何地发⽣。
4.随机噪声–不属于上述三类情况的时间序列数据中的突然变化,⽽且也很难被解释,因此被称为随机波动或随机噪声。
如何分解时间序列?
有两种技术可以获取时间序列要素。在进⾏深⼊研究和查看相关Python抽取函数之前,必须了解以下两点:
时间序列不必具有所有要素。
弄清该时间序列是可加的还是可乘的。
那么什么是可加和可乘时间序列模型呢?
可加性模型–在可加性模型中,要素之间是累加的关系。y(t)=季节+趋势+周期+噪⾳
可乘性模型–在可乘性模型中,要素之间是相乘的关系。y(t)=季节趋势周期*噪⾳
你想知道为什么我们还要分解时间序列吗?你看,分解背后的⽬的之⼀是估计季节性影响并提供经过季节性调整的值。去除季节性的值就可以轻松查看趋势。例如,在美国,由于农业领域需求的增加,夏季的失业率有所下降。从经济学⾓度来讲,这也意味着6⽉份的失业率与5⽉份相⽐有所下降。现在,如果你已经知道了逻辑,这并不代表真实的情况,我们必须调整这⼀事实,即6⽉份的失业率始终低于5⽉份。
这⾥的挑战在于,在现实世界中,时间序列可能是可加性和可乘性的组合。这意味着我们可能并不总是能够将时间序列完全分解为可加的或可乘的。
现在你已经了解了不同的模型,下⾯让我们研究⼀些提取时间序列要素的常⽤⽅法。
经典分解法
该⽅法起源于1920年,是诸多⽅法的⿐祖。经典分解法有两种形式:加法和乘法。Python中的statsmodels库中的函数season_decompose()提供了经典分解法的实现。在经典分解法中,需要你指出时间序列是可加的还是可乘的。你可以在此处()了解有关加法和乘法分解的更多信息。
在下⾯的代码中,要获得时间序列的分解,只需赋值model=additive。
import numpy as np
from pandas import read_csv
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from pylab import rcParams
elecequip = read_csv(r"C:/Users/datas/python/data/elecequip.csv")
result = seasonal_decompose(np.array(elecequip), model='multiplicative', freq=4)
rcParams['figure.figsize'] = 10, 5
result.plot()
numpy教程 pdfpyplot.figure(figsize=(40,10))
pyplot.show()
上图的第⼀⾏代表实际数据,底部的三⾏显⽰了三个要素。这三个要素累加之后即可以获得原始数据。第⼆个样本集代表趋势性,第三个样本集代表季节性。如果我们考虑完整的时间范围,你会看到趋势⼀直在变化,并且在波动。对于季节性,很明显,在规律的时间间隔之后可以看到峰值。
如何获得季节性调整值?
对于可加性模型,可以通过y(t)– s(t)获得季节性调整后的值,对于乘法数据,可以使⽤y(t)/ s(
t)来调整值。
如果你正想问为什么我们需要季节性调整后的数据,让我们回顾⼀下刚才讨论过的有关美国失业率的⽰例。因此,如果季节性本⾝不是我们的主要关注点,那么季节性调整后的数据将更有⽤。尽管经典⽅法很常见,但由于以下原因,不太建议使⽤它们:
该技术对异常值不可靠。
它倾向于使时间序列数据中的突然上升和下降过度平滑。
假设季节性因素每年只重复⼀次。
对于前⼏次和最后⼏次观察,该⽅法都不会产⽣趋势周期估计。
其他可⽤于分解的更好⽅法是X11分解,SEAT分解或STL分解。现在,我们将看到如何在Python中⽣成它们。
与经典法,X11和SEAT分解法相⽐,STL具有许多优点。接下来,让我们探讨STL分解法。
STL分解法
STL代表使⽤局部加权回归(Loess)进⾏季节性和趋势性分解。该⽅法对异常值具有鲁棒性,可以处理任何类型的季节性。这个特性还使其成为⼀种通⽤的分解⽅法。使⽤STL时,你控制的⼏件事是:
趋势周期平滑度
季节性变化率
可以控制对⽤户异常值或异常值的鲁棒性。这样你就可以控制离值对季节性和趋势性的影响。
同任何其他⽅法⼀样,STL也有其缺点。例如,它不能⾃动处理⽇历的变动。⽽且,它仅提供对可加性模型的分解。但是你可以得到乘法分解。你可以⾸先获取数据⽇志,然后通过反向传播要素来获取结果。但是,这超出了本⽂讨论的范围。
Import pandas as pd
Import seaborn as sns
Import matplotlib.pyplot as plt
From statsmodels.tsa.seasonal import STL
elecequip =read_csv(r"C:/Users/datas/python/data/elecequip.csv")
stl = STL(elecequip, period=12, robust=True)
res_robust = stl.fit()
fig = res_robust.plot()
时间序列预测的基本⽅法
尽管有许多统计技术可⽤于预测时间序列数据,我们这⾥仅介绍可⽤于有效的时间序列预测的最直接、最简单的⽅法。这些⽅法还将⽤作其他⽅法的基础。
PYTHON中的简单移动平均(SMA)
简单移动平均是可以⽤来预测的所有技术中最简单的⼀种。通过取最后N个值的平均值来计算移动平均值。我们获得的平均值被视为下⼀个时期的预测。
为什么使⽤简单移动平均?
移动平均有助于我们快速识别数据趋势。你可以使⽤移动平均值确定数据是遵循上升趋势还是下降趋势。
它可以消除波峰波⾕等不规则现象。这种计算移动平均值的⽅法称为尾随移动平均值。在下⾯的⽰例中,我们使⽤rolling()函数来获取电⽓设备销售数据的移动平均线。
Import pandas as pd
from matplotlib import pyplot
elecequip = pd.read_csv(r"C:/Users/datas/python/data/elecequip.csv")
# Taking moving average of last 6 obs
rolling = lling(window=6)
rolling_mean = an()
# plot the two series
pyplot.plot(elecequip)
pyplot.plot(rolling_mean, color='red')
pyplot.show()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论