当前位置: 首页 > news >正文

时序顶会基础创新知识点-小波变换篇上

前面的文章我们总结了傅立叶变换在时间序列中的应用,但FFT实际有其局限性,所以最近陆续在学习小波变换,感觉小波变换要比傅立叶变换更加复杂,所以预计本篇文章会冗长一些。此外,文章不少代码参考了网络博客,因为博客质量良莠不齐,且不少内容是互相转载,从繁多内容中找到有价值的部分,我花了不少时间。我希望能讲清楚小波变换,此外尽量把参考源写清楚。

1. 小波变换与傅立叶变换的差异比较

之前我们一起学习总结过傅立叶变换在时序问题中的应用,那么有了小波变换和傅里叶变换和傅立叶变换有什么区别呢?或者说,为什么有了傅立叶变换还不够,还要有小波变换呢?这是文本要解释的第一个问题。

1.1 傅里叶变换

首先回顾一下傅立叶变换,傅里叶变换是一种频域分析方法,它基于傅里叶级数的思想,将信号表示为一系列不同频率的正弦和余弦函数的线性组合傅里叶变换将信号从时域转换到频域(时域信息完全丢失),得到信号的频谱,频谱反映了信号中不同频率成分的幅度和相位信息。但是有时候,我们希望知道时间序列在不同时刻的频域信息,这时候傅立叶变换就行不通了。此外,如果是下面的情况,频率成分相同,但是时间位置不同,傅立叶变换也是识别不出来了的。这就是FFT的不足。

看下图,三条时间序由三个不同频率的三角函数拼接而成,且很明显它们的先后顺序存在差异。

图片

注:图片来源于网络

但是如果我们做傅立叶变换,会得到如下结果。我们发现明明是三条不同的序列,却得到了同样的频率分析图。这就是傅立叶变换的不足之处,失去了时间维度信息。那么有没有一种可能,能够同时得到时间和频率两个维度的特征分析结果呢,是可以的,这就是小波变换。

图片

1.2 小波变换

而我们今天学习的小波变换也是一种时频分析方法,它通过一组小波基函数对信号进行分解。得到不同尺度和位置的近似系数和细节系数,这些系数反映了信号在不同时间和频率上的局部特征。所以小波变换的结果实际上反映了两个维度:时间和频率,小波变换更适合处理非平稳信号,通过不同尺度的小波函数来捕捉信号在不同时间和频率上的变化,也能够有效地提取信号中的突变、瞬态和局部特征。

图片

对比一下小波变换和傅立叶变换的特性差异,我们可以发现:

图片

注:图片来源于网络

  • 小波变换:具有良好的时频局部性,能够同时在时间和频率上对信号进行局部分析。支持多分辨率分析,通过多级分解可以在不同尺度下观察信号的特征。不同尺度的小波基函数可以捕捉信号在不同时间和频率上的变化,因此非常适合处理非平稳信号,例如包含突变、瞬态等特征的信号。

  • 傅里叶变换:缺乏时频局部性,它只能提供信号的整体频率信息,无法确定某个频率成分在时间上的具体位置。对于非平稳信号,傅里叶变换的结果可能无法准确反映信号的时变特性。不具备多分辨率分析的能力,它只能提供单一分辨率的频域信息。

2. 小波变换的Python实现

我在查博客的时候,看到有些代码用pywt.dwt,有些用pywt.wavedec,还有一些用pywt.cwt,专门查了一下,三者的区别具体如下:

  • pywt.dwt:执行一级离散小波变换(Discrete Wavelet Transform)。它将输入信号分解为两个部分,即近似系数(Approximation coefficients,低频部分,反映信号的总体趋势)和细节系数(Detail coefficients,高频部分,反映信号的局部变化)。

  • pywt.wavedec:执行多级离散小波变换。它会对信号进行多次分解,每一级都将上一级得到的近似系数进一步分解为新的近似系数和细节系数,最终得到不同尺度下的近似系数和各级细节系数。

  • pywt.cwt:执行连续小波变换。输入包括信号signal、尺度scale、小波基等。输出 coefficients 是一个二维复数矩阵,其行对应不同尺度(scales),列对应时间点,幅度 np.abs(coefficients) 反映信号在各尺度和时间点的能量强度,相位 np.angle(coefficients)提供局部相位信息;frequencies 表示各尺度对应的实际频率(Hz),尺度越小频率越高。

2.1 使用pywt.dwt进行一级分解
 

# 生成信号变量t = np.linspace(0, 1, num=1000)signal = np.sin(2 * np.pi * 10 * t) + np.sin(2 * np.pi * 20 * t) + np.sin(3 * np.pi * 30 * t)# 添加随机噪声noise = np.random.normal(0, 0.05, len(signal))signal = signal + noise# 进行DWTcoeffs = pywt.dwt(signal, 'db1')cA, cD = coeffs

解释一下几行核心代码,其中'db1' 是小波基的名称,db1 也就是哈尔(Haar)小波,它是最简单且最早被提出的小波基,具有正交性和紧支撑性。pywt.dwt函数会返回一个包含两个元素的元组,这两个元素分别是近似系数(Approximation coefficients)和细节系数(Detail coefficients),并将其赋值给变量 coeffs。

近似系数:代表信号的低频部分,体现了信号的总体趋势和缓慢变化的特征。可以把它看作是对原始信号进行平滑处理后的结果,保留了信号的主要信息。例如在图像中,低频部分对应着图像的整体亮度和大致轮廓;在音频信号里,低频部分对应着声音的基频和主要音调。

细节系数:代表信号的高频部分,反映了信号的局部变化、细节特征以及噪声等信息。它体现了信号在不同尺度下的快速变化情况。在图像中,高频部分对应着图像的边缘、纹理等细节信息;在音频信号中,高频部分对应着声音的音色、谐波等细节。

cA, cD = coeffs 这行代码将 coeffs 元组中的两个元素分别赋值给变量 cA 和 cD。cA 是近似系数,cD 代表细节系数。下面是绘制出的分解结果:

# 绘制原始信号及其DWT系数plt.figure(figsize=(12, 6))plt.subplot(3, 1, 1)plt.plot(t, signal, label='Original Signal')plt.legend()plt.subplot(3, 1, 2)plt.plot(cA, label='Approximation Coefficients')plt.legend()plt.subplot(3, 1, 3)plt.plot(cD, label='Detail Coefficients')plt.legend()plt.tight_layout()plt.show()​​​​​​​

图片

2.2 使用pywt.wave进行多级分解

# https://www.oryoy.com/news/shi-yong-pywavelets-ku-zai-python-zhong-jin-xing-gao-xiao-de-xiao-bo-bian-huan-yu-xin-hao-chu-li-shi.htmlimport numpy as npimport pywtimport matplotlib.pyplot as plt# 生成信号变量t = np.linspace(0, 1, num=1000)signal = np.sin(2 * np.pi * 10 * t) + np.sin(2 * np.pi * 20 * t) + np.sin(3 * np.pi * 30 * t)# 添加随机噪声noise = np.random.normal(0, 0.05, len(signal))signal = signal + noisewavelet_name = 'db4'  # 定义小波基名称为'db4'# 小波变换coeffs = pywt.wavedec(signal, wavelet_name, level=4)  # 使用指定小波基进行4级小波分解这里我们用了'db4' ,代表的是四阶 Daubechies 小波基,也是一类常用的小波基,具有紧支撑性和正交性等特性。

代码coeffs = pywt.wavedec(signal, wavelet_name, level=4)实现了多级离散小波变换,signal 是输入的一维信号,wavelet_name 是指定的小波基名称,这里使用的是 'db4'。

level=4 指定了小波变换的分解级数为 4。多级离散小波变换会对信号进行多次分解,每一级都将上一级得到的近似系数进一步分解为新的近似系数和细节系数。本代码进行了四级分解,返回一个列表 coeffs,列表的第一个元素是最高级别的近似系数(经过四级分解后得到的最粗略的近似),其余元素依次是从第一级到第四级的细节系数。​​​​​​​

# 绘制原始信号图像plt.figure(figsize=(8, 6))plt.subplot(5, 1, 1)plt.plot(t, signal)plt.title('Original Signal')plt.xlabel('Time')plt.ylabel('Amplitude')# 绘制小波分解信号图像for i in range(1, len(coeffs)):    plt.subplot(5, 1, i+1)    plt.plot(t[:len(coeffs[i])], coeffs[i])    plt.title(f'Wavelet Coefficients - Level {i}')    plt.xlabel('Time')    plt.ylabel('Amplitude')plt.tight_layout()plt.show()

图片

这里大家也可以尝试使用pywt.wave进行一级分解,比较两者的结果是否相同。

2.3 使用pywt.cwt进行连续小波变换

import numpy as npimport matplotlib.pyplot as pltimport pywtfrom pywt import scale2frequency# 生成合成信号fs = 1000  # 采样频率 (Hz)t = np.linspace(0, 1, fs, endpoint=False)  # 时间轴 (1秒)f1, f2 = 10, 50  # 两个频率成分signal = np.sin(2 * np.pi * f1 * t) + np.sin(2 * np.pi * f2 * t)  # 合成信号# 添加高斯噪声noise = 0.5 * np.random.randn(len(t))signal_noisy = signal + noise# 定义CWT参数wavelet = 'morl'  # Morlet小波scales = np.arange(1, 128)  # 尺度范围(与频率成反比)

合成一个包含10Hz和50Hz正弦波的信号,并添加噪声模拟真实数据。选择Morlet小波,根据目标频率调整尺度scales范围,尺度越小对应频率越高。

  • # 计算CWTcoefficients, frequencies = pywt.cwt(signal_noisy, scales, wavelet, sampling_period=1/fs)# 获取实际频率(PyWavelets的scale2frequency需注意单位)frequencies = scale2frequency(wavelet, scales) * fs  # 转换为实际频率(Hz)

进行变换,并使用scale2frequency将尺度转换为实际频率。最后进行可视化,时频图用imshow展示CWT系数的绝对值(能量分布)。等高线图更精确显示频率随时间的变化。

图片

这样,通过本篇文章我们就知道了小波变换与傅立叶变换的区别,小波变换的优势,同时我们还总结小波变换的三个常用代码。但是,时间序列问题中具体如何应用小波变换?小波变换能带来哪些不一样的性能提升,这个我们留到下篇讲解。

http://www.lryc.cn/news/595514.html

相关文章:

  • 设计系统搭建:大型 Pad 应用的协同开发解决方案
  • 优测发布IoT云联解决方案,赋能生态应用创新跨端体验!
  • 一文详解REST风格
  • WSL如何安装docker?
  • 人生的意义
  • 培生生成式人工智能(GAI)认证职场应用白皮书
  • CMakeLists.txt 中一些最常见和核心的命令
  • 三大工厂设计模式
  • Oracle自治事务——从问题到实践的深度解析
  • mcu中的调试接口是什么?
  • 阿里思想学习-如何优化大事务提交
  • JAVA后端开发—— JWT(JSON Web Token)实践
  • c语言----文件操作
  • 上海RISC-V峰会-香山开源RISC-V CPU随想随记
  • 软件测试 —— A / 入门
  • 从0开始学习R语言--Day53--AFT模型
  • react-window 大数据列表和表格数据渲染组件之虚拟滚动
  • Spring关于依赖注入的几种方式和Spring配置文件的标签
  • 面试总结第54天微服务开始
  • Spring处理器和Bean的生命周期
  • 线程池与ThreadPoolExecutor源码解析(上)
  • 暴力破解练习
  • Pandas - JSON格式数据操作实践
  • AV1平滑缓冲区
  • iostat的使用说明
  • MongoDB 查询时区问题
  • GUI简介
  • Kafka 如何优雅实现 Varint 和 ZigZag 编码
  • 【每天一个知识点】非参聚类(Nonparametric Clustering)
  • 期权到期会对大盘有什么影响?