Press "Enter" to skip to content

时间序列分类用于跑步者的疲劳检测 – 教程

踏进跑步者佩戴传感器数据的互参与者和内参与者分类的逐步指南

作者图片

使用佩戴式传感器收集的跑步数据可以提供有关跑者表现和整体技术的见解。这些传感器产生的数据通常是时间序列性质的。本教程演示了在跑步数据集上使用时间序列分类方法进行疲劳检测任务。在本教程中,原始格式的时间序列数据被使用,而不是从时间序列中提取特征。这样会增加数据的一个额外维度,因此传统的采用传统向量格式使用数据的机器学习算法效果不好。因此需要使用特定的时间序列算法。

数据包含正常和疲劳状态下的跑步者的动作捕捉数据。该数据是在爱尔兰都柏林大学(University College Dublin)使用惯性测量单元(IMU)收集的。本教程使用的数据可在https://zenodo.org/records/7997851找到。该数据进行了一个二元分类任务,我们试图预测“疲劳”和“非疲劳”之间的区分。在本教程中,我们使用专用的Python包,Scikit-learn;这是一个用于Python上机器学习的工具包和sktime;这是专门用于时间序列的机器学习库。

数据集包含多个通道的数据。在这里,为了简单起见,我们将问题建模为单变量问题,因此只使用了一个通道的数据。我们选择了加速度的振幅信号,因为它是性能最好的信号[1, 2]。振幅信号是每个方向分量的平方和的平方根。

有关数据采集和处理的更详细信息可以在以下论文中找到[1, 2]。

总结一下,本教程:

  • 使用最新的时间序列分类技术对佩戴传感器收集的数据进行时间序列分类任务。
  • 对于跑步者的疲劳检测,比较了使用互参与者模型(全局化)和内参与者模型(个性化)的效果。

分类任务的设置

首先,我们需要加载分析所需的数据。在此评估中,我们使用“Accel_mag_all.csv”中的数据。我们使用pandas加载数据。请确保您已从https://10.5281/zenodo.7997850下载了此文件。

import pandas as pdfilename = "Accel_mag_all.csv"data = pd.read_csv(filename, header = None)

在开始分析之前,需要加载sktime和sklearn库中的一些函数:

from sktime.transformations.panel.rocket import Rocketfrom sklearn.pipeline import make_pipelinefrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import RidgeClassifierCV, LogisticRegression, LogisticRegressionCVfrom sklearn.model_selection import LeaveOneGroupOut

接下来,我们将标签和参与者编号分开。数据将以数组的形式表示。

import numpy as npX = data.iloc[:,2:].valuesy =  data[1].valuesparticipant_no =  data[0].values

对于这个任务,我们将使用Rocket转换和岭回归分类器。Rocket是一种用于时间序列分类的最先进技术[3]。Rocket通过生成随机卷积核,将这些卷积核沿着时间序列进行卷积以产生特征图。然后,在这个特征图上使用简单的线性分类器,如岭分类器。可以创建一个管道,先使用Rocket转换数据,标准化特征,最后使用岭分类器进行分类。

rocket_pipeline_ridge = make_pipeline(    Rocket(random_state=0),     StandardScaler(),     RidgeClassifierCV(alphas=np.logspace(-3, 3, 10)))

全球分类

在涉及多个参与者的应用中,将所有数据一起使用意味着一个人的数据可能同时出现在训练集和测试集中。为了避免这种情况,通常会进行一种被称为留一主题外(LOSO)分析的方法,即模型在除一个参与者之外的所有参与者上进行训练,并在留出的一个参与者上进行测试。这个过程会为每个参与者重复进行。这种方法可以测试模型在参与者之间的泛化能力。

logo = LeaveOneGroupOut()logo.get_n_splits(X, y, participant_no)Rocket_score_glob = []for i, (train_index, test_index) in enumerate(logo.split(X, y, participant_no)):    rocket_pipeline_ridge.fit(X[train_index], y[train_index])    Rocket_score = rocket_pipeline_ridge.score(X[test_index],y[test_index])    Rocket_score_glob = np.append(Rocket_score_glob, Rocket_score)

打印出上述结果的摘要:

print("全球模型结果")print(f"平均准确率: {np.mean(Rocket_score_glob)}")print(f"标准差: {np.std(Rocket_score_glob)}")print(f"最低准确率: {np.min(Rocket_score_glob)}")print(f"最高准确率: {np.max(Rocket_score_glob)}")

上述代码的输出结果为:

全球模型结果平均准确率: 0.5919805636306338标准差: 0.10360659996594646最低准确率: 0.4709480122324159最高准确率: 0.8283582089552238

这种LOSO分析的准确率明显较低,有些数据集的结果甚至与随机猜测相去甚远。这表明一位参与者的数据可能不太适用于另一位参与者。当处理个人感知数据时,这是一个常见的问题,因为运动技巧和整体生理状况在不同个体之间是不同的。此外,在这个应用中,一个人对疲劳的补偿方式可能与另一个人不同。让我们看看是否可以通过个性化模型来提高性能。

个性化分类

在构建个性化模型时,预测是基于个体的数据进行的。在将时间序列数据分成训练集和测试集时,应该以不打乱数据的方式进行。为此,我们将每个类别拆分为独立的训练集和测试集,以保持训练集和测试集中每个类别的比例,并保持数据的时间序列属性。我们使用运行时间的前三分之二的数据来训练模型,并在剩下的三分之一数据上进行预测。

Rocket_score_pers = []for i, (train_index, test_index) in enumerate(logo.split(X, y, participant_no)):        #print(f"Participant: {participant_no[test_index][0]}")    label = y[test_index]    X_S = X[test_index]        # Identify the indices for each class    class_0_indices = np.where(label == 'NF')[0]    class_1_indices = np.where(label == 'F')[0]        # Split each class into train and test using indexing    class_0_split_index = int(0.66 * len(class_0_indices))    class_1_split_index = int(0.66 * len(class_1_indices))    X_train = np.concatenate((X_S[class_0_indices[:class_0_split_index]], X_S[class_1_indices[:class_1_split_index]]), axis=0)    y_train = np.concatenate((label[class_0_indices[:class_0_split_index]], label[class_1_indices[:class_1_split_index]]), axis=0)        X_test = np.concatenate((X_S[class_0_indices[class_0_split_index:]],X_S[class_1_indices[class_1_split_index:]]), axis=0)    y_test = np.concatenate((label[class_0_indices[class_0_split_index:]], label[class_1_indices[class_1_split_index:]]), axis=0)        rocket_pipeline_ridge.fit(X_train, y_train)    Rocket_score_pers = np.append(Rocket_score_pers, rocket_pipeline_ridge.score(X_test,y_test))

如前所述,打印出上述结果的摘要:

print("个性化模型结果")
print(f"平均准确率:{np.mean(Rocket_score_pers)}")
print(f"标准差:{np.std(Rocket_score_pers)}")
print(f"最低准确率:{np.min(Rocket_score_pers)}")
print(f"最高准确率:{np.max(Rocket_score_pers)}")

以上代码输出:

个性化模型结果
平均准确率:0.9517626092184379
标准差:0.07750979452994386
最低准确率:0.7037037037037037
最高准确率:1.0

通过个性化模型的应用,性能得到了显著的提升。因此,在这个应用中,很明显从一个人推广到另一个人存在困难。

结论

为了对可穿戴传感器的时间序列数据进行分类,采用了最先进的技术Rocket。这个分析表明,在这个领域中,个性化模型能够更好地进行分类。

全局分类和个性化分类对每个参与者的准确率的影响

上图显示了使用个性化模型在性能上的显著提高,其中对于许多参与者,性能几乎翻倍。从一个人到另一个人的生理和跑步技术的差异可能对这种行为起到了贡献。从用户的角度来看,全局模型和个性化模型都有其优点,取决于具体应用。例如,在临床设置中需要监测个体用户的运动技术时,个性化模型可能会很有用。然而,收集足够的数据从单个个体进行准确预测可能是困难的,因此对于许多应用来说,全局模型更理想。

本教程中提供的代码也可以在GitHub上找到:https://github.com/bahavathyk/TSC_for_Fatigue_Detection

参考文献:

[1] B. Kathirgamanathan, T. Nguyen, G. Ifrim, B. Caulfield, P. Cunningham. Explaining Fatigue in Runners using Time Series Analysis on Wearable Sensor Data, XKDD 2023: 5th International Workshop on eXplainable Knowledge Discovery in Data Mining, ECML PKDD, 2023, http://xkdd2023.isti.cnr.it/papers/223.pdf

[2] B. Kathirgamanathan, B. Caulfield and P. Cunningham, “Towards Globalised Models for Exercise Classification using Inertial Measurement Units,” 2023 IEEE 19th International Conference on Body Sensor Networks (BSN), Boston, MA, USA, 2023, pp. 1–4, doi: 10.1109/BSN58485.2023.10331612.

[3] A. Dempster, F. Petitjean, and G. I.Webb. ROCKET: exceptionally fast and accurate time series classification using random convolutional kernels. Data Mining and Knowledge Discovery, 34(5):1454–1495, 2020.

Leave a Reply

Your email address will not be published. Required fields are marked *