数据转换操作
在这个实验室里,我们将考虑2种类型的变换:傅里叶变换和小波变换,应用于数据平滑。
这些变换的主要应用是信号处理、图像处理。在图像处理的实验室工作中,我们还将看到卷积(来自前面的实验室工作)和小波变换是如何使用的。
1.傅里叶变换
大家都熟悉傅立叶行连续周期函数的分解。对于不熟悉参考维基百科的人来说,最简单的例子就是三角函数傅里叶数列中函数分解系数的计算。可以通过一组正交多项式和其他正交函数的系统(例如,Haar、Walsh和Kotelnikov的函数)将一个函数分解成一个系列。
与傅里叶数列相比,傅里叶变换不是按离散频率(傅里叶数列的一组频率,一般来说,按其分解是离散的),而是按连续频率分解函数。
傅立叶变换是一种积分变换,它描述了将被调查函数分解为基本分量--不同频率的谐波振荡的系数(振幅)。
在信号处理及相关领域,通常认为傅里叶变换是将信号分解为频率和振幅,即从时域到频域的可逆转换。
傅立叶变换的图解
傅里叶变换的结果其实叫频谱。
傅里叶变换的一些有用特性。
- 傅立叶变换是可逆的,而逆向变换的形状几乎与直接变换相同。
- 正弦基函数(或者说是复展函数)是自己的微分函数,也就是说,这种表示方法将系数不变的线性微分方程转化为普通代数方程。
- 在卷积定理中,傅立叶变换将复杂的卷积运算转化为简单的乘法,这意味着它们为计算多项式的乘法和大数的乘法等基于卷积的运算提供了一种有效的方法。
- 离散版的傅里叶变换可以使用快速傅里叶变换算法(FFT)在计算机上快速计算。
通过傅里叶变换,模拟信号可以有效地转换为数字信号进行计算处理。
例如:
获得周期性信号的 "平滑 "版本。即使信号不是完全周期性的,转换也会去除大部分白噪声。
你需要对信号进行傅里叶变换,并从中减去低频成分。
傅立叶变换适用于复数。scipy软件包提供了一个离散傅里叶变换的实数序列变体。
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import scipy.fftpack
#生成带有噪音的合成数据
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + np.random.random(100) * 0.2
plt.plot(y)
plt.show();
rfft---材料序列的离散傅里叶变换。
w = scipy.fftpack.rfft(y)
rfftfreq方法返回实变离散傅里叶变换的采样率。窗口长度和采样间隔必须作为参数传递。
f = scipy.fftpack.rfftfreq(len(x), x[1]-x[0])
频谱
plt.plot(w)
plt.show();
功率
power = w ** 2
plt.plot(power)
plt.show();
让我们来设置截止阈值。
cutoff_idx = power < (power.max() / 5)
w2 = w.copy()
w2[cutoff_idx] = 0
利用反离散傅里叶变换irfft回到原始空间。
y2 = scipy.fftpack.irfft(w2)
figure = plt.figure(figsize=(10,5))
plt.subplot(1, 2, 1)
plt.plot(y, label='noisy data')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(y2, label='smoothed data')
plt.legend()
plt.show();
如上所述,我们可以使用傅里叶变换将信号从时域转换到频域。频谱中的峰值表示信号中最常出现的频率。峰值越大、越尖锐,信号中的主导频率越高。那么频谱中峰的位置(频率值)和高度(振幅)就可以作为随机森林或梯度提升等分类器的输入数据。
2.小波变换
小波变换是一种积分变换,它是小波函数与信号的卷积。小波变换将信号从临时表示转换为频率-时间表示。
小波这个词的意思是小波,这正是小波的意思。
它代表离散、连续和多级小波变换。这些类型的变换在一组参数上有所不同:尺度(小波的压缩/拉伸,对应于频率的增加/减少)和移位(小波沿时间轴的移位,以便与所研究的数字保持一致)对于离散变换--离散,对于连续--连续。
一些真实的离散基础的例子。
HAAR
FHAT("французская шляпа", French hat)
一些真实的、连续的基础的例子。
高斯:一阶,即WAVE小波;二阶,即MHAT小波("墨西哥帽",墨西哥帽子);n-th阶。
高斯数之差
LP(Littlewood&Paley)
一些复式碱基的例子。
- Morle
- Paul
一组 "互补 "的小波会对数据进行分解,没有空格和重叠,所以分解过程在数学上是可逆的。
Scalograms、scaleograms用于可视化连续小波变换,用于一维数据分析。
举个例子,考虑一个基于多级分解的离散小波变换。
用于处理小波的Python库pywt
import pywt
wavedec--多级分解参考文献
pywt.wavedec(data, wavelet, mode='symmetric', level=None, axis=-1)
要使用wavedec,需要指定小波的类型、模式信号的外推方式和分解级别。
wavelet
pywt.wavelist()
以下为部分内容截图
mode
由于表示数字信号的最常见、最实用的方法是使用有限的数值数组,因此在使用级联滤波库算法计算离散小波变换之前,必须对输入数据进行一些外推,以扩展信号。
pywt库提供了几种信号外推的方法,例如
零(零填充)--通过添加零样本来扩展信号。
对称填充--通过镜像样本来扩展信号。
周期性(周期性填充)--信号被认为是周期性的。更多内容
pywt.Modes.modes
level
分解等级必须>=0。如果级别为None(默认情况下),将使用函数dwt_max_level计算。
# wavelet type
wavelet_type = 'sym6'
w = pywt.Wavelet(wavelet_type)
# phi, psi, x = w.wavefun(level=6)
plt.plot(w.dec_lo)
plt.show();
level = pywt.dwt_max_level(len(y), w)
coeffs = pywt.wavedec(data=y, wavelet=w, mode='periodization', level=level)
让我们来设置一下滤波器电平的阈值。
为了直接过滤系数,我们将使用函数pywt.threshold。要使用它,我们需要定义过滤模式:软、硬、大、小。soft
, hard
, greater
, less
.
threshold = 0.1
filtered_coeffs = []
plt.figure(figsize=(10, 20))
for i in range(0, len(coeffs)):
plt.subplot(len(coeffs), 1, i+1)
plt.plot(coeffs[i], label='coeffs_' + str(i+1))
filtered_coeffs.append(pywt.threshold(coeffs[i], threshold * max(coeffs[i]), mode='soft'))
plt.plot(filtered_coeffs[-1], label='filtered_coeffs_' + str(i+1))
plt.legend()
plt.show();
用滤波系数还原信号。
datarec = pywt.waverec([filtered_coeffs[0]], w)
让我们来显示结果
figure = plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(y, label='data')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(datarec, label='data reconstructed')
plt.legend()
plt.show();
小波的实际应用小视频链接
【小结】
因此,傅里叶变换利用一系列不同频率的正弦波进行信号分析。也就是说,信号是由正弦波的线性组合来表示的,而不是在时域中局部的。
小波变换使用了许多称为小波的函数,每个函数都有自己的尺度。
小波变换的应用,由于小波在时域和频域都是局部的,可以发现数据的急剧变化。如果一个未知信号中含有类似频率的信息,小波将与信号进行数学关联。这种相关性的概念是小波理论许多实际应用的核心。