基于小波分析和机器学习的时间序列分析与识别

研究对象:ECG等时间序列信号

方法:小波变换,简单神经网络

首先导入相关模块,需要安装尺度谱模块:pip install scaleogram

和mat4py模块:pip install mat4py

import numpy as np
import pandas as pd
import pywt
import seaborn as sns
import scaleogram as scg 
import matplotlib.pyplot as plt
import matplotlib.gridspec as GridSpec
from mat4py import loadmat
from scipy.fftpack import fft

导入数据,并提取标签

data = loadmat("ECGData.mat")
ecg_total = len(data['ECGData']['Data'])
ecg_data = []
ecg_labels = []
for i in range(0, ecg_total):
    ecg_data.append(data['ECGData']['Data'][i])
    ecg_labels.append(data['ECGData']['Labels'][i])

flat_list_ecg_labels = [item for sublist in ecg_labels for item in sublist]

数据可视化

fig = plt.figure(figsize=(12, 6))
grid = plt.GridSpec(3, 1, hspace=0.6)

arr_signal = fig.add_subplot(grid[0, 0])
chg_signal = fig.add_subplot(grid[1, 0])
nsr_signal = fig.add_subplot(grid[2, 0])

arr_signal.plot(range(0, len(data['ECGData']['Data'][33]), 1), ecg_data[33], color = 'blue')
arr_signal.set_xlim(0, 1000)
arr_signal.set_title('ARR Signal')

chg_signal.plot(range(0, len(data['ECGData']['Data'][100]), 1), ecg_data[100], color = 'red')
chg_signal.set_xlim(0, 1000)
chg_signal.set_title('CHG Signal')

nsr_signal.plot(range(0, len(data['ECGData']['Data'][150]), 1), ecg_data[150], color = 'green')
nsr_signal.set_xlim(0, 1000)
nsr_signal.set_title('NSR Signal')

进行傅里叶变换

nn = 160
signal_length = 1000
full_signal_fft_values = np.abs(fft(ecg_data[nn][:signal_length]))
x_values_fft = range(0, len(data['ECGData']['Data'][nn]), 1)[:signal_length]

fig = plt.figure(figsize=(12, 6))
grid = plt.GridSpec(2, 1,hspace=0.6)

full_signal = fig.add_subplot(grid[0, 0])
fft_comp = fig.add_subplot(grid[1, 0])

full_signal.plot(x_values_fft, ecg_data[nn][:signal_length], color = 'green')
full_signal.set_xlim(0, 512)
full_signal.set_title('Full Signal')
fft_comp.plot(x_values_fft, list(full_signal_fft_values), color = 'purple')
fft_comp.set_xlim(0, 512)
fft_comp.set_ylim(0, 100)
fft_comp.set_title('FFT of full signal')

看下所用的Morlet小波啥个样子

axes = scg.plot_wav('morl', figsize=(12,4))

顺便看下小波族大致包含多少小波类

pywt.families(False)

['Haar',

'Daubechies',

'Symlets',

'Coiflets',

'Biorthogonal',

'Reverse biorthogonal',

'Discrete Meyer (FIR Approximation)',

'Gaussian',

'Mexican hat wavelet',

'Morlet wavelet',

'Complex Gaussian wavelets',

'Shannon wavelets',

'Frequency B-Spline wavelets',

'Complex Morlet wavelets']

顺便再给几个小波的波形及相应的频谱

下面进行小波尺度谱变换

# 选择一个默认的小波
scg.set_default_wavelet('morl')

nn = 33
signal_length = 128
# 小波变换的尺度范围
scales = scg.periods2scales( np.arange(1, signal_length+1) )
x_values_wvt_arr = range(0,len(ecg_data[nn]),1)

# 绘制信号
fig1, ax1 = plt.subplots(1, 1, figsize=(9, 3.5));  
ax1.plot(x_values_wvt_arr, ecg_data[nn], linewidth=3, color='blue')
ax1.set_xlim(0, signal_length)
ax1.set_title("ECG ARR")

# 计算小波时间-尺度谱
scg.cws(ecg_data[nn][:signal_length], scales=scales, figsize=(10, 4.0), coi = False, ylabel="Period", xlabel="Time",
        title='ECG_ARR: scaleogram with linear period'); 

print("Default wavelet function used to compute the transform:", scg.get_default_wavelet(), "(",
      pywt.ContinuousWavelet(scg.get_default_wavelet()).family_name, ")")

下面开始进行机器学习识别,首先准备机器学习所需要的数据

arr_list = ecg_data[0:95]
chf_list = ecg_data[96:125]
nsr_list = ecg_data[126:162]

arr_split_256 = [np.array_split(arr_list[ii], 256) for ii in range(95)]
arr_flatten = [item for sublist in arr_split_256 for item in sublist]

chf_split_256 = [np.array_split(chf_list[ii], 256) for ii in range(29)]
chf_flatten = [item for sublist in chf_split_256 for item in sublist]

nsr_split_256 = [np.array_split(nsr_list[ii], 256) for ii in range(36)]
nsr_flatten = [item for sublist in nsr_split_256 for item in sublist]

reduce_size = 500
full_1500 = (arr_flatten[0:reduce_size] + chf_flatten[0:reduce_size] + nsr_flatten[0:reduce_size])

创建数据集

#机器学习相干模块
from sklearn import preprocessing
from sklearn.model_selection import train_test_split

fs = len(full_1500[0])  
sgn_length = 2000   #信号长度
size_dataset = len(full_1500)
scales = range(1, fs)
waveletname = 'morl'   #小波
 
X_full = np.ndarray(shape=(size_dataset, fs-1, fs-1, 3))
 #开始生成数据                
for i in range(0, size_dataset):
    if i % 500 == 0:
        print (i, 'done!')
    for j in range(0, 3):
        signal = full_1500[i]
        coeff, freq = pywt.cwt(signal, scales, waveletname, 1)
        X_full[i, :, :, j] = coeff[:,:fs-1]
#相应的标签
list_ecg_labels_arr = ['ARR']*reduce_size 
list_ecg_labels_chf = ['CHF']*reduce_size 
list_ecg_labels_nsr = ['NSR']*reduce_size 
list_ecg_labels = (list_ecg_labels_arr + list_ecg_labels_chf + list_ecg_labels_nsr)

le = preprocessing.LabelEncoder()
ecg_labels_encoded = le.fit_transform(list_ecg_labels)
X_train, X_test, y_train, y_test = train_test_split(X_full, ecg_labels_encoded, test_size=0.25, random_state=42)

使用尺度谱训练ECG分类器

import sys
from tensorflow import keras

查看一下训练数据

定义基本的神经网络

num_filter, num_classes = 3, 3
model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[fs-1, fs-1, num_filter]),
    keras.layers.Dense(300, activation="relu"),                 
    keras.layers.Dense(100, activation="relu"),
    keras.layers.Dense(num_classes, activation="softmax")
])
model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd", metrics=["accuracy"])

model.summary()

训练模型

history = model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))

model.evaluate(X_test, y_test)

def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    plt.grid(True)
    plt.gca().set_ylim(0, 1)
    plt.xlabel('epochs', size = 16)
    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)
    plt.savefig('Figure_epochs.png')   
    plt.close()

plot_learning_curves(history)

prediction = model.predict(X_test)
pred_classes = prediction.argmax(axis=1)

绘制混淆矩阵

cm = confusion_matrix(y_test, pred_classes)
cm_norm =  cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]


df_cm = pd.DataFrame(cm_norm, ['ARR', 'CHF', 'NSR'], ['ARR', 'CHF', 'NSR'])
plt.figure(figsize = (10,6))
conf = sns.heatmap(df_cm, annot=True, square=True, annot_kws={"size": 12})
conf.set_xlabel('Prediction')
conf.set_ylabel('True')

基于小波分析和机器学习的时间序列分析与识别 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/554097033

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
时间序列的小分析 时间序列(Time Series)是地学研究中经常遇到的问题。在时间序列研究中,时域和频域是常用的两种基本形式。其中,时域分析具有时间定位能力,但无法得到关于时间序列变化的更多信息;频域分析(如Fourier变换)虽具有准确的频率定位功能,但仅适合平稳时间序列分析。然而,地学中许多现象(如河川径流、地震、暴雨、洪水等)随时间的变化往往受到多种因素的综合影响,大都属于非平稳序列,它们不但具有趋势性、周期性等特征,还存在随机性、突变性以及“多时间尺度”结构,具有多层次演变规律。对于这类非平稳时间序列的研究,通常需要某一频段对应的时间信息,或某一时段的频域信息。显然,时域分析和频域分析对此均无能为力。 20世纪80年代初,由Morlet提出的一种具有时-频多分辨功能的小分析(Wavelet Analysis)为更好的研究时间序列问题提供了可能,它能清晰的揭示出隐藏在时间序列中的多种变化周期,充分反映系统在不同时间尺度中的变化趋势,并能对系统未来发展趋势进行定性估计。 目前,小分析理论已在信号处理、图像压缩、模式识别、数值分析和大气科学等众多的非线性科学领域内得到了广泛的应。在时间序列研究中,小分析主要用于时间序列的消噪和滤,信息量系数和分形维数的计算,突变点的监测和周期成分的识别以及多时间尺度的分析等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哥廷根数学学派

码字不易,且行且珍惜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值