本篇文章是针对下文解读:
作者:Treant
出处:http://www.cnblogs.com/en-heng/ http://www.cnblogs.com/en-heng/
所谓STL时序分解,就是将基于LOESS将某一时刻的数据分解为趋势分量(trend)、周期分量(seasonal)和余项。
其中,趋势项指的是时间序列整体呈现的一种上升或下降的趋势,周期项则表现为其在国定时长内表现重复,余项就是数据值减去周期项和趋势项。
STL时序分解就是将一张图分解为三张图。
这时候一定会有很多和我一样初学的同学就会问了:思想我懂了,但怎么分解呢?基于LOESS又是什么呢?
LOESS
想要了解LOESS,我们先要知道LOWESS。(开始套娃)
1.LOWESS
LOWESS就是局部加权回归。局部先别管,它的核心就是加权回归。
回归回归,听得这么洋气,土点说就是在大量数据点中学习一条线将他们都串起来。
那么问题便是加权了。
传统KNN的平均回归大家应该都有用过:我想要预测x点的值,那么我就将距离x点最近的k个点都拿出来,将他们的值相加,取个平均数,就是x点的预测值。
(这里xi是里x最近的k个数据点)
大家一定和我一样,都觉得这种方法又土又捞吧。这种平均回归不仅没有考虑不同距离的点对x点的影响权重不同,由于孤立地计算各点,产生的回归曲线还可能是不连续的。
因此我们引入一种加权平滑的回归:
其中,K就是每个点的加权值了。众所周知,离x点越远对x产生的影响也就越小,因此我们可以设置K为:
其中被称为window width。这里,我们只考虑最近的k个点,那么我们可以把
设置为k个点的窗口内
与最远点的距离。那么在这个窗口内,t的值将一直小于1,且距离越近,权值越大。
之所以将t设置为二次呢?想来是为了平滑。(没查过资料,纯属经验之谈)
接着,问题又来了。这种加权平滑回归确实不错,但是这种回归存在边界问题。所谓边界问题:就是当你加权回归第一个或最后一个甚至邻接边界的点时,你会发现左右是不对称的。通俗地说,对于第一个点,它的右侧是没问题的,但是你会发现,他的左侧没有点给它加权了。如果这段数据是递增的,那么第一个点只受之后的点影响,很显然,之后的点更大,那么预测值也会偏大。因此边界问题会导致预测值的不准确。(老实说,我还真看不出来这有多大的影响。大家都做大数据了嘛,大大小小的误差也不差这么一点)
那么那么又来了。为了避免边界问题,我们对原来的权值进行修正:
(a)
目标函数: 其中
为变量
曾经有一门线代课摆在我眼前,我没好好珍惜。所以现在是什么鬼啊!
这哪里是修正权值,除了个k还有哪个地方和上面是一样的?
虽然有些混乱,但是不难发现,这里的目标函数的目标是使两者的差值最小。那么,神奇的地方出现了:
式(a)中的j的实际意义是位于x0位置的第j个点,及x0位置上一共有d个数据点。
其实当我看到这里的时候,我又陷入了困惑:这修正怎么这么菜?这也算优化?
但这个目标函数让我灵光一现:式(a)的预测实际上是对目标点x0周围点的预测。在原来的回归中,我们取预测值为目标周围点的K、y乘积之和。在这里,我们将用与K预测,而目标函数则通过调整
,使
与y拟合。
接下来我们一步步求解:
令
这里我们需要解的是目标函数取最小时的Δ
先将目标函数改写为矩阵形式:
好了,接下来我又不会了。于是悔恨交加的我又去学了便矩阵求导。
对上式关于Δ求偏导(经过一阵xjb操作):
那么预测值就出来了
从此以后,我们只需要根据整体数据求出Δ后,只根据目标点所处位置的点与Δ就可以求出该点预测值了,这种回归方法就叫做LOWESS。
2.Robust LOWESS
首先定义回归残差;
定义robustnest weight:
其中,s为残差值绝对值序列得中位值,B为bisquare函数:
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
、