本文继续讲解一篇关于小波变换在机器学习中的应用的博客:《A guide for using the Wavelet Transform in Machine Learning》,极力推荐!!3.1 使用连续小波变换可视化状态空间

1维信号的小波变换是2维的时间-尺度图,该图给出了系统状态空间的详细信息,也就是给出了系统的动态行为。

下图给出了El Nino数据集的原始时间序列信号、傅里叶变换和小波变换的结果。

3.2 使用连续小波变换和卷积神经网络进行信号的分类

由3.1部分的2维时间-尺度图可知:小波变换不仅可以更好地理解系统的动态行为,也可以被用来区分不同类型的信号。测试所用的数据集包含了人做6种不同的活动。

3.2.1 加载UCI-HAR时间序列数据集

对于数据集的描述如下:包含人做6种不同的活动,一共10000多个信号,每个信号包含如下图的9个分量。

由于每个信号包含9个分量,因此需要对每个信号进行9次连续小波变换。

按照7:3的比例划分所有信号,每个信号包含9个分量,每个分量包含128个样本点。因此,训练集的大小为(7352,128,9),测试集的大小为(2947,128,9)。3.2.2 对数据集应用连续小波变换,并且将数据变换到合适的格式

既然每条信号对应9张时间-尺度图,该怎么把它们输入到CNN中呢?有如下四种可选的方案:

1)为每个分量分别训练CNN,最终的结果通过集成方式确定。这个方法可能性能较差,因为它忽略了不同分量之间的联系;2)先将9个分量的时间序列信号串联起来,然后对串联信号做连续小波变换。这种方法会在信号拼接的地方不连续,进而在时间-尺度图上信号拼接处产生造成噪声。3)首先计算每个分量的连续小波变换,然后将9个不同分量的时间-尺度图拼接成一张大的,再输入到CNN中。但是该方法同样也会在拼接处不连续,从而将噪声引入到CNN中。如果CNN足够深,也许可以区分出这些噪声。4)将9个不同分量的时间-尺度图纵向摞在一起,形成一张通道数为9的图片,再输入到CNN中训练,如下图所示。

scales = range(1,128)waveletname = 'morl'train_size = 5000test_size= 500 train_data_cwt = np.ndarray(shape=(train_size, 127, 127, 9)) for ii in range(0,train_size):    if ii % 1000 == 0:        print(ii)    for jj in range(0,9):        signal = uci_har_signals_train[ii, :, jj]        coeff, freq = pywt.cwt(signal, scales, waveletname, 1)        coeff_ = coeff[:,:127]        train_data_cwt[ii, :, :, jj] = coeff_ test_data_cwt = np.ndarray(shape=(test_size, 127, 127, 9))for ii in range(0,test_size):    if ii % 100 == 0:        print(ii)    for jj in range(0,9):        signal = uci_har_signals_test[ii, :, jj]        coeff, freq = pywt.cwt(signal, scales, waveletname, 1)        coeff_ = coeff[:,:127]        test_data_cwt[ii, :, :, jj] = coeff_ uci_har_labels_train = list(map(lambda x: int(x) - 1, uci_har_labels_train))uci_har_labels_test = list(map(lambda x: int(x) - 1, uci_har_labels_test)) x_train = train_data_cwty_train = list(uci_har_labels_train[:train_size])x_test = test_data_cwty_test = list(uci_har_labels_test[:test_size])

对于一个信号单个分量进行连续小波变换的结果是127×127的图片,因此一个信号最终的格式为(127,127,9)。

3.2.3 训练卷积神经网络

import kerasfrom keras.layers import Dense, Flattenfrom keras.layers import Conv2D, MaxPooling2Dfrom keras.models import Sequentialfrom keras.callbacks import History history = History() img_x = 127img_y = 127img_z = 9input_shape = (img_x, img_y, img_z) num_classes = 6batch_size = 16num_classes = 7epochs = 10 x_train = x_train.astype('float32')x_test = x_test.astype('float32') y_train = keras.utils.to_categorical(y_train, num_classes)y_test = keras.utils.to_categorical(y_test, num_classes)  model = Sequential()model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1),                 activation='relu',                 input_shape=input_shape))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))model.add(Conv2D(64, (5, 5), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Flatten())model.add(Dense(1000, activation='relu'))model.add(Dense(num_classes, activation='softmax')) model.compile(loss=keras.losses.categorical_crossentropy,              optimizer=keras.optimizers.Adam(),              metrics=['accuracy'])  model.fit(x_train, y_train,          batch_size=batch_size,          epochs=epochs,          verbose=1,          validation_data=(x_test, y_test),          callbacks=[history]) train_score = model.evaluate(x_train, y_train, verbose=0)print('Train loss: {}, Train accuracy: {}'.format(train_score[0], train_score[1]))test_score = model.evaluate(x_test, y_test, verbose=0)print('Test loss: {}, Test accuracy: {}'.format(test_score[0], test_score[1]))

训练过程如下。

*** Epoch 1/10*** 5000/5000 [==============================] - 235s 47ms/step - loss: 0.3963 - acc: 0.8876 - val_loss: 0.6006 - val_acc: 0.8780*** Epoch 2/10*** 5000/5000 [==============================] - 228s 46ms/step - loss: 0.1939 - acc: 0.9282 - val_loss: 0.3952 - val_acc: 0.8880*** Epoch 3/10*** 5000/5000 [==============================] - 224s 45ms/step - loss: 0.1347 - acc: 0.9434 - val_loss: 0.4367 - val_acc: 0.9100*** Epoch 4/10*** 5000/5000 [==============================] - 228s 46ms/step - loss: 0.1971 - acc: 0.9334 - val_loss: 0.2662 - val_acc: 0.9320*** Epoch 5/10*** 5000/5000 [==============================] - 231s 46ms/step - loss: 0.1134 - acc: 0.9544 - val_loss: 0.2131 - val_acc: 0.9320*** Epoch 6/10*** 5000/5000 [==============================] - 230s 46ms/step - loss: 0.1285 - acc: 0.9520 - val_loss: 0.2014 - val_acc: 0.9440*** Epoch 7/10*** 5000/5000 [==============================] - 232s 46ms/step - loss: 0.1339 - acc: 0.9532 - val_loss: 0.2884 - val_acc: 0.9300*** Epoch 8/10*** 5000/5000 [==============================] - 237s 47ms/step - loss: 0.1503 - acc: 0.9488 - val_loss: 0.3181 - val_acc: 0.9340*** Epoch 9/10*** 5000/5000 [==============================] - 250s 50ms/step - loss: 0.1247 - acc: 0.9504 - val_loss: 0.2403 - val_acc: 0.9460*** Epoch 10/10*** 5000/5000 [==============================] - 238s 48ms/step - loss: 0.1578 - acc: 0.9508 - val_loss: 0.2133 - val_acc: 0.9300*** Train loss: 0.11115437872409821, Train accuracy: 0.959*** Test loss: 0.21326758581399918, Test accuracy: 0.93

3.3 利用离散小波变换分解信号

在2.5小节讲到离散小波变换可以通过一个滤波器组实现,可以将信号分解成一系列的频率子带。这部分,我们会用到PyWavelet包将一个信号分解成频率子带以及重构出原来的信号。PyWavelet提供了两种不同的方法来分解一个信号:1)pywt.dwt()可以多次对近似系数进行分解,一直到期望的分解层次;

(cA1, cD1) = pywt.dwt(signal, 'db2', 'smooth')reconstructed_signal = pywt.idwt(cA1, cD1, 'db2', 'smooth') fig, ax = plt.subplots(figsize=(8,4))ax.plot(signal, label='signal')ax.plot(reconstructed_signal, label='reconstructed signal', linestyle='--')ax.legend(loc='upper left')plt.show()

2)pywt.wavedec()可以一次性得到期望分解层次的所有近似系数和细节系数

coeffs = pywt.wavedec(signal, 'db2', level=8)reconstructed_signal = pywt.waverec(coeffs, 'db2')fig, ax = plt.subplots(figsize=(8,4))ax.plot(signal[:1000], label='signal')ax.plot(reconstructed_signal[:1000], label='reconstructed signal', linestyle='--')ax.legend(loc='upper left')ax.set_title('de- and reconstruction using wavedec()')plt.show()

3.4 使用离散小波变换移除高频噪声

丢弃将信号分解后的细节信号,就能达到移除噪声的目的。有许多不同的方法可以用来移除信号中的噪声。例如:Scipy库包含了许多平滑滤波器,并且使用也较为简单。那么,用离散小波变换移除高频噪声的优点是什么呢?主要是因为有许多不同形状的小波函数可以选择。我们可以选择一个与我们期望看到的特性相符的小波函数,这样的话我们期望看到的特性就不会被当成噪声被移除。

3.5 使用离散小波变换来对信号进行分类

在3.2小节使用了连续小波变换+CNN的方式对信号进行分类,在本小节将使用离散小波变换来对信号进行分类。

3.5.1 离散小波分类背后的思路

利用离散小波变换将一个信号分解成不同的频率子带。如果不同类别的信号具有不同的频率特性,那么频率特性的不同一定会展示在某一个频率子带上。我们可以从每一个频率子带上产生特征(比如一些统计特征),然后再把这些特征串联起来作为分类器的输入。

3.5.2 从每一个频率子带上产生特征

从每个频率子带上可以产生什么样的特征呢?一般而言,下面几种特征是最常使用的。因为在实际应用中不知道哪些特征是有用的,可先进行特征选择然后再分类,也可将特征选择融入到分类过程中。

· Auto-regressive model coefficient values· (Shannon) Entropy values; entropy values can be taken as a measure of complexity of the signal.· Statistical features like:    variance    standard deviation    Mean    Median    25th percentile value    75th percentile value    Root Mean Square value; square of the average of the squared amplitude values    The mean of the derivative    Zero crossing rate, i.e. the number of times a signal crosses y = 0    Mean crossing rate, i.e. the number of times a signal crosses y = mean(y)
def calculate_entropy(list_values):    counter_values = Counter(list_values).most_common()    probabilities = [elem[1]/len(list_values) for elem in counter_values]    entropy=scipy.stats.entropy(probabilities)    return entropydef calculate_statistics(list_values):    n5 = np.nanpercentile(list_values, 5)    n25 = np.nanpercentile(list_values, 25)    n75 = np.nanpercentile(list_values, 75)    n95 = np.nanpercentile(list_values, 95)    median = np.nanpercentile(list_values, 50)    mean = np.nanmean(list_values)    std = np.nanstd(list_values)    var = np.nanvar(list_values)    rms = np.nanmean(np.sqrt(list_values**2))    return [n5, n25, n75, n95, median, mean, std, var, rms]def calculate_crossings(list_values):    zero_crossing_indices = np.nonzero(np.diff(np.array(list_values) < 0))[0]    no_zero_crossings = len(zero_crossing_indices)    mean_crossing_indices = np.nonzero(np.diff(np.array(list_values) < np.nanmean(list_values)))[0]    no_mean_crossings = len(mean_crossing_indices)    return [no_zero_crossings, no_mean_crossings]def get_features(list_values):    entropy = calculate_entropy(list_values)    crossings = calculate_crossings(list_values)    statistics = calculate_statistics(list_values)    return [entropy] + crossings + statistics

3.5.3 使用上一小节产生的特征以及scikit-learn中的分类器对两个ECG数据集进行分类

下一步是利用离散小波变换将训练集中的信号分解为频率子带,为每个子带计算特征,使用这些特征训练分类器以及使用分类器来预测信号。

如果一个信号有多个分量,则先对每个分量提取特征,再将这些分量串接在一起,作为该信号的特征向量。

使用DTW进行分类的精度依赖你所提取的特征、所选择的小波函数以及所使用的分类器(梯度增强算法表现较好)。

4、结语

这篇博客利用小波变换对时间序列进行分析和分类。

可以在这个链接:https://github.com/taspinar/siml中找到相应代码。

机器学习中val_小波变换(七):小波变换在机器学习中的应用(下)相关推荐

  1. 自动机器学习:团队如何在自动学习项目中一起工作?(附链接)

    来源 | 数据派THU 作者 | Francesca Lazzeri 翻译 | 王琦 责编 | Carol 出品 | AI科技大本营(ID:rgznai100) 去年11月,我写了一篇关于使用自动机器 ...

  2. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  3. 机器学习入门笔记(七):聚类

    文章目录 一.聚类的基本概念 1.1 相似度或距离 1.2 类或簇 1.3 类与类之间的距离 二.层次聚类 2.1 基本概念 2.1 算法描述 2.3 例题 三.K均值聚类 3.1 模型 3.2 策略 ...

  4. 《机器学习实战》(七)-- LinearRegression

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://mp.csdn.net/mdeditor/100577083 目录 ...

  5. 【机器学习算法面试题】四.深度神经网络中激活函数有哪些?

    欢迎订阅本专栏:<机器学习算法面试题> 订阅地址:https://blog.csdn.net/m0_38068876/category_11810806.html [机器学习算法面试题]一 ...

  6. 李弘毅机器学习笔记:第七章—深度学习的发展趋势

    李弘毅机器学习笔记:第七章-深度学习的发展趋势 回顾一下deep learning的历史: 1958: Perceptron (linear model) 1969: Perceptron has l ...

  7. 机器学习应用篇(七)——基于LightGBM的分类预测

    机器学习应用篇(七)--基于LightGBM的分类预测 文章目录 机器学习应用篇(七)--基于LightGBM的分类预测 一.Introduction 1 LightGBM的优点 2 LightGBM ...

  8. 二十三.基于机器学习的恶意请求识别及安全领域中的机器学习

    这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步.前文分享了Web渗透的第一步工作,涉及网站信息.域名信息.端口信息.敏感信息及指纹 ...

  9. Nat. Rev. Neurol. | 机器学习在神经退行性疾病诊断和治疗中的应用

    今天为大家介绍的是2020年6月谢菲尔德大学Laura Ferraiuolo教授课题组和BenevolentAI公司合作发表在Nature Reviews Neurology上的一篇有关神经退行性疾病 ...

  10. 独家 | 自动机器学习:团队如何在自动学习项目中一起工作?(附链接)

    作者:Francesca Lazzeri 翻译:王琦 校对:冯羽 本文约3300字,建议阅读13分钟. 本文介绍了在零售商工作的数据科学家.项目经理和业务主管利用自动机器学习和Azure机器学习服务来 ...

最新文章

  1. Nova — 虚拟机密码修改
  2. 搭建Python+Django开发环境
  3. C++ 初始化列表初始化列表性能问题的简单的探索
  4. Bootstrap学习笔记系列1-------Bootstrap网格系统
  5. redis发布订阅c接口_Redis 发布/订阅机制原理分析
  6. 上证50基金有哪些_定投基金(易方达上证50指数A)
  7. wordpress模板-单栏整洁的个人博客Siren主题模板
  8. “安防+人工智能”,安企选择哪种抱大腿姿势才有出息?
  9. 练习题︱基于今日头条开源数据(二)——两款Apriori算法实践
  10. 怎么下载英文文献?多种方法告诉你
  11. java中的缓存详解,一篇就够了
  12. Servlet 请求转发
  13. linux 卸载 flash,Linux系统下Flash Player崩溃的一个解决办法分享
  14. 1638_chdir函数的功能
  15. Jetson nano/NX 部署Yolo v5过程记录
  16. 你真的了解白帽、黑帽、灰帽 吗?看看这个你就懂了
  17. androidtv gms包_Android之GMS自我总结
  18. 微信小程序和百度小程序差异(持续更新)
  19. dlib.get_frontal_facedetector UINT8 和float格式互相转换
  20. Linux环境编程05

热门文章

  1. python装饰器实现对异常代码出现进行监控
  2. 如何写一个Python万能装饰器,既可以装饰有参数的方法,也可以装饰无参数方法,或者有无返回值都可以装饰
  3. Python文件读写、StringIO和BytesIO
  4. mysql数据太大,如何导入_MySQL导入文件过大怎么办
  5. java 连接 sftp失败,与apache vfs的SFTP连接失败,但使用WinSCP成功
  6. 如何新建分支上传_Git分支策略及操作演示1|IDCF FDCC认证学员作品
  7. flask request (request.files)
  8. 克隆仓库时HTTPS和SSH方式的区别和使用
  9. 深入浅出python机器学习_6.3.1_随机森林实例——要不要和相亲对象进一步发展
  10. 人体姿态估计论文总结 (2D + 视频)