数据的预处理——平滑处理

在对时间序列数据(如信号数据或股票价格数据)进行统计分析时,往往需要对数据进行平滑处理,本次主要介绍smooth函数、smoothts函数和medfilt1函数的用法

1.smooth函数

smooth函数调用格式如下:
1) yy=smooth(y)
利用移动平均滤波器对列向量y进行平滑处理,返回与y等长的列向量yy。移动平均滤波器的默认窗宽为5,yy中元素的计算方法如下:
yy(1)=y(1)
yy(2)=(y(1)+y(2)+y(3))/3
yy(3)=(y(1)+y(2)+y(3)+y(4)+y(5))/5
yy(4)=(y(2)+y(3)+y(4)+y(5)+y(6))/5
yy(5)=(y(3)+y(4)+y(5)+y(6)+y(7))/5

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

method参数值说明
'moving ’移动平均法(默认情况)。一个低通滤波器,滤波系数为窗宽的倒数
’ lowess’局部回归(加权线性最小二乘和一个一阶多项式模型)
‘loess’局部回归(加权线性最小二乘和一个二阶多项式模型)
‘sgolay’Savitzky -Golay滤波。一种广义移动平均法.滤波系数由不加权线性最小二乘回归和一个多项式模型确定,多项式模型的阶数n可以指定(默认为2)
‘rlowess’'lowess’方法的稳健形式。异常值被赋予较小的权重,6倍的平均绝对偏差以外的数据的权重为0
‘rloess’'loess’方法的稳健形式。舁常值被赋予较小的权承.6倍的平均绝对偏差以外的数据的权重为0

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方法平滑数据,此时用dcgree参数指定多项式模型的阶数。dcgree是一个整数,取值介于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进行排序。

【例】产生一列正弦波信号,加入噪声信号,然后调用smooth函数对加入噪声的正弦波进行滤波(平滑处理)。

%--------------------------------------------------------------------------
%              调用smooth函数进行加噪数据的平滑处理
%--------------------------------------------------------------------------

%*****************产生加噪正弦波信号,绘制加噪波形图*************************
t = linspace(0,2*pi,500)';  		% 产生一个从02*pi的向量,长度为500
y = 100*sin(t);  					% 产生正弦波信号
% 产生5001列的服从N(0,15^2)分布的随机数,作为噪声信号
noise = normrnd(0,15,500,1);
y = y + noise; 						% 将正弦波信号加入噪声信号
figure;  							% 新建一个图形窗口
plot(t,y);  						% 绘制加噪波形图
xlabel('t');  						% 为X轴加标签
ylabel('y = sin(t) + 噪声');  		% 为Y轴加标签


%*************利用移动平均法对加噪信号进行平滑处理,绘制平滑波形图*************
yy1 = smooth(y,30);  				% 利用移动平均法对y进行平滑处理
figure;  							% 新建一个图形窗口
plot(t,y,'k:');  					% 绘制加噪波形图
hold on;
plot(t,yy1,'k','linewidth',3);  	% 绘制平滑后波形图
xlabel('t');  						% 为X轴加标签
ylabel('moving');  					% 为Y轴加标签
legend('加噪波形','平滑后波形');


%*************利用lowess方法对加噪信号进行平滑处理,绘制平滑波形图*************
yy2 = smooth(y,30,'lowess');  		% 利用lowess方法对y进行平滑处理
figure;  							% 新建一个图形窗口
plot(t,y,'k:');  					% 绘制加噪波形图
hold on;
plot(t,yy2,'k','linewidth',3);  	% 绘制平滑后波形图
xlabel('t');  						% 为X轴加标签
ylabel('lowess');  					% 为Y轴加标签
legend('加噪波形','平滑后波形');


%*************利用rlowess方法对加噪信号进行平滑处理,绘制平滑波形图************
yy3 = smooth(y,30,'rlowess');  		% 利用rlowess方法对y进行平滑处理
figure;  							% 新建一个图形窗口
plot(t,y,'k:');  					% 绘制加噪波形图
hold on;
plot(t,yy3,'k','linewidth',3);  	% 绘制平滑后波形图
xlabel('t');  						% 为X轴加标签
ylabel('rlowess');  				% 为Y轴加标签
legend('加噪波形','平滑后波形');


%*************利用loess方法对加噪信号进行平滑处理,绘制平滑波形图*************
yy4 = smooth(y,30,'loess');  		% 利用loess方法对y进行平滑处理
figure;  							% 新建一个图形窗口
plot(t,y,'k:');  					% 绘制加噪波形图
hold on;
plot(t,yy4,'k','linewidth',3);  	% 绘制平滑后波形图
xlabel('t');  						% 为X轴加标签
ylabel('loess');  					% 为Y轴加标签
legend('加噪波形','平滑后波形');


%*************利用sgolay方法对加噪信号进行平滑处理,绘制平滑波形图*************
yy5 = smooth(y,30,'sgolay',3);  	% 利用sgolay方法对y进行平滑处理
figure;  							% 新建一个图形窗口
plot(t,y,'k:');  					% 绘制加噪波形图
hold on;
plot(t,yy5,'k','linewidth',3);  	% 绘制平滑后波形图
xlabel('t');  						% 为X轴加标签
ylabel('sgolay');  					% 为Y轴加标签
legend('加噪波形','平滑后波形');

加噪波形图:
在这里插入图片描述
平滑后波形图(移动平均法):
在这里插入图片描述
平滑后波形图(lowess法):
在这里插入图片描述
平滑后波形图(rlowess法):
在这里插入图片描述
平滑后波形图(loess法):
在这里插入图片描述
平滑后波形图(sgolay法):
在这里插入图片描述
实际上随着窗宽的增大,平滑后的曲线会越来越光滑,但过于光滑也可能造成失真。

2.smoothts函数

smoothts函数调用格式如下:
output = smoothts(input)
output = smoothts(input,‘b’,wsize)
output = smoothts(input,‘g’,wsize,stdev)
output = smoothts(input,‘e’,n)

smoothts函数的输入参数input是一个金融时间序列对象或行导向矩阵,其中金融时间序列对象是MATLAB中由ascii2fts或fints函数所创建的一种对象。行导向矩阵是指用行表示观测数据集的矩阵,若input是一个行导向矩阵,input的每一行都是一个单独的观测集。
以上调用格式中的’b’,‘g’,或’e’表示不同的数据平滑方法,其中’b’表示盒子法(box method),'g’表示高斯窗方法(gaussian window method),'e’表示指数法(exponential method)。
输入参数wsize是一个标量,用来指定各种数据平滑方法的窗宽,默认窗宽为5.
输入参数stdcv也是一个标量,用来指定高斯窗方法的标准差,默认值为0.65
【例】现有上海股市日开盘价、最高价、最低价、收盘价、收益率等数据,时间跨度为2005年1月4日至2007年4月3日,共510组数据。完整数据保存在文件examp03_02.xls中,试调用smoothts函数对日收盘价数据进行平滑处理。

%--------------------------------------------------------------------------
%              调用smoothts函数对金融时间序列数据进行平滑处理
%--------------------------------------------------------------------------

%*********************读取金融时间序列数据,绘制波形图************************
x = xlsread('examp03_02.xls');  				% 从文件examp03_02.xls中读取数据
price = x(:,4)';  								% 提取矩阵x的第4列数据,即收盘价数据
figure;  										% 新建一个图形窗口
plot(price,'k','LineWidth',2);  				% 绘制日收盘价曲线图,黑色实线,线宽为2
xlabel('观测序号'); ylabel('上海股市日收盘价'); 	% 为X轴和Y轴加标签


%*****************利用盒子法对数据进行平滑处理,绘制平滑波形图****************
output1 = smoothts(price,'b',30);  				% 用盒子法平滑数据,窗宽为30
output2 = smoothts(price,'b',100);  			% 用盒子法平滑数据,窗宽为100
figure;  										% 新建一个图形窗口
plot(price,'.');  								% 绘制日收盘价散点图
hold on
plot(output1,'k','LineWidth',2);  				% 绘制平滑后曲线图,黑色实线,线宽为2
plot(output2,'k-.','LineWidth',2);  			% 绘制平滑后曲线图,黑色点划线,线宽为2
xlabel('观测序号'); ylabel('Box method'); 		% 为X轴和Y轴加标签
% 为图形加标注框
legend('原始散点','平滑曲线(窗宽30)','平滑曲线(窗宽100)','location','northwest');


%****************利用高斯窗方法对数据进行平滑处理,绘制平滑波形图**************
output3 = smoothts(price,'g',30);  				% 窗宽为30,标准差为默认值0.65
output4 = smoothts(price,'g',100,100);  		% 窗宽为100,标准差为100
figure;  										% 新建一个图形窗口
plot(price,'.');  								% 绘制日收盘价散点图
hold on
plot(output3,'k','LineWidth',2);  				% 绘制平滑后曲线图,黑色实线,线宽为2
plot(output4,'k-.','LineWidth',2);  			% 绘制平滑后曲线图,黑色点划线,线宽为2
xlabel('观测序号'); ylabel('Gaussian window method'); % 为X轴和Y轴加标签
legend('原始散点','平滑曲线(窗宽30,标准差0.65)',...
          '平滑曲线(窗宽100,标准差100)','location','northwest');


%*****************利用指数法对数据进行平滑处理,绘制平滑波形图****************
output5 = smoothts(price,'e',30); 				% 用指数法平滑数据,窗宽为30
output6 = smoothts(price,'e',100);  			% 用指数法平滑数据,窗宽为100
figure;  										% 新建一个图形窗口
plot(price,'.');  								% 绘制日收盘价散点图
hold on
plot(output5,'k','LineWidth',2);  				% 绘制平滑后曲线图,黑色实线,线宽为2
plot(output6,'k-.','LineWidth',2);  			% 绘制平滑后曲线图,黑色点划线,线宽为2
xlabel('观测序号'); ylabel('Exponential method'); % 为X轴和Y轴加标签
legend('原始散点','平滑曲线(窗宽30)','平滑曲线(窗宽100)','location','northwest');

原始收盘价曲线图:
在这里插入图片描述
平滑后曲线图(box method):
在这里插入图片描述
平滑后曲线图(gaussian window method):
在这里插入图片描述

平滑后曲线图(exponential method):
在这里插入图片描述
总的来说,在数据的中端,3种方法的平滑效果都比较好,并且随着窗宽的增大,平滑后的曲线的光滑性也在增强,但光滑性增强的同时也造成了失真。

  • 25
    点赞
  • 254
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
数据预处理中的自定义转换是指将数据集中的原始数据按照一定的规则进行处理,以便于后续的模型训练和应用。C++作为一门强类型语言,提供了丰富的数据类型和操作函数,可以非常方便地实现数据预处理中的自定义转换。下面以一个简单的案例来演示如何使用C++实现数据预处理中的自定义转换。 假设我们有一个包含学生信息的数据集,其中每个学生的信息包括姓名、年龄、性别与成绩四个属性。现在我们要对这个数据集进行处理,将每个学生的成绩按照以下规则转换为一个0~5的整数: - 小于60分的成绩转换为0 - 60~69分的成绩转换为1 - 70~79分的成绩转换为2 - 80~89分的成绩转换为3 - 90~99分的成绩转换为4 - 100分的成绩转换为5 下面是一个使用C++实现的解决方案: ```c++ #include <iostream> #include <vector> #include <string> using namespace std; // 定义一个结构体,表示学生信息 struct Student { string name; int age; char gender; int score; }; // 自定义转换函数,将成绩转换为0~5的整数 int score_transform(int score) { if (score < 60) { return 0; } else if (score < 70) { return 1; } else if (score < 80) { return 2; } else if (score < 90) { return 3; } else if (score < 100) { return 4; } else { return 5; } } int main() { // 定义一个学生信息列表 vector<Student> students = { {"张三", 18, 'M', 75}, {"李四", 19, 'F', 68}, {"王五", 20, 'M', 92}, {"赵六", 21, 'F', 85} }; // 遍历学生信息列表,将成绩转换为整数 for (auto& student : students) { student.score = score_transform(student.score); } // 输出转换后的学生信息列表 for (auto& student : students) { cout << student.name << " " << student.age << " " << student.gender << " " << student.score << endl; } return 0; } ``` 在上面的代码中,我们首先定义了一个包含学生信息的结构体`Student`,并且定义了一个自定义转换函数`score_transform`,用于将成绩转换为整数。然后我们定义了一个学生信息列表`students`,并且遍历该列表,将每个学生的成绩按照自定义转换函数进行转换。最后我们输出转换后的学生信息列表。 需要注意的是,在实际应用中,我们可能需要进行更加复杂的自定义转换,例如对数据进行归一化、标准化、降维等处理。C++提供了丰富的函数库和工具,可以帮助我们实现这些复杂的自定义转换。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你是誰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值