|
本帖最后由 matlab的旋律 于 2021-12-12 15:58 编辑
数据来源和样本分割可参考帖子: 数据来源和样本分割
前面的帖子中介绍了用于人体日常活动分类的六轴传感信号的数据来源,本帖中介绍如何将数据进行样本分割得到适合分类器模型进行训练和预测的样本集。分类器模型进行训练和预测的样本集包括两个部分:一是样本的数据集,这部分对应4个部位六轴的传感信号,一般选择至少包含一个或者几个完整动作时长的传感数据,因此这里样本的数据集包括24个通道和时长信息;二是样本的标签,对应人体日常活动分类,样本的标签与样本的数据是对应的关系,按照DaLiAc数据库的数据形式也就是当分割后的样本的数据对应的L全部相同时,样本数据对应的标签为L,否则不符合样本集规则,丢弃。根据前面的叙述,划分样本集的关键是如何选择样本数据对应的时长,以及每个数据是否进行时间覆盖(即滑动窗口截取数据时,窗口长度小于每个样本数据的长度)。
采样使用重叠采样的方法对模型输入进行操作,具体过程为在同一条数据中进行滑动窗口获取前一个样本,重叠一定比例(这里为50%)窗口获得下一个样本。如下图所示:
对应的数据分割python代码如下:
- # -*- coding: utf-8 -*-
- # @File : DataPrepro.py
- # @Author : Xiaoyong Li
- # @Email : debugvsrun@163.com
- # @University : South China Normal University
- # @Date : 2021/06/29
- # @Software : vscode
- # -*---------------------------------------------------------*-
- import os
- import numpy as np
- import math
- import matplotlib
- matplotlib.rcParams['font.family'] = 'STsong' # # 字体类型
- matplotlib.rcParams['font.style'] = 'normal' # # 字体样式
- matplotlib.rcParams['font.size'] = 18 # # 字体大小
- import matplotlib.pyplot as plt
- # plt.rcParams['font.sans-serif'] = ['SimHei']
- # plt.rcParams['axes.unicode_minus'] = False
- class DataPrepro(object):
- def __init__(self):
- self.fs = 204.8
- self.win_len = math.ceil(self.fs*2)
- self.overlap_len = math.ceil(self.fs*1)
- self.lw = 2
- self.fontsize = 12
- def _getSampleFunc(self, data):
- sample_data = np.empty(shape=[0, self.win_len, data.shape[1]-1])
- label_data = []
- for k in range(len(data)//self.overlap_len-2):
- temp = np.array(data[self.overlap_len*k:self.overlap_len*(k+2), :], dtype='float64')
- flag = np.unique(temp[:, 24])
- if len(flag) > 1:#标签不一致表示不是同一动作的数据
- continue
- label_data.append(temp[0, 24])
- temp = np.expand_dims(temp[:, 0:-1], 0)
- sample_data = np.concatenate((sample_data, temp), axis=0)
- return sample_data, label_data
- def _Draw(self, data):
- sample_loc = 1000
- t = np.linspace(0, 2, num=410)
- fig = plt.figure(figsize=(8, 4))
- axs1 = fig.add_subplot(211)
- axs1.plot(t,data[sample_loc, :, 0:3], lw=self.lw)
- axs1.plot(t,data[sample_loc, :, 6:9], lw=self.lw)
- axs1.plot(t,data[sample_loc, :, 12:15], lw=self.lw)
- axs1.plot(t,data[sample_loc, :, 18:21], lw=self.lw)
- axs1.set_title(r'加速度信号', loc="center", fontsize=self.fontsize)
- axs1.set_xlabel(r'时间/s', fontsize=self.fontsize)
- axs1.set_ylabel('g', fontsize=self.fontsize)
- axs1.grid()
- plt.xticks(fontsize=self.fontsize)
- plt.yticks(fontsize=self.fontsize)
-
-
- axs2 = fig.add_subplot(212)
- axs2.plot(t, data[sample_loc, :, 3:6], lw=self.lw)
- axs2.plot(t, data[sample_loc, :, 9:12], lw=self.lw)
- axs2.plot(t, data[sample_loc, :, 15:18], lw=self.lw)
- axs2.plot(t, data[sample_loc, :, 21:24], lw=self.lw)
- axs2.set_title(r'陀螺仪信号', loc="center", fontsize=self.fontsize)
- axs2.set_xlabel(r'时间/s', fontsize=self.fontsize)
- axs2.set_ylabel('deg', fontsize=self.fontsize)
- plt.xticks(fontsize=self.fontsize)
- plt.yticks(fontsize=self.fontsize)
- axs2.grid()
- plt.subplots_adjust(bottom=0.1, top=0.85, left=0.1, right=0.9,
- hspace=0.55, wspace=0.2)#子图之间的间隔
- fig.legend(("wx", "wy", "wz", "cx", "cy", "cz", "hx", "hy", "hz", "ax", "ay", "az"),
- ncol=6, loc='upper center', fontsize=self.fontsize-4)
- plt.savefig('sensor.png', dpi=fig.dpi)
- plt.show()
- def getFileName(self, FilePath):#python程序
- f_list = os.listdir(FilePath) #获取指定目录下的所有指定后缀的文件名
- sample_data = np.empty(shape=[0, self.win_len, 24])
- label_data = []
- for FileName in f_list:
- if os.path.splitext(FileName)[1] == '.txt': #分离文件名与扩展名
- file_path_name = os.path.join(FilePath, FileName)#文件路径与文件名连接完整路径
- data = np.loadtxt(file_path_name, dtype='float64', delimiter=',')#文件内容为用逗号分隔的数值
- data, label = self._getSampleFunc(data)
- self._Draw(data)
- sample_data = np.concatenate((sample_data, data), axis=0)
- label_data.extend(label)
- break
- return sample_data, np.array(label_data)
复制代码 生成样本的处理函数已经全部构建,下面就可以调用这些子函数进行样本划分了。将下载的daliac.zip解压缩放在存放代码的同一文件夹中,然后运行下面的代码,生成对应的样本sample_data和样本标签sample_label,共计1169个通道数为24长度为410的样本, 然后通过函数np.random.shuffle进行顺序的随机排列。
其中某一样本数据绘图显示如下:
其中的w、c、h、a分别表示Wrist、Chest、Hip、Ankle,对应加速度的x、y、z表示加速度三轴数据,对应陀螺仪的x、y、z表示陀螺仪Roll、Pitch、Yaw数据。
- if __name__ == '__main__':
- num_classes = 13#样本的分类数
- classes = [str(i+1) for i in range(num_classes)]
- FilePath = 'Data/daliac'#路径
- data_prepro = DataPrepro()
- sample_data, sample_label = data_prepro.getFileName(FilePath)
- sample_data = sample_data.swapaxes(1, 2)#相当于转置
- index = np.arange(sample_label.shape[0])
- np.random.shuffle(index)
- sample_data = sample_data[index, :, :]
- sample_label = sample_label[index]
复制代码 在sklearn库中也有自带随机划分训练和测试样本集的函数train_test_split,具体代码实现如下:- from sklearn.model_selection import train_test_split
- X_train_seq, X_test_seq, y_train, y_test = train_test_split(sample_data, sample_label, test_size=0.2, random_state=7)
复制代码
以上程序就完成了原始数据的读取和样本的划分。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|