首页IT科技时间序列的时序图怎么看(【时序列】时序列数据如何一步步分解成趋势(trend)季节性(seasonality)和误差(residual)- 详细理解python sm.tsa.seasonal_decompose)

时间序列的时序图怎么看(【时序列】时序列数据如何一步步分解成趋势(trend)季节性(seasonality)和误差(residual)- 详细理解python sm.tsa.seasonal_decompose)

时间2025-06-20 19:10:20分类IT科技浏览3929
导读:【时序列】时序列数据如何一步步分解成趋势(trend)季节性(seasonality)和误差(residual)- 理解python sm.tsa.seasonal_decompose...

【时序列】时序列数据如何一步步分解成趋势(trend)季节性(seasonality)和误差(residual)- 理解python sm.tsa.seasonal_decompose

在做时序列分析的时候            ,好多教程都告诉你要把时序列分解成趋势                 ,季节性      ,残差         ,然后画图看一下有没有趋势变化                 ,有没有季节性            。像这样:

import statsmodels.api as sm decomposition = sm.tsa.seasonal_decompose(train[Count] ,model=addictive, period=7) decomposition.plot()

相信大家都很熟悉python的这个包和命令         ,但是具体是如何分解的却不是特别清楚                 。今天就来详细理解一下一个时序列是如何一步一步被分解的      。

举个例子理解概念

首先我们默认每个时序列在某个时间点i的数值      ,都可以分解成三部分                 ,分别是趋势           ,季节性和残差   ,以此来解释时序列的变化         。

比如                  ,某列车2021年2月的总乘客人数1000人              ,这1000人如何理解,为什么是1000人?

2018年2月还是100人               ,2021年1月还是300人                 ,为啥到2021年2月就1000人了?

首先   ,可能因为列车开通后乘车人数有逐年上升的趋势            ,每年增加100人                 ,2018年到2021年的3年之间增加了300人      ,只考虑趋势原因的话2021年2月应该是:100+300=400人

然后         ,和2021年1月分相比                 ,2021年2月是春节         ,每年的2月乘客都1月多200人      ,只考虑春节这个季节性原因的话2021年2月应该是:300+200=500人

把季节性和趋势原因都考虑进去应该是:400+500=900人                 ,但2021年2月是1000人           ,剩下的100人如何解释呢?暂时解释不了   , 我们就把它作为残差(误差)

理解了例子公式就简单了

就是下面这个公式:

y_i = t_i + s_i + n_i

y_i :在i时间点的数值(乘客人数                  ,销量等等)

t_i :在i时间点的趋势

s_i :在i时间点的季节性

n_i:在i时间点的残差

当然在上面这个例子里              ,我们假设这个y(乘客人数),是线性增长的               ,所以我们用加法把每个要素加起来                 ,来解释y的变化                 。

如果y不是线性增长   ,而是比如指数增长的            ,那就不能用加法                 ,需要用乘法      ,即:

y_i = t_i * s_i * n_i

decomposition = sm.tsa.seasonal_decompose(train[‘Count’], model=‘addictive’, period=7)

那么         ,上面这句代码里的model就应该从‘addictive’                 , 改成‘multiplicative’

一步步分解趋势         ,季节性      ,残差

所以趋势                 ,季节性           ,残差都是咋分出来的呢         。计算方法貌似有很多   ,我们理解一个最基本的      。

五步走:

1: 确定季节性变化的期间

2: 分离 趋势

3: 分离 季节性+残差

4: 分离 季节性

5: 分离 残差

1: 确定季节变化的期间

这个期间就是decompose命令里面的period                 。看一下你的数据图           。我手头的数据是日次的                  ,看起来以周为单位有一个先升高再下降的循环   。所以我把period定为7(7天的意思)

2: 分离 趋势

7这个期间定好之后              ,我们用移动平均的方法分离趋势                  。为了方便解释,我都用excel做示例              。

计算的时候               ,以7的中心为开始计算移动平均。所以时序列最开始的3个三个数和最后的3个数是没有值的               。

个人理解                 ,如果季节性以周次出现   ,那么以7为单位计算的时候            ,比如每周六日数值都很高                 ,这个因素就每个cycle(周)里面都有      ,平均下来的数值         ,就可以看作是摒弃了季节性的趋势的影响                 。

可以看到计算结果和python的decompose是一样的

3: 分离 季节性+残差

分离好趋势之后                 ,如果你选的是model=‘addictive’         ,根据公式y_i = t_i + s_i + n_i      , 我们只要用数值减去趋势那部分                 ,就能得到季节性+残差的部分了   。如果是multiplicative           ,那就是除以趋势            。

结果如下   ,季节性+残差

4                  ,5: 分离 季节性 残差

接下来就从季节性+残差里面把季节性分出来                 。比如              ,如果时序列是周次季节性,那么周一的数值               ,就减去所有周一的数值的平均                 ,周二的数值就减去所有周二的平均   ,以此类推            ,剩下的就是残差了      。当然这只举了一个分离季节性的超简单逻辑         。python里面decompose貌似用了更复杂的计算方法来计算季节性                 ,由于篇幅过大暂且省略                 。

验证以下python的结果

看一下用python的seasonal_decompose算完      ,季节性         ,趋势                 ,残差         ,加起来是不是真的等于原来的数值         。

代码如下 decomposition = sm.tsa.seasonal_decompose(train[Count],model=addictive, period=7) #Additive trend = decomposition.trend seasonal = decomposition.seasonal residual = decomposition.resid train[trend]=trend train[seasonal]= seasonal train[residual]= residual train[add] = train[trend]+train[seasonal+*train[residual]

结果如下      ,Count果然和三个加起来的数值是一样的      。

前三行的trend是没有值的                 。这是因为以7为中心算移动平均的时候                 ,中心点位置是第四行           ,前3行没有值也就可以理解了           。

就写到这里   。欢迎大家指导讨论!

【参考文献】

https://timeseriesreasoning.com/contents/time-series-decomposition/

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
python merge inner(python merge()的连接)