在寻找曲线的波峰、波谷时,由于数据帧数多的原因,导致生成的曲线图噪声很大,不易寻找规律。如下图:
由于高频某些点的波动导致高频曲线非常难看,为了降低噪声干扰,需要对曲线做平滑处理,让曲线过渡更平滑。常见的对曲线进行平滑处理的方法包括: Savitzky-Golay 滤波器、插值法等。
对曲线进行平滑处理,通过Savitzky-Golay 滤波器,可以在scipy库里直接调用,不需要再定义函数。
python中Savitzky-Golay滤波器调用如下:
y_smooth = scipy.signal.savgol_filter(y,53,3)
# 亦或
y_smooth2 = savgol_filter(y, 99, 1, mode= 'nearest')
# 备注:
y:代表曲线点坐标(x,y)中的y值数组
window_length:窗口长度,该值需为正奇整数。例如:此处取值53
k值:polyorder为对窗口内的数据点进行k阶多项式拟合,k的值需要小于window_length。例如:此处取值3
mode:确定了要应用滤波器的填充信号的扩展类型。(This determines the type of extension to use for the padded signal to which the filter is applied. )
调参规律:
现在看一下window_length和k这两个值对曲线的影响。
1)window_length对曲线的平滑作用:
( window_length的值越小,曲线越贴近真实曲线;window_length值越大,平滑效果越厉害(备注:该值必须为正奇整数)。
1)2)k值对曲线的平滑作用:
( k值越大,曲线越贴近真实曲线;k值越小,曲线平滑越厉害。另外,当k值较大时,受窗口长度限制,拟合会出现问题,高频曲线会变成直线。
# 用于生成问题描述中示例曲线的代码如下:
import numpy as np
from matplotlib import pyplot as plt
Size = 100
x = np.linspace(1, Size,Size)
#生成随机矩阵
data = np.random.randint(1, Size, Size)
print(data)
# 可视化图线
plt.plot(x, data,'r')
# 使用Savitzky-Golay 滤波器后得到平滑图线
from scipy.signal import savgol_filter
y = savgol_filter(data, 15, 2, mode= 'nearest')
# 可视化图线
plt.plot(x, y, 'b', label = 'savgol')
#显示曲线
plt.show()
#生成的随机矩阵
>>>
[61 36 90 88 89 29 36 39 92 62 89 10 8 66 37 92 14 45 97 35 94 1 10 15
14 65 55 55 10 8 57 39 28 62 20 19 30 75 82 71 54 24 40 48 64 65 22 97
61 13 14 69 35 58 61 2 42 93 43 62 75 39 63 75 82 53 32 86 17 95 89 25
73 47 22 57 85 27 49 47 63 54 61 6 99 84 78 41 88 2 41 63 32 43 81 70
75 86 13 57]
Savitzky-Golay 平滑曲线 效果
在scipy官方帮助文档里可以看到关于Savitzky-Golay 滤波器中关于 savgol_filter()函数 的详细说明。
以下是关于 Savitzky-Golay平滑滤波 的简单介绍(参考Python 生成曲线进行快速平滑处理):
Savitzky-Golay平滑滤波是光谱预处理中的常用滤波方法,其 核心思想:是对一定长度窗口内的数据点进行k阶多项式拟合,从而得到拟合后的结果。 对它进行离散化处理后,S-G 滤波其实是一种移动窗口的加权平均算法,但是其加权系数不是简单的常数窗口,而是通过在滑动窗口内对给定高阶多项式的最小二乘拟合得出。
Savitzky-Golay平滑滤波被广泛地运用于数据流平滑除噪,是一种在时域内基于局域多项式最小二乘法拟合的滤波方法。这种滤波器的 最大特点:在滤除噪声的同时可以确保信号的形状、宽度不变。
使用平滑滤波器对信号滤波时,实际上是拟合了信号中的低频成分,而将高频成分平滑出去了。 如果噪声在高频端,那么滤波的结果就是去除了噪声,反之,若噪声在低频段,那么滤波的结果就是留下了噪声。
总之,平滑滤波是光谱分析中常用的预处理方法之一。用Savitzky-Golay方法进行平滑滤波,可以提高光谱的平滑性,并降低噪音的干扰。S-G平滑滤波的效果,随着选取窗宽不同而不同,可以满足多种不同场合的需求。
参考链接:Savitzky-Golay平滑滤波的python实现
插值法对折线平滑处理——详解
基于Numpy.convolve实现滑动平均滤波——详解
曲线平滑处理——Savitzky-Golay 滤波器——详解