基于Savitzky-Golay (SG) 的数据去噪(MATLAB-附案例代码)

1. 摘要

低质量的数据导致低质量的数据挖掘结果。数据是数据挖掘的目标对象和原始资源,对数据挖掘最终结果起着决定性的作用。现实世界中的数据是多种多样的,具有不同的特征,这就要求数据的存储采用合适的数据类型,并且数据挖掘算法的适用性会受到具体的数据类型限制。现实世界中的数据大多都是“脏”的,原始数据通常存在着噪声、不一致、部分数据缺失等问题。本文将使用SG滤波器,对含噪声的正弦曲线数据进行去噪,其中为学习使用归一化和标准化方法,将使用标准化和归一化方法对生成的噪声数据进行处理,观察处理前后的数据进去噪后的结果。

2. 基本原理

噪声数据是指:收集数据时很难得到精确的数据,如数据采集设备故障、数据传输过程中,会出现错误或存储介质可能出现的损坏等情况。

常用的数据去噪方法主要有:基于滤波器的去噪法(中值滤波器,自适应维纳滤波器),时间序列去噪法(滚动平均法,傅里叶变换法),Savitzky-Golay 滤波器、滑动平均法、插值法,小波去噪等。

2.1 Savitzky-Golay 滤波器

Savitzky-Golay滤波器(通常简称为S-G滤波器)最初由Savitzky和Golay于1964年提出,发表于Analytical Chemistry 杂志。之后被广泛地运用于数据流平滑除噪,是一种在时域内基于局域多项式最小二乘法拟合的滤波方法。这种滤波器最大的特点在于在滤除噪声的同时可以确保信号的形状、宽度不变。

使用平滑滤波器对信号滤波时,实际上是拟合了信号中的低频成分,而将高频成分平滑出去了。如果噪声在高频端,那么滤波的结果就是去除了噪声,反之,若噪声在低频段,那么滤波的结果就是留下了噪声。S-G平滑滤波的效果,随着选取窗宽不同而不同,可以满足多种不同场合的需求。

Savitzky和Golay 发现计算最小二乘拟合的常数项,相当于对原始数据进行一次FIR 滤波,也即可以利用卷积运算来实现。

y[n]=\sum_{m=-M}^{M} {h[m]}x[n-m]=\sum_{m=n-M}^{n+M} {h[n-m]}x[m]

Savitzky-Golay卷积平滑算法是移动平滑算法的改进:

2.2 归一化与标准化

某些算法对预测变量是有要求的,比如需要预测变量具有相同的尺度,如果有的预测变量范围是0.1~0.2,但是有的却是10000~ 20000,这种变量间的绝大差距会影像某些模型的稳定性,所以需要想办法把它们变成差不多的范围(有个专有名词:无量纲化)。归一化和标准化可以解决这样的问题。

2.2.1 归一化

归一化目的是消除不同特征间的量纲影响,sklearn.preprocessing中提供了常用的三种归一化方法:MaxAbsScaler(将数据规约到[-1,1],也称小数定标规范化),MinMaxScaler(将数据规约到[0,1] 也称最小最大规范化),StandardScaler(标准差归一化,也称零-均值规范化)。

这里选用最大最小归一化——MinMaxScaler。

2.2.2 标准化

标准化是将数据减去均值后除以数据的标准差,使得变换后的数据特征具有零均值和单位标准差。

3. 基于Savitzky-Golay的正弦数据去噪

本研究使用MATLAB语言编写程序代码,使用sgolay函数设计Savitzky-Golay FIR 平滑滤波器。

3.1 模型构建

3.1.1 数据生成

采用自己生成的随机噪声,给正弦函数添加一个加值噪声。正弦曲线的时间步长为0.25秒,总时长100秒,生成一个500×1的数据集。

3.1.2 结果分析

设置sgolay的函数参数为:多项式阶数为4阶,窗口长度为11;计算后的结果如下。

(1) 原始噪声曲线及对应的去噪曲线

(2) 归一化的噪声曲线及对应的去噪曲线

(3) 标准化的噪声曲线及对应的去噪曲线

可见,三种类型的数据使用SG方法去噪平滑的效果均还不错。

参考文献

[1] 几种常用信号平滑去噪的方法(附Matlab代码)_信号去噪_hyhhyh21的博客-CSDN博客. Blog. 几种常用信号平滑去噪的方法(附Matlab代码)_wdenoise-CSDN博客.

[2] Savitzky-Golay 滤波器详解及C/matlab语言程序设计_沈子恒的博客-CSDN博客. Blog. Savitzky-Golay 滤波器详解及C/matlab语言程序设计-CSDN博客.

[3] Savitzky-Golay filter design - MATLAB sgolay - MathWorks 中国. Ww2. Savitzky-Golay filter design - MATLAB sgolay- MathWorks 中国.

附录

本研究的代码如下:

%% 数据的滤波去噪
clc
clear
close all
%% 噪声信号
dt = 1/5;     % 时间步长
t = (0:dt:100-dt)';    % 总时间
x = 5*sin(2*pi*0.2*t) + randn(size(t));  % 生成带随机噪声的正弦信号
%% 信号归一化  MinMax
x1=(x-min(x))/(max(x)-min(x));

%% 信号标准化
mu=mean(x);
sigma=std(x);
x2=(x-mu)/sigma;

%% 设计Savitzky Golay FIR平滑滤波器
order = 4;    % 多项式阶数
framelen = 11;   % 窗口长度
b = sgolay(order,framelen);

%% 计算输出的稳态部分,利用卷积函数,b的中间行
ycenter = conv(x,b((framelen+1)/2,:),'valid');
ycenter1 = conv(x1,b((framelen+1)/2,:),'valid');
ycenter2 = conv(x2,b((framelen+1)/2,:),'valid');
% ycenter2=conv(x,b((framelen+1)/2,:),'same');

%% 计算过渡过程
ybegin = b(end:-1:(framelen+3)/2,:) * x(framelen:-1:1);  
yend = b((framelen-1)/2:-1:1,:) * x(end:-1:end-(framelen-1));

ybegin1 = b(end:-1:(framelen+3)/2,:) * x1(framelen:-1:1);  
yend1 = b((framelen-1)/2:-1:1,:) * x1(end:-1:end-(framelen-1));

ybegin2 = b(end:-1:(framelen+3)/2,:) * x2(framelen:-1:1);  
yend2 = b((framelen-1)/2:-1:1,:) * x2(end:-1:end-(framelen-1));

%% 连接稳态过程+过渡过程→输出平滑后曲线
y = [ybegin; ycenter; yend];
y1 = [ybegin1; ycenter1; yend1];
y2= [ybegin2; ycenter2; yend2];
figure(1)
plot([x y]);
xlabel('时序');
ylabel('值');
legend('带噪声的正弦曲线','S-G 平滑后的正弦曲线')

figure(2)
plot([x x1 y1]);
xlabel('时序');
ylabel('值');
legend('原始带噪声的正弦曲线','归一化后带噪声的正弦曲线','S-G 平滑后的归一化正弦曲线')

figure(3)
plot([x x2 y2]);
xlabel('时序');
ylabel('值');
legend('原始带噪声的正弦曲线','标准化后带噪声的正弦曲线','S-G 平滑后的标准化正弦曲线')


  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于MATLAB的Savitzky-Golay(S-G)滤波器类的示例代码: ```matlab classdef SGFilter % SGFilter - Savitzky-Golay filter class % % obj = SGFilter(N, W) creates a Savitzky-Golay filter object with a % window size of N and a polynomial degree of W. % % y_filtered = obj.filter(y) applies the filter to the input signal y. % % Example: % x = linspace(0, 2*pi, 100); % y = sin(x) + randn(size(x))*0.1; % sgf = SGFilter(15, 3); % y_filtered = sgf.filter(y); % plot(x, y, 'b', x, y_filtered, 'r'); % % Reference: % [1] Savitzky, A. and Golay, M.J.E. (1964) Smoothing and Differentiation % of Data by Simplified Least Squares Procedures. Analytical Chemistry, % 36, 1627-1639. % % Written by Zoltan Kato <zoltan.d.kato@gmail.com> properties window_size % window size poly_degree % polynomial degree coefficients % filter coefficients end methods function obj = SGFilter(window_size, poly_degree) obj.window_size = window_size; obj.poly_degree = poly_degree; obj.coefficients = sgolay(obj.window_size, obj.poly_degree); end function y_filtered = filter(obj, y) y_filtered = conv(y, obj.coefficients(:, end), 'same'); end end end ``` 在这个示例代码中,我们定义了一个名为 `SGFilter` 的类,它有三个属性:`window_size`、`poly_degree` 和 `coefficients`。`window_size` 和 `poly_degree` 分别是窗口大小和多项式阶数,而 `coefficients` 则是 SG 滤波器的系数矩阵。我们通过调用 `sgolay` 函数来计算这个系数矩阵。 在类的构造函数中,我们传入窗口大小 `N` 和多项式阶数 `W`,并通过 `sgolay` 函数计算出 SG 滤波器的系数矩阵。 在类中还定义了一个名为 `filter` 的方法,它接受一个输入信号 `y` 并将其应用到 SG 滤波器。该方法使用 `conv` 函数将输入信号 `y` 和系数矩阵的最后一列进行卷积,以获得 SG 滤波器的输出信号 `y_filtered`。注意,我们使用了 `same` 选项来保持输出信号的长度与输入信号的长度相同。 最后,我们可以使用以下代码来创建一个 SG 滤波器对象,并将其应用于一个示例信号: ```matlab x = linspace(0, 2*pi, 100); y = sin(x) + randn(size(x))*0.1; sgf = SGFilter(15, 3); y_filtered = sgf.filter(y); plot(x, y, 'b', x, y_filtered, 'r'); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值