时间序列分类

434 阅读6分钟

在这篇文章中,我们将了解一个初级的时间序列分类方法。

目录

  • 简介
  • 数据集
  • 安装/设置
  • 合并和拆分数据
  • 特征提取
  • 创建和测试一个机器学习分类器
  • 测试/结果
  • 总结

绪论

什么是时间序列?

时间序列是一个按时间顺序排列的数据点序列。通常情况下,时间序列是在相同间隔的时间点上进行测量的序列。

时间序列数据的一些常见例子包括股票价格和历史天气数据。时间序列在病人健康监测中也很常见,如连续测量神经活动的脑电图(EEG)和监测心脏活动的心电图(ECG)。

什么是时间序列分类?

时间序列分类是用来预测一个时间序列属于哪个类别。基于一个时间序列中的几个数据点,时间序列分类被用来确定整个时间序列所属的类别。

时间序列分类的方法

在这篇文章中,我们将介绍一个初级的时间序列分类方法。使用tsfresh Python 库,我们将首先为每个时间序列提取数千个统计特征,包括方差、偏度、标准差和一些更复杂的特征。然后,我们将以表格的形式存储这些特征,丢弃不重要的特征,并在得到的数据上训练一个机器学习模型。

数据集

我们将通过一个时间序列分类的应用来预测真实世界办公环境中的用户移动模式。

这个问题涉及到根据无线传感器网络(WSN)节点之间的无线电信号强度(RSS)的时间序列来确定一个人是否在房间之间移动。

该数据集是由意大利比萨大学的研究人员收集并提供的。他们的论文《环境辅助生活应用中水库计算的实验特征》对其进行了描述。

下载数据集

该数据集可以通过这个链接在UCI机器学习资源库中找到。

数据集结构

对于我们的任务,我们将只使用dataset 目录。dataset 目录的组织方式如下。

dataset
    MovementAAL_RSS_1.csv
    MovementAAL_RSS_2.csv
    ...
    MovementAAL_target.csv

每个MovementAAL_RSS_{id} 文件代表一个时间序列,按时间顺序进行测量,包含四列代表RSS测量值。

MovementAAL_target.csv 包含这些时间序列中每一列的标签。目标类别1代表位置改变的运动,而-1代表位置保持的运动。

安装和设置

使用下面的pip 命令来安装必要的库。

pip install pandas
pip install numpy
pip install scikit-learn

导入一些我们需要的主要库和模块。

import os

import numpy as np
import pandas as pd

当我们需要时,我们将导入更多的库和模块。

合并和拆分数据

我们将把所有单独的RSS数据文件合并成一个数据框,并把数据分成80%的训练数据和20%的测试数据。

让我们首先加载类标签。

data_path = '..' # the root dataset path, change if necessary

target_df = pd.read_csv(os.path.join(data_path, 'dataset', 'MovementAAL_target.csv')) # read the labels CSV file

这些是target_df 的前几行。
sequence_labels

#sequence_ID 列代表每个序列的ID,以后我们将用这个ID来引用序列对应的时间序列CSV文件。

接下来,由于在#sequence_IDclass_label 之间有一个空格,pandas将第二列读作 " class_label",在开头有一个额外的空格。我们将删除这个空格,这样以后使用数据就会更方便。

labels = target_df[' class_label']
labels.rename('class_label', inplace=True) # remove the leading whitespace

接下来,我们将创建一个包含每个序列ID的列表。

sequence_ids = target_df['#sequence_ID']

分割数据

如果我们在合并每个单独的序列之前分割数据,那么代码就会简单得多。通过这样做,我们将有一个每个训练序列的ID列表,以及一个单独的测试ID列表。

from sklearn.model_selection import train_test_split
train_ids, test_ids, train_labels, test_labels = train_test_split(sequence_ids, labels, test_size=0.2)

现在,我们将创建两个数据框,一个用于训练数据,另一个用于测试数据。

X_train = pd.DataFrame()
X_test = pd.DataFrame()

现在,将循环浏览训练序列的ID和测试序列的ID。对于每一个序列ID,我们将读取相应的RSS时间序列数据CSV文件并将其添加到主数据框中。我们还将添加一列序列号和一列step ,其中包含代表序列中时间步长的整数(例如,它是时间序列中的第一次还是第二次测量)。

for i, sequence in enumerate(train_ids):
    df = pd.read_csv(os.path.join(data_path, 'dataset', f'MovementAAL_RSS_{sequence}.csv'))
    df.insert(0, 'sequence', i)
    df['step'] = np.arange(df.shape[0]) # creates a range of integers starting from 0 to the number of the measurements.
    X_train = pd.concat([X_train, df])

for i, sequence in enumerate(test_ids):
    df = pd.read_csv(os.path.join(data_path, 'dataset', f'MovementAAL_RSS_{sequence}.csv'))
    df.insert(0, 'sequence', i)
    df['step'] = np.arange(df.shape[0])
    X_test = pd.concat([X_test, df])

特征提取

现在,我们将使用tsfresh Python库来提取特征。

下面的代码将生成一个有3000多个特征的综合特征集。参数column_id 是表示一个测量值属于哪个时间序列的列。参数column_sort ,用于对每个时间序列的测量值进行排序。然而,这对我们来说是没有必要的,因为数据集已经包含了按时间顺序排列的测量值。这段代码运行大约需要1-2分钟。

from tsfresh import extract_features

extracted_features = extract_features(X_train, column_id='sequence', column_sort='step')

extracted_features 现在,我们的数据集包含了3000多列。现在,我们将估算所有的缺失值,只保留相关的特征。

from tsfresh import select_features
from tsfresh.utilities.dataframe_functions import impute

impute(extracted_features)
train_labels = train_labels.reset_index() # reset the index 
features_filtered = select_features(extracted_features, train_labels['class_label'])

在这之后,我们只有大约300列。这种减少将减少模型的训练时间,而不会丢失任何重要信息。

现在,让我们提取测试数据的特征,并计算出缺失值。

test_features =  extract_features(X_test, column_id='sequence', column_sort='step')
impute(test_features)

我们将保留我们在训练数据中保留的相同列。

test_features_filtered = test_features[features_filtered.columns]

创建和测试一个机器学习分类器

我们将创建一个由1000棵决策树组成的随机森林分类器。

from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators = 1000)
rf.fit(features_filtered, train_labels['class_label'])

现在,让我们测试一下准确性。

from sklearn.metrics import accuracy_score
print(accuracy_score(test_labels, rf.predict(test_features_filtered)))
0.9206349206349206

如上所示,我们的模型的准确率为~92%。

总结

在这篇文章中,我们学习了一种初级的时间序列分类方法。我们的最终模型最终以超过92%的准确率表现出来。如果你对这个数据集上应用的其他模型和技术的结果感兴趣,可以看看我的GitHub仓库

这篇文章就写到这里,感谢您的阅读。

参考文献。

  • Bacciu, D., Barsocchi, P., Chessa, S., Gallicchio, C., & Micheli, A. (2013)。水库计算在环境辅助生活应用中的实验特征。神经计算和应用,24(6),1451-1464。https://doi.org/10.1007/s00521-013-1364-4
  • Christ, M., Braun, N., Neuffer, J., & Kempa-Liehr, A. W. (2018).基于可扩展假设测试的时间序列FeatuRe提取(tsfresh - A Python软件包)。Neurocomputing, 307, 72-77.doi.org/10.1016/j.n…