介绍
在数据分析领域,尤其是在处理噪声信号时,平滑技术在提取有效信息方面起着至关重要的作用。无论您处理的是实验数据、金融时间序列还是任何形式的信号处理,噪声都会模糊您想要研究/发现的潜在模式和趋势。虽然有多种方法可以解决这个问题(有些方法比其他方法更简单快捷),但根据我的个人经验,在处理短时信号和运行时间有限的情况下,为了保证数据质量,噪声问题可能会被忽略;而有一种技术因其能够在平滑数据的同时保留其重要特征而脱颖而出——那就是Savitzky-Golay 滤波器。

Savitzky-Golay滤波器由Abraham Savitzky和Marcel JE Golay于1964年开发,是一种广泛用于数据平滑和微分的数字滤波器。与其他许多平滑方法(例如中值滤波器或均值滤波器)不同,后者会模糊信号的尖锐特征,从而导致信号失真,而Savitzky-Golay滤波器则能很好地保持原始信号的完整性。这使得它在那些需要保持信号形状和特征的应用场景中尤为有用。

本文将带您全面了解 Savitzky-Golay 滤波器。我们将探索其底层逻辑,深入研究其数学公式,并尝试对每个步骤建立直觉。此外,我们还将使用 Python 可视化该滤波器的应用,从而提供实践经验。希望读完本文后,您能够牢牢掌握 Savitzky-Golay 滤波器的工作原理,并能在数据分析工作中有效地应用它!

什么是萨维茨基-戈莱滤波器?
Savitzky-Golay滤波器是一种数字滤波器,它通过线性最小二乘法(本文稍后会详细解释)将相邻数据点的连续子集拟合成低阶多项式,从而平滑数据点。它的主要优势在于能够在平滑数据的同时保留原始信号的特征,例如峰值和谷值,而这些特征在其他平滑技术中可能会丢失(参见其他技术1、2、3、4)。

定义和基本概念
Savitzky-Golay滤波器的工作原理是:在数据上滑动一个固定大小的窗口(窗口大小是其超参数之一),并对窗口内的每个点拟合一个多项式(多项式的次数也是一个超参数)。窗口中心点处的多项式值即为平滑值。对数据集中的每个点重复此过程,最终得到平滑后的信号。

让我们试着把这个过程分解成一个个小部分,分别了解每个部分。

基于最小二乘法的多项式拟合
核心思想是用一定次数的多项式来逼近滑动窗口内的数据点。假设我们有一组数据点 ( xi , yi ),其中i 的取值范围为1到N。我们的目标是用p次多项式拟合这些数据点。

p次多项式
对于以x_k为中心的给定数据点窗口,我们需要确定系数a0 , a1 , … , ap ​,使得多项式能够最好地拟合窗口内的数据点。这可以通过最小化实际数据点y_i​ 与多项式值y_ih​ 之间差异的平方和来实现:

最小化实际数据点y_i与多项式值y_ih之间差异的平方和。这里,2m+1是以点x_k为中心的窗口大小。
多项式拟合示例
让我们确保理解上述概念,因为它对接下来的步骤至关重要!
考虑一个简单的例子,窗口大小为 5(即m=2),多项式为2 次 §。假设窗口内有以下数据点:

Press enter or click to view image in full size

以x_k为中心的窗口内的 5 个数据点
我们用以下多项式拟合这些点:

二次多项式
我们通过最小化误差平方和来求解a0、a1、a2 :

最小化使用当前 a0、a1、a2 的多项式与实际观测值 y_k 之间的平方误差
确定系数后(例如,如果从头开始实现,则使用 scipy optimize),x_k处的平滑值由在x_k处计算的多项式给出:

其中yhat_k是x_k处的平滑值
步骤详解示例:
让我们通过一个详细的例子来了解 Savitzky-Golay 滤波器是如何工作的!

生成噪声信号

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.signal import savgol_filter 

np.random.seed( 0 ) 
x = np.linspace( 0 , 2 * np.pi, 100 ) 
y = np.sin(x) + np.random.normal( 0 , 0.1 , x.size) 

plt.plot(x, y, label= '噪声信号' ) 
plt.grid(lw= 2 ,ls= ':' ) 
plt.xlabel( '时间步长' ) 
plt.ylabel( "值" ) 
plt.legend() 
plt.show()

含噪声示例信号
应用萨维茨基-戈莱滤波器
我们选择窗口大小为 11,多项式次数为 3。

window_size = 11
 poly_order = 3
 y_smooth = savgol_filter(y, window_size, poly_order) 

plt.plot(x, y, label= '噪声信号' ) 
plt.plot(x, y_smooth, label= '平滑信号' , color= 'red' ) 
plt.grid(lw= 2 , ls= ':' ) 
plt.xlabel( '时间步长' ) 
plt.ylabel( "值" ) 
plt.legend() 
plt.show()

按回车键或点击查看完整尺寸的图片

应用萨夫戈尔滤波器后得到的信号
按回车键或点击查看完整尺寸的图片

逐步可视化过滤器运行过程
平滑后的信号保留了原始正弦波形,同时降低了噪声。

探索不同的窗口大小和多项式次数
fig, axs = plt.subplots( 2 , 2 , figsize=( 20 , 12 ))

小窗口大小,低多项式阶数

y_smooth_1 = savgol_filter(y_complex, 5 , 2 ) 
axs[ 0 , 0 ].plot(x, y_complex, label= '噪声信号' ) 
axs[ 0 , 0 ].plot(x, y_smooth_1, label= '平滑信号 (5, 2)' , color= 'red' ) 
axs[ 0 , 0 ].legend() 
axs[ 0 , 0 ].set_title( '窗口大小:5,多项式阶数:2' ) 
plt.xlabel( '时间步长' ) 
plt.ylabel( "值" ) 
plt.legend() 

小窗口大小,高y_smooth_2 = savgol_filter

 (y_complex, 5 , 4 ) 
axs[ 0 , 1 ].plot(x, y_complex, label= '噪声信号' ) 
axs[ 0 , 1 ].plot(x, y_smooth_2, label= '平滑信号 (5, 4)' , color= 'red' ) 
axs[ 0 , 1 ].legend() 
axs[ 0 , 1 ].set_title( '窗口大小:5,多项式阶数:4' ) 

大窗口大小,低多项式阶数

y_smooth_3 = savgol_filter(y_complex, 21 , 2 ) 
axs[ 1 , 0 ].plot(x, y_complex, label= '噪声信号' ) 
axs[ 1 , 0 ].plot(x, y_smooth_3, label= '平滑信号 (21, 2)' , color= 'red' ) 
axs[ 1 , 0 ].legend() 
axs[ 1 , 0 ].set_title( '窗口大小:21,多项式阶数:2' ) 

大窗口大小,高多项式阶数

y_smooth_4 = savgol_filter(y_complex, 21 , 4 ) 
axs[ 1 , 1 ].plot(x, y_complex, label= '噪声信号' ) 
axs[ 1 , 1 ].plot(x, y_smooth_4, label= '平滑信号 (21, 4)' ,color= 'red' ) 
axs[axs [1 , 1 ].legend() 
axs[ 1 , 1 ].set_title( '窗口大小:21,多边形度:4' ) 

plt.tight_layout() 
plt.show()

观察
小窗口尺寸,低多项式阶数:滤波器可以平滑数据,但可能无法很好地捕捉整体趋势,特别是对于具有较高频率成分的信号。
小窗口尺寸,高多项式阶数:滤波器可以捕捉更复杂的趋势,但可能会过度拟合噪声,导致平滑效果不佳。
大窗口尺寸,低多项式阶数:该滤波器提供稳定的平滑效果,但可能会抹去信号的重要特征。
大窗口尺寸,高多项式阶数:该滤波器能够捕捉复杂的趋势,同时提供有效的平滑效果,但如果窗口尺寸相对于信号的频率分量过大,则可能会引入伪影。
实际考虑因素
在使用Savitzky-Golay滤波器时,选择合适的窗口大小和多项式阶数对于实现有效的平滑而不失真信号至关重要。本文将概述如何选择这些参数、其中涉及的权衡取舍,以及该滤波器的一些局限性和潜在缺陷。

选择窗口大小和多项式次数
窗户尺寸(2米+1):
小窗口尺寸:较小的窗口尺寸可以捕捉更多局部细节,但可能无法有效平滑噪声。它适用于包含高频成分或快速变化的信号。
大窗口尺寸:较大的窗口尺寸可以提供更稳定的平滑效果,但可能会抹去一些重要特征,尤其是在信号快速变化的情况下。它适用于低频成分较多或变化缓慢的信号。
2. 多项式次数 §:

低阶多项式:低阶多项式(例如,p=2 或 p=3)提供了一个更简单的模型,可以捕捉到总体趋势,但可能无法很好地拟合复杂的模式。
高阶多项式:高阶多项式(例如 p=4 或 p=5)可以捕捉更复杂的趋势,但可能会过度拟合噪声,尤其是在窗口尺寸较小时。
一些权衡取舍和“经验法则”
平衡平滑和特征保留:目标是在平滑噪声的同时保留信号的重要特征。这需要在窗口大小和多项式阶数之间取得平衡。尝试不同的值,找到适合您特定数据的最佳参数。
避免过拟合:使用高阶多项式和较小的窗口尺寸会导致过拟合,此时多项式捕捉到的是噪声而非潜在趋势。这会导致信号虽然平滑,但仍然包含噪声。
信号特性:选择参数时,请考虑信号的特性。例如,变化迅速的信号需要较小的窗口尺寸和可能较高的多项式阶数,而变化缓慢的信号则可以受益于较大的窗口尺寸和较低的多项式阶数。
局限性和潜在陷阱
“边缘效应”:由于可用于拟合多项式的点较少,Savitzky-Golay滤波器难以平滑信号边缘附近的数据点。这会导致边界处的平滑精度降低。
数据均匀分布假设:该滤波器假设数据点均匀分布(这一点至关重要)。如果您的数据分布不均匀,您可能需要对其进行预处理以确保均匀分布,或者使用可以处理不均匀分布的其他方法。
参数选择:滤波器的有效性很大程度上取决于所选的窗口大小和多项式阶数。选择不当会导致平滑效果不佳,要么噪声降低不足,要么信号失真。
计算复杂度:对于非常大的数据集,每个窗口的多项式拟合过程可能计算量巨大。处理大规模数据可能需要高效的实现和优化技术。
实用技巧
从默认值开始:一个好的起点是使用窗口大小为 11 和多项式次数为 3。这些值通常在平滑和特征保留之间提供良好的平衡。
目视检查:应用滤波器后,对平滑后的信号进行目视检查,以确保其有效降低噪声的同时保留重要特征。
参数调优:尝试不同的窗口大小和多项式阶数,找到适用于特定数据的最佳参数。使用交叉验证或其他技术客观地评估不同参数选择的性能。
边缘处理:考虑在边缘处使用填充或扩展数据来减轻边缘效应。或者,使用不同的边缘平滑技术。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐