2021-07-20

 本篇文章是针对下文解读:

作者:Treant

出处:http://www.cnblogs.com/en-heng/              http://www.cnblogs.com/en-heng/

         所谓STL时序分解,就是将基于LOESS将某一时刻的数据分解为趋势分量(trend)、周期分量(seasonal)和余项。

                                                         Y_{t}=T_{t}+S_{t}+R_{t}

        其中,趋势项指的是时间序列整体呈现的一种上升或下降的趋势,周期项则表现为其在国定时长内表现重复,余项就是数据值减去周期项和趋势项。

        STL时序分解就是将一张图分解为三张图。

        这时候一定会有很多和我一样初学的同学就会问了:思想我懂了,但怎么分解呢?基于LOESS又是什么呢?

LOESS

        想要了解LOESS,我们先要知道LOWESS。(开始套娃)

1.LOWESS

        LOWESS就是局部加权回归。局部先别管,它的核心就是加权回归。

        回归回归,听得这么洋气,土点说就是在大量数据点中学习一条线将他们都串起来。

        那么问题便是加权了。

        传统KNN的平均回归大家应该都有用过:我想要预测x点的值,那么我就将距离x点最近的k个点都拿出来,将他们的值相加,取个平均数,就是x点的预测值。

                                            \widehat{f}(x)=\frac{1}{k}\sum f(x_{i})    i=1...k    (这里xi是里x最近的k个数据点)

        大家一定和我一样,都觉得这种方法又土又捞吧。这种平均回归不仅没有考虑不同距离的点对x点的影响权重不同,由于孤立地计算各点,产生的回归曲线还可能是不连续的。

        因此我们引入一种加权平滑的回归:

                                \widehat{f}(x)=\frac{\sum_{i=1}^{n}K_{\lambda}(x_{0},x_{i})y_{i}}{\sum_{i=1}^{n}K_{\lambda}(x_{0},x_{i})}

        其中,K就是每个点的加权值了。众所周知,离x点越远对x产生的影响也就越小,因此我们可以设置K为:

K_{\lambda }(x_{0},x_{i})=D(\frac{|x_{0}-x_{i}|}{\lambda })

D(t)=\frac{3}{4}(1-t^{2})\, \, \,\, \, \, \, |y|<1 \; \; \; \; \; else\, \, \, D(t)=0

        其中\lambda被称为window width。这里,我们只考虑最近的k个点,那么我们可以把\lambda设置为k个点的窗口内x_{0}与最远点的距离。那么在这个窗口内,t的值将一直小于1,且距离越近,权值越大。

        之所以将t设置为二次呢?想来是为了平滑。(没查过资料,纯属经验之谈)

        接着,问题又来了。这种加权平滑回归确实不错,但是这种回归存在边界问题。所谓边界问题:就是当你加权回归第一个或最后一个甚至邻接边界的点时,你会发现左右是不对称的。通俗地说,对于第一个点x_{0},它的右侧是没问题的,但是你会发现,他的左侧没有点给它加权了。如果这段数据是递增的,那么第一个点只受之后的点影响,很显然,之后的点更大,那么预测值也会偏大。因此边界问题会导致预测值的不准确。(老实说,我还真看不出来这有多大的影响。大家都做大数据了嘛,大大小小的误差也不差这么一点)

        

        那么那么又来了。为了避免边界问题,我们对原来的权值进行修正:

                                                                  \widehat{f}(x_{0})=\sum_{j=0}^{d}\beta _{j}x_{0}^{j}                   (a)

目标函数:                     min\sum_{i=1}^{N}K_{\lambda }(x_{0},x_{i})[y_{i}-\sum_{j=0}^{d}\beta _{j}x_{i}^{j}]^{2}  其中\beta为变量

        曾经有一门线代课摆在我眼前,我没好好珍惜。所以现在是什么鬼啊!

        这哪里是修正权值,除了个k还有哪个地方和上面是一样的?

        虽然有些混乱,但是不难发现,这里的目标函数的目标是使[y_{i}-\sum_{j=0}^{d}\beta _{j}x_{i}^{j}]^{2}两者的差值最小。那么,神奇的地方出现了:

        式(a)中的j的实际意义是位于x0位置的第j个点,及x0位置上一共有d个数据点。

        其实当我看到这里的时候,我又陷入了困惑:这修正怎么这么菜?这也算优化?

        但这个目标函数让我灵光一现:式(a)的预测实际上是对目标点x0周围点的预测。在原来的回归中,我们取预测值为目标周围点的K、y乘积之和。在这里,我们将用\sum_{j=0}^{d}\beta _{j}x_{0}^{j}与K预测,而目标函数则通过调整\beta,使\sum_{j=0}^{d}\beta _{j}x_{0}^{j}与y拟合。

        接下来我们一步步求解\beta

 令

   

B=\begin{bmatrix} 1 & x_{1} & ... &x_{1}^{d} \\ 1 & x_{2} & ... &x_{2}^{d} \\ ...& ... & ...& ...\\ 1 & x_{N}&... &x_{N}^{d} \end{bmatrix}

 

       

W_{x_{0}}=\begin{bmatrix} K_{\lambda }(x_{0},x_{1}) & 0 &... &0 \\ 0& K_{\lambda }(x_{0},x_{2}) & ...&0 \\ ...&... & ... &... \\ 0& 0&... & K_{\lambda }(x_{0},x_{N}) \end{bmatrix}

 

\Delta =(\beta _{0},\beta_{1},...,\beta_{d})^{T}

 

Y=(y_{1},y_{2},...,y_{N})^{T}

 

 这里我们需要解的是目标函数取最小时的Δ

先将目标函数改写为矩阵形式:

min(Y-B\Delta )^{T}(Y-B\Delta)W_{x_{0}}

好了,接下来我又不会了。于是悔恨交加的我又去学了便矩阵求导。

对上式关于Δ求偏导(经过一阵xjb操作):

\Delta =(B_{T}W_{x_{0}B})^{-1}(B_{T}W_{x_{0}}Y)

那么预测值就出来了

f(\hat{x_{0}})=(1,x_{0},...,x_{0}^{d})\Delta

        从此以后,我们只需要根据整体数据求出Δ后,只根据目标点所处位置的点与Δ就可以求出该点预测值了,这种回归方法就叫做LOWESS。

2.Robust LOWESS

        首先定义回归残差;

e_{i}=y_{i}-f(\hat{x}_{i})

        定义robustnest weight:

\delta _{i}=B(e_{i}/6s)

        其中,s为残差值绝对值序列得中位值,B为bisquare函数:

                ​​​​​​​        ​​​​​​​        ​​​​​​​        B(u)=(1-u^{2})^{2} for \, \, \, \, 0\leq u<1\: \: \: \: \: else\: \: \: B(u)=0

        robustnest weight 乘以kernel weight(K)作为W得新weight,残差越大,计算出的robustnest越小,在kernel weight中产生影响越小,从而剔除残差较大的异常点对于回归的影响

STL时序分解算法

        好了,理解完Robust LOWESS之后,我们终于可以回归STL了。

        STL有内循环和外循环。其中,外循环主要用于调节robustness weight,减少残差值过大项的影响,而内循环一共有6个步骤,用于趋势拟合和周期分量的计算:

        我们取每个周期相同位置的样本点组成一个子序列。初始时,设置趋势项T=0。

  • Step 1: 去趋势。即减去上一轮循环的趋势分量Y-T。
  • Step 2:周期子序列平滑。用LOESS对每个子序列做回归,并前后各自延展一个周期,得到序列C。
  • Step 3:周期子序列的低通量过滤。对C依次做长度为一周期样本数、一周期样本数、3的滑动平均,再做LOESS回归,得到序列L,相当于周期子序列的低通量。
  • Step 4:去除平滑周期子序列趋势。周期项S=C-L。
  • Step 5:去周期。Y-S。
  • Step 6:趋势平滑。对去周期的序列再做LOESS回归,得到趋势分量T。

是不是感觉没看懂?挺巧的,我也没看懂。我决定去补习一下滑动平均,看懂了Step3再继续分析。

不过很巧的是,我发现python里面STL的包,只要设置其中函数参数就行了。所以,其实看不懂原理,我们还是可以先读懂接口和实现的。

https://www.statsmodels.org/stable/examples/notebooks/generated/stl_decomposition.html

        

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值