仅以本文来记录初次处理伴随时间的一维数据的过程,后续若有改进,持续补充。
1. 数据预处理
1.1 数据详情
伴随时间的一维数据是指跟着时间同步变化的一维数据,对应不同时间具有不同变化特征,现已打好标签。任务目标就是使用一维数据进行分类。
举个栗子,10:00:00开始,10:00:00-10:02:00,记录下200条数据,经观察知道该阶段对应标签1,即0-200条数据对应标签都是1;10:02:01-10:03:00,记录下100条数据,该阶段对应标签2,即100-300条数据对应标签都是2。
下面是数据的一个片段:
图一 数据某片段对应波形
1.2 特征
针对伴随时间的一维数据,每个点都对应一个标签,但某个标签往往都持续一段时间,即单个点很难看出有什么特征,反而是在数据的某一段与另一端中能够体现出不同标签下的差异和特征。因此,采用10s的时间窗口,相邻窗口50%的重叠,也就是0-10s的数据段、5s-15s的数据段、10-20s的数据段...依次类推。
直观地,可以想到不同标签下的数据段可能在时域和频域上有显著差别。因此,我们求一些经典的统计量:
时域上,求均值、中位数、方差、标准差、最大值、最小值、峰峰值(最大值-最小值)、众数和大于均值的个数 共9个统计量。
频域上,将每个数据段都傅里叶变换之后,求直流分量(傅里叶变换后的第一个值a0)、幅度均值、幅度方差、幅度标准差、幅度斜度、幅度峰度,功率谱密度等共21个统计量。
为了兼顾时频特征,另外求小波域上的统计量。采用db1小波对数据段进行两层分解,得到小波分解系数:二级低频ca2、一级高频cd1、二级高频cd2。而后,通过小波分解系数进行重构,得到重构信号ca2_rec、cd1_rec、cd2_rec。所求统计量包括:
小波域上,ca2、cd1、cd2各自的最大值、最小值,重构信号ca2_rec、cd1_rec、cd2_rec各自的最大值、最小值以及能量总和(数据段内所有点的平方和)共计15个统计量。
综上,对于每一个数据段,可在三个域上求得统计量共45个。
1.3 降维
上述得到了45个统计量,对于下一步进行分类来说,过于繁琐。因此,进行一定的特征约简。此处采用的是主成分分析PCA进行降维。
主成分分析指的是利用数据中最主要的方面来代替原始数据。原始数据为(x(1),x(2),...x(m)),每个数据具有n维,共m个数据。通过某种变换降低每个数据的维度,例如从n维降低到d维,使得m×d维数据集尽可能表示出原始数据,信息损失最小。
PCA具体算法步骤如下:
1.将原始数据标准化(减去均值再除以标准差),得到矩阵X;
2.求X的协方差矩阵Cov(X);
3.对Cov(X)进行特征值分解,得到特征值λ1,λ2,...,λn和对应的特征向量w1,w2,...,wn;
4.将前几个最大的特征值取出,得到对应的特征向量如w1,w2,..wd,标准化后形成特征向量矩阵W
5.使用矩阵W转置后,对原始数据进行变换,得到z(i)=*x(i),最终得到降维后的数据D=(z(1),z(2),...z(d))。
针对最后一步,通俗的来讲,原始数据的每一行都去和挑选出的特征向量w1,w2,..wd相乘,每行都能得到z(i,1),z(i,2),...z(i,d),填入对应行号中,该过程将原始数据每一行的n维降低为d维。
1.4 匹配标签
通过上述步骤,得到了每个数据段降维后的统计量,一个数据段内的表现浓缩为d个统计量。但是针对每个数据段内的每一个点,都对应有标签,即一个数据段内对应了n个标签。这样是没办法进行分类的,只能是一个数据段对应一个标签。因此,这里采取数据段内标签的众数作为整个数据段的标签。计算n个标签的众数填入对应数据段号,最终得到了每个数据段内包含d个统计量和一个对应的标签。
至此,数据预处理完成。
本文PCA部分主要参考以下帖子,非常感谢:
主成分分析法(PCA)及其python实现_python pca-CSDN博客
附录
在此提供时域上求解特征的代码,其他代码可私聊获取。
from openpyxl import load_workbook
from statistics import mean, mode, stdev, variance, median
from collections import Counter
resbook = load_workbook(r'.\time_feature.xlsx') # 存入结果
res_sheet = resbook.create_sheet('Sheet_10s_copy')
header = ['mean', 'mode', 'stedv', 'variance', 'median', 'max',
'min', 'gap', 'num']
res_sheet.append(header)
workbook = load_workbook(r'.\raw_data_copy.xlsx') # 读取原始数据
sheet1 = workbook["Sheet1"]
ans = []
s = 2
temp = []
r = 1
flag = 1
while r < sheet1.max_row + 1:
v = sheet1.cell(r, 1).value
temp.append(v)
r += 1
flag += 1
if flag % 201 == 0:
r -= 100
flag = 1
mean_temp = mean(temp) # 均值
mode_temp = (Counter(temp).most_common(1))[0][0] # 众数
stdev_temp = stdev(temp) # 标准差
variance_temp = variance(temp) # 方差
median_temp = median(temp) # 中位数
max_temp = max(temp) # 最大值
min_temp = min(temp) # 最小值
gap_temp = max_temp - min_temp # 极差
num = 0 # 大于均值的个数
for j in temp:
if j > mean_temp:
num += 1
temp = []
res_sheet.cell(s, 1).value = mean_temp
res_sheet.cell(s, 2).value = mode_temp
res_sheet.cell(s, 3).value = stdev_temp
res_sheet.cell(s, 4).value = variance_temp
res_sheet.cell(s, 5).value = median_temp
res_sheet.cell(s, 6).value = max_temp
res_sheet.cell(s, 7).value = min_temp
res_sheet.cell(s, 8).value = gap_temp
res_sheet.cell(s, 9).value = num
s += 1
resbook.save(r'.\0506_1_time_feature.xlsx')