2.4 数据的平滑处理
对时间序列数据(如信号数据或股票价格数据)进行统计分析时,可能存在数据的缺失或奇异(如ST股票反复的停牌),此时往往需要对数掘进行平滑处理。本节介绍基于MATLAB的数据平滑方法和smooth函数、smoothts函数、medfiltl函数的用法。
注:缺失的数据或奇异的数据的处理是否影响结论的正确性?由于数据缺失的原因不同,奇异数据是否为具实数据(代表了市场某种内在逻辑,例如分级基金A份额分红后连续跌停是由于分级计价机制造成的),这些问题需要在数据处理前考虑周全。
2.4.1 smooth函数
MATLAB曲线拟合工具箱中提供了smooth函数用来对数据进行平滑处理,其调用方式如下:


1. yy=smooth(y)
利用移动平均滤波器对列向量y进行平滑处理,返回与y等长的列向量yy。移动平均滤波器的默认窗宽为5,yy中元素的计算方法如下:用method参数指定平滑数据的方法,method是字符串变量,可用的字符串如表2-3所示。

2. yy=smooth(y,span)
用span参数指定移动平均滤波器的窗宽,span为奇数。
3. yy=smooth(y,method)
用method参数指定平滑数据的方法,method是字符串变量,可用的字符串如表2-3所示。


4. yy=smooth(y,span,method)
对于由method参数指定的平滑方法,用span参数指定滤波器的窗宽。对于loess和lowess方法,span是一个小于或等于1的数,表示占全体数据点总数的比例;对于移动平均法和Savitzky-Golay法,span必须是一个正的奇数。只要用户输入的span是一个正数, smooth函数内部会自动把span转为正的奇数。
5. yy=smooth(y,'sgolay',degree)
利用Savitzky-Golay方法平滑数据,此时用degree参数指定多项式模型的阶数。degree是一个整数,取值介于0和span-1之间。
6. yy=smooth(y,span,'sgolay',degree)
用span参数指定Savitzky-Golay滤波器的窗宽。span必须是一个正的奇数,degree是一个整数,取值介于0和span-1之间。
7. yy=smooth(x,y,…)
同时指定x数据。如果没有指定X,则smooth函数自动令x=1:length(y)。当x是非均匀数据或经过排序的数据时,用户应指定x数据。如果x是非均匀数据而用户没有指定method参数,则smooth函数自动调用lowess方法。如果数据平滑方法要求x是经过排序的数据,则smooth函数自动对x进行排序。
【例2-7】产生一列正弦波信号,加入噪声信号,然后调用smooth函数对加入噪声的正弦波进行滤波(平滑处理)。





上面命令产生了一个周期的正弦波信号,并加上了正态分布随机数作为噪声信号,然后调用smooth函数,设置相同的窗宽,用5种方法对加噪后的信号进行平滑处理,做出的加噪波形图和平滑后波形图如上图所示,从中可以清楚地看出各种方法的平滑效果。总的来说,5种方法的平滑效果都不错,比较好地滤除了噪声,反映了数据的总体规律。实际上随着窗宽的增大,平滑处理后的曲线会越来越光滑,但过于光滑也可能造成失真。
2.4.2 smoothts函数
MATLAB金融工具箱中的smoothts函数也可用来对数据进行平滑处理,其调用方式如下:


smoothts函数的输入参数input是一个金融时间序列对象或行导向矩阵,其中金融时间序列对象是由MATLAB中的ascii2fts或fints函数创建的。行导向矩阵是指用行表示观测数据集的矩阵,若input是一个行导向矩阵,则input 的每一行都是一个单独的观测集。以上调用方式中的b、g、e表示不同的数据平滑方法,其中b表示盒子法(BoxMethod,为默认情况),g表示高斯窗方法(Gaussian Window Method), e表示指数法(Exponential Method)。输入参数wSlze是一个标量,用来指定各种数据平滑方法的窗宽,默认窗宽为5。输入参数stdev也是一个标量,用来指定高斯窗方法的标准差,默认值为0.65。对于指数法,输入参数n用来指定窗宽(wsize,默认值为5)或指数因子(alpha,默认值为0.3333),当n>1时,n是窗宽:当0<n<1时,n是指数因子:当n=1时,n是窗宽,也是指数因子。smoothts函数的输出参数output是平滑后数据,若input是一个金融时间序列对象,则output也是一个金融时间序列对象;若input是一个行导向矩阵,则output也是一个同样长度的行导向矩阵。
【例2-8】现有上海股市日开盘价、最高价、最低价、收盘价、收益率等数据,时间跨度为2005年1月4日至2007年4月3日,共510组数据。完整数据保存在文件StockPriceData.xls中,部分数据如图2-20所示。调用smoothts函数对日收盘价数据进行平滑处理。




如图2-21所示,上海股市日收盘价曲线比较曲折,不够光滑。我们可以调用smoothts函数,用3种不同的方法(ox method、Gaussian window method和Exponential method),每种方法设定两种不同的窗宽,对上海股市日收盘价数据进行了平滑处理,做出的平滑曲线如图2-22~图2-24所示。从图中可以看出,前两种方法在端点处的平滑效果不是很好,最后一种方法在右尾部的处理有些失真。总的来说,在数据的中段,3种方法的平滑效果都比较好,并且随着窗宽的增大,平滑后的曲线的光滑性也在增强,但光滑性增强的同时也造成了失真。
2.4.3 medfiltl函数
MATLAB信号处理工具箱中的medfilt1函数用来对信号数据进行一维中值滤波,其调用方式如下:


2. y=medfilt1(x,n,blksz)
用for循环,每次循环输出blksz个计算值,默认情况下,blksz=length1(x)。当x是一个矩阵时,通过循环对x的各列进行一维中值滤波,返回与x具有相同行数和列数的矩阵y。
3. y=medfilt1(x,n,blksz,dim)
用dim参数指定沿x的哪个维进行滤波。
【例2-9】产生一列正弦波信号,加入噪声信号,然后调用medfilt1函数对加入噪声的正弦波进行滤波(平滑处理)。

如上命令产生了一个周期的正弦波信号,并加上了取自正态分布N(0,152)的随机数作为噪声信号,然后调用medfilt1函数,设置窗宽为30,对加噪后正弦波信号进行一维中值滤波,绘出的加噪波形图和平滑后波形图如图2-25和图2-26所示。从图中可以看出,中值滤波比较好地滤除了噪声,反映了数据的总体规律。
