简介大多数时间序列数据主要用于生成交易预测。无论是预测产品的需求或销售、航空公司的乘客数量还是特定股票的收盘价,我们都可以利用时间序列技术来预测需求。
随着生成的数据量呈指数级增长,尝试新想法和算法的机会也随之增加。处理复杂的时间序列数据集仍然是一个尚未探索的领域。
本文的目的是介绍时间序列分类中的新概念。我们首先要了解这个概念的含义及其在工业中的应用。我们不会仅仅停留在理论部分,还会通过处理时间序列数据集和执行分类来解决实际问题。通过实践学习可以帮助您以实用的方式理解概念。
时间序列分类简介时间序列分类实际上已经存在了一段时间。但到目前为止,它主要用于实验室研究而不是工业应用。有很多正在进行的研究、新创建的数据集、许多新算法。当我第一次接触到时间序列分类的概念时,我最初的想法是:我们如何对时间序列进行分类,时间序列分类数据是什么样的?我相信你也想知道。
可以想象,时间序列分类数据与常规分类问题不同,因为它的属性是有序序列。让我们看一些时间序列分类用例并了解它们之间的差异。
1.心电/脑电信号分类
心电图(ECG,心电图)用于记录心脏的电活动,广泛用于诊断各种心脏问题。这些心电图信号是使用外部电极捕获的。
例如,考虑以下信号样本,它代表心跳的电活动。左边的图像代表正常的心跳,而相邻的图像代表心肌梗塞。
从电极捕获的数据将以时间序列的形式出现,并且信号可以分为不同的类别。我们还可以对记录大脑电活动的脑电图信号进行分类。
2. 图像分类
图像也可以按时间顺序相关。考虑以下情况:
农作物根据天气条件、土壤肥力、水的可用性和其他外部因素在特定的田地中种植。继续五年内每天对该地区拍照,并标记该地区种植的农作物的名称。该数据集中的图像是按固定间隔和特定顺序拍摄的,这可能是图像分类的重要因素。
3. 运动传感器数据分类
传感器生成高频数据,可以识别其范围内物体的运动。通过设置多个无线传感器并观察传感器中信号强度的变化,我们可以识别物体的运动方向。
您还知道时间序列分类的其他应用吗?欢迎大家在文末留言。
在描述问题场景时,我们将重点关注“室内用户运动预测”问题。在这个问题中,多个运动传感器被放置在不同的房间中,目标是根据这些运动传感器捕获的频率数据来识别个体是否在房间之间移动。
两个房间(A1、A2、A3、A4)中有四个运动传感器。请参阅下图,其中显示了每个房间中传感器的位置。共设置3对相似房间(group1、group2、group3)。
一个人可以沿着上图所示的六个预定义路径中的任何一个移动。路径2、3、4或6用于在房间内移动,路径1或5用于在房间之间移动。
传感器的读数可以识别一个人在某个时间点的位置。当人在房间内或周围移动时,传感器中的读数会发生变化。改变可以用来识别一个人的路径。
现在问题已经明确了,是时候开始编码了!在下一节中,我们将研究该问题的数据集,这有助于使问题更加清晰。数据集:室内用户运动预测。
查看数据集数据集共包含316个文件:
314 MovementAAL csv 文件,包含环境中运动传感器的读数。包含每个MovementAAL 文件的目标变量的目标csv 文件。组数据csv 文件,用于标识MovementAAL 文件属于哪个组。路径csv 文件包含目标所采用的路径。让我们首先看一下数据集。
将pandas 导入为pd
将numpy 导入为np
%matplotlib 内联
将matplotlib.pyplot 导入为plt
从操作系统导入列表目录
来自keras.preprocessing 导入序列
导入张量流astf
从keras.models 导入顺序
从keras.layers 导入密集
从keras.layers 导入LSTM
从keras.optimizers 导入Adam
从keras.models 导入load_model
从keras.callbacks 导入ModelCheckpoint
在加载所有文件之前,快速浏览一下要处理的数据。读取移动数据的前两个文件:
df1=pd.read_csv(\’/MovementAAL/dataset/MovementAAL_RSS_1.csv\’)
df2=pd.read_csv(\’/MovementAAL/dataset/MovementAAL_RSS_2.csv\’)
d1.head()
df2.head()
df1.形状、df2.形状
((27, 4), (26, 4))
这些文件包含四个传感器—— A1、A2、A3、A4 的标准化数据。 csv 文件的长度(行数)不同,因为相应的持续时间不同。为了方便起见,我们假设每秒收集一次传感器数据。第一个更改持续27 秒(第27 行),而另一个更改持续26 秒(第26 行)。
在构建模型之前,我们必须处理这种不同的长度。以下代码用于读取和存储传感器值:
路径=\’MovementAAL/数据集/MovementAAL_RSS_\’
序列=列表()
对于范围(1,315): 内的i
文件路径=路径+ str(i) + \’.csv\’
打印(文件路径)
df=pd.read_csv(文件路径,标题=0)
值=df.values
序列.append(值)
目标=pd.read_csv(\’MovementAAL/dataset/MovementAAL_target.csv\’)
目标=目标.值[:1]
现在有一个名为“序列”的列表,其中包含目标——csv 文件的运动传感器数据和标签。序列[0]中的数据是第一个csv文件中获取的传感器的值:
序列[0]
如上所述,数据集是在三对不同的房间中收集的,因此共有三组数据。数据集可分为训练集、测试集和验证集。现在加载DatasetGroup csv 文件:
groups=pd.read_csv(\’MovementAAL/groups/MovementAAL_DatasetGroup.csv\’, header=0)
组=groups.values[:1]
前两组数据用于训练,第三组数据用于测试。
预处理由于时间序列数据的长度不同,我们无法直接在数据集上建立模型。那么如何确定合适的长度呢?我们可以通过多种方式来处理这个问题。以下是一些简单的想法(欢迎评论区批评和建议):
用零填充较短的序列以使所有序列长度相等。这样,我们向模型提供不正确的数据来找到序列的最大长度,使用最后一行中的数据填充来确定数据集中序列的最小长度,并将所有其他序列截断为该长度。这将丢失大量数据,取所有长度的平均值,截断较长的序列,并填充较短的序列以获得最小、最大和平均序列长度:
长度序列=[]
对于序列:中的one_seq
len_sequences.append(len(one_seq))
pd.Series(len_sequences).describe()
计数314.000000
平均值42.028662
标准16.185303
分钟19.000000
25% 26.000000
50% 41.000000
75% 56.000000
最大129.000000
dtype: float64
大多数文件的长度在40 到60 个字符之间。只有3 个文件的长度超过100。因此,采用最小或最大长度没有多大意义。第90 个四分位数是60,可以作为所有序列的长度。代码:
# 用最长序列最后一行的数据填充较短序列
到_垫=129
新序列=[]
对于序列:中的one_seq
len_one_seq=len(one_seq)
最后一个值=one_seq[-1]
n=to_pad – len_one_seq
to_concat=np.repeat(one_seq[-1], n).reshape(4, n).transpose()
new_one_seq=np.concatenate([one_seq, to_concat])
new_seq.append(new_one_seq)
Final_seq=np.stack(new_seq)
# 截断较长的序列
来自keras.preprocessing 导入序列
序列长度=60
Final_seq=sequence.pad_sequences(final_seq, maxlen=seq_len, padding=\’post\’, dtype=\’float\’, truncating=\’post\’)
然后根据分组分离数据集,准备训练集、验证集和测试集:
train=[final_seq[i] for i in range(len(groups)) if (groups[i]==2)]
验证=[final_seq[i] for i in range(len(groups)) if groups[i]==1]
test=[final_seq[i] for i in range(len(groups)) if groups[i]==3]
train_target=[目标[i] for i in range(len(groups)) if (groups[i]==2)]
validation_target=[targets[i] for i in range(len(groups)) if groups[i]==1]
test_target=[目标[i] for i in range(len(groups)) if groups[i]==3]
火车=np.array(火车)
验证=np.array(验证)
测试=np.array(测试)
train_target=np.array(train_target)
训练目标=(训练目标+1)/2
验证目标=np.array(验证目标)
验证目标=(验证目标+1)/2
test_target=np.array(test_target)
测试目标=(测试目标+1)/2
构建分类模型我们已经为LSTM(长短期记忆)模型准备了数据,处理了不同长度的序列并创建了训练、验证和测试集。下一步是构建单层LSTM 网络。
模型=顺序()
model.add(LSTM(256, input_shape=(seq_len, 4)))
model.add(密集(1,激活=\’sigmoid\’))
模型.summary()
训练模型并验证准确性:
亚当=亚当(lr=0.001)
chk=ModelCheckpoint(\’best_model.pkl\’, Monitor=\’val_acc\’, save_best_only=True, mode=\’max\’, verbose=1)
model.compile(loss=\’binary_crossentropy\’, 优化器=adam, 指标=[\’accuracy\’])
model.fit(train,train_target,epochs=200,batch_size=128,callbacks=[chk],validation_data=(validation,validation_target))
最终准确率得分为0.78846153846153844。这是一个非常好的开始,但我们还可以通过使用超参数、改变学习率或迭代次数来提高LSTM 模型的性能。