2022年第十一届数学建模国际赛小美赛
C题 人类活动分类
原题再现:
人类行为理解的一个重要方面是对日常活动的识别和监控。可穿戴式活动识别系统可以改善许多关键领域的生活质量,如动态监测、家庭康复和跌倒检测。基于惯性传感器的活动识别系统用于通过个人报警系统对老年人进行远程监测和观察[1]、跌倒的检测和分类[2]、医疗诊断和治疗[3]、在家或学校远程监测儿童、康复和物理治疗、生物力学研究、人机工程学、体育科学、芭蕾舞和舞蹈、动画、,电影制作、电视、现场娱乐、虚拟现实和电脑游戏[4]。我们尝试利用微型惯性传感器和磁强计定位在人体不同部位对人体活动进行分类,得到以下数据。
19项活动中的每项活动由8名受试者(4名女性,4名男性,年龄在20至30岁之间)进行5分钟。每个受试者的每个活动的总信号持续时间为5分钟。受试者被要求以自己的方式进行活动,不受活动应如何进行的限制。由于这个原因,在某些活动的速度和幅度上存在着主体间的差异。
传感器单元经过校准,以在25 Hz采样频率下获取数据。将5分钟信号分为5秒段,以便为每个活动获得480(=60×8)个信号段。
这19项活动是:
1、坐(A1);
2、站立(A2);
3、仰卧(A3);
4、右侧卧(A4);
5、上行楼梯(A5);
6、下楼梯(A6);
7、站在电梯内静止(A7);
8、在电梯内走动(A8);
9、在停车场行走(A9);
10、在跑步机上以4 km/h的速度平卧、15度倾斜行走(A10);
11、以4 km/h的速度在跑步机上以15度倾斜位置行走(A11);
12、在跑步机上以8 km/h的速度运行(A12);
13、在步进机上运动(A13);
14、交叉训练器训练(A14);
15、在水平位置的健身车上骑车(A15);
16、在垂直位置的健身车上骑车(A16);
17、划船(A17);
18、跳跃(A18);
19、打篮球(A19)。
您的团队被要求开发一个合理的数学模型来解决以下问题。
1、请设计一套特征和高效算法,以便从这些穿戴式传感器的数据中对19种人体行为进行分类。
2、由于数据成本高,需要在有限的数据集上使模型具有良好的泛化能力。我们需要对这一问题进行具体的研究和评价。请设计一种可行的方法来评估模型的泛化能力。
3、请研究并克服过拟合问题,以便您的分类算法能够广泛应用于人的行为分类问题
可通过以下链接下载完整数据:
附件:文件结构
•19项活动(a)
•8名受试者(p)
•60段
•躯干(T)、右臂(RA)、左臂(LA)、右腿(RL)、左腿(LL)各5个单元
•每个装置上有9个传感器(x、y、z加速计、x、y、z陀螺仪、x、y、z磁强计)
文件夹a01,a02。。。,a19包含19项活动记录的数据。
对于每个活动,子文件夹p1、p2、...、。。。,p8包含8名受试者的数据。
在每个子文件夹中,有60个文本文件s01、s02、。。。,s60,每段一个。
在每个文本文件中,有5个单元×9个传感器=45列,5秒×25赫兹=125行。
每列包含在5秒内从其中一个单元的一个传感器获取的125个数据样本。
每行包含在特定采样瞬间从所有45个传感器轴获取的数据,数据之间用逗号分隔。
第1-45列对应于:
•T\u xacc、T\u yacc、T\u zacc、T\u xgyro。。。,T\u ymag,T\u zmag,
•RA\u xacc、RA\u yacc、RA\u zacc、RA\u xgyro等。。。,RA\u ymag,RA\u zmag,
•LA\u xacc、LA\u yacc、LA\u zacc、LA\u xgyro等。。。,LA\u ymag,LA\u zmag,
•RL\U xacc、RL\U yacc、RL\U zacc、RL\U xgyro等。。。,RL\U ymag、RL\U zmag、,
•LL\U xacc、LL\U yacc、LL\U zacc、LL\U xgyro等。。。,LL\u ymag,LL\u zmag。
因此,
•1-9列对应于1号机组(T)中的传感器,
•第10-18列对应于2号机组(RA)中的传感器,
•第19-27列对应于3号机组(LA)中的传感器,
•第28-36列对应于4号机组(RL)中的传感器,
•第37-45列对应于5号机组(LL)中的传感器。
整体求解过程概述(摘要)
人类活动分类在医疗保健、运动分析等领域发挥着重要作用,广泛应用于人们的日常生活中。本文采用Savitzky-Golay滤波器对九轴传感器数据进行去噪。在互补滤波姿态融合算法提取特征的基础上,设计了一种基于随机森林算法的两阶段粗-精多分类模型,用于人类活动的分类。
针对问题1,由于原始数据具有分散性和噪声性,首先将数据重组为三层,然后利用SG滤波器对数据进行去噪。然后对加速度计数据进行快速傅立叶变换,采用互补滤波方法对加速度计、磁强计和陀螺仪的数据进行积分,计算出相应的姿态角。加速度计数据对应人体平移,陀螺仪数据对应人体旋转,提取60个特征。考虑到人类活动的时间区域,进一步提取了60个特征的均值、标准差、偏度和峰度。对应不同的位置传感器,最终得到240维特征。最后,构建随机森林模型,对19种人类活动进行分类。
针对问题2,为了评价模型的泛化能力,将每个被试作为一个集合,通过划分不同比例的训练集和测试集训练19个分类随机森林模型,并利用混淆矩阵评价模型的准确性。结果表明,随着训练集所占比例的增加,总体准确率从44%提高到95%,但训练集的准确率远高于测试集的准确率,表明该模型泛化能力较差,存在过拟合问题,需要进一步优化。
针对问题3,为了解决过拟合问题,构建了基于随机森林算法的由粗到精的两阶段多分类模型。由于19个活动中的相邻活动具有明显的相关性特征,第一层将19个活动划分为8个类别,训练出8个类别的随机森林。第二层进一步为每个类别划分相应的活动。对8个亚类的随机森林进行训练,结果分为19类活动。结果表明,优化后的模型在各评价指标上均优于预优化模型,且训练集与测试集的精度差距较小,模型泛化能力较好,有效缓解了过拟合问题。
模型假设:
考虑到实际问题往往包含许多复杂的因素,首先需要做出合理的假设来简化模型,每个假设都紧跟着相应的解释:
假设1:使用五个位置传感器采集的数据,不考虑传感器之间的影响。
说明:针对不同的行为,考虑到人体不同部位的运动不一样,从5个位置传感器获取数据并提取特征,便于后续训练分类模型,不考虑传感器之间的影响。
假设2:考虑所有受试者佩戴同一传感器方向,不考虑不同传感器方向引起的数据差异。
说明:由于传感器的磨损方向不同,同一行为测量将获得不同的数据。我们认为所有的主体都朝着同一个方向。定义了坐标参考系和相应的传感器坐标系,简化了后续的数据融合计算过程。
假设3:数据误差只考虑陀螺的低频误差和加速度计、磁强计的高频误差,忽略了其他因素对误差的影响。
说明:为了简化数据融合的计算过程,我们只考虑由三个传感器特性引起的数据误差。事实上,这种误差是最主要的,其他因素引起的误差可以忽略不计。
假设4:假设通过提取采样点时间数据的时域特征可以反映人类活动。
说明:考虑到检测到的人类活动数据处于一段时间内,且每个时间采样点的数据都有噪声影响,为了反映此类活动的整体数据分布特征,考虑可以提取时域特征来反映。
问题重述:
问题重述
通过传感器了解人类行为是一个非常复杂的过程。通过对问题背景的深入分析和研究,结合给出的具体约束条件,可以将问题的重述表述如下:
•根据每个单元上九个传感器收集的不同数据,设定一套标准来评估人体行为。在此基础上,设计了一种算法,根据测量数据对19种不同的人类行为进行分类。
•对于问题1中设计的算法,需要选择新的数据来测试其适应性,测试算法是否能找到隐藏在数据背后的规律,测试训练后的网络是否也能以相同的规律对学习集之外的数据给出适当的输出,以及是否具有较强的泛化能力。
•当模型本身过于复杂时,会同时拟合训练样本集中的噪声,使得算法在训练集上表现良好,而在测试集上表现不佳,泛化性能较差。我们需要采用适当的方法来克服这一问题,使该算法能够得到广泛的应用。
我们的工作
该问题要求我们设计一套能够对传感器数据中的19种人类活动进行分类的特征集和高效算法,进而评估模型的泛化能力和克服过拟合问题。我们的工作主要包括:
1、针对原始数据的分散性和噪声性,将整理后的数据分为三层,采用Savitzky-Golay滤波器对数据进行去噪处理。
2、对加速度计数据进行FFT变换,采用互补滤波的方法对三个传感器的数据进行融合,计算出相应的姿态角,结合加速度和角速度,提取60个特征,进一步提取60个特征的时域特征。
3、构建了随机森林分类模型,采用不同比例的训练集和测试集对模型进行训练。模型的识别结果用混淆矩阵表示,发现模型的泛化能力较差。
4、为了解决模型的过拟合问题,进一步构建了两阶段随机森林分类模型,先粗分类后细分类,发现模型的分类精度得到了显著提高。
模型的建立与求解整体论文缩略图
全部论文请见下方" 只会建模 QQ名片" 点击QQ名片即可
部分程序代码:(代码和文档not free)
python
cv_params = {'n_estimators': [5,10,15,20,25,30,35]}
other_params = {'learning_rate': 0.1, 'n_estimators': 500, 'max_depth':
5, 'min_child_weight': 1, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha':
0, 'reg_lambda': 1}
model = xgb.XGBClassifier(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params,
scoring='accuracy', cv=5, verbose=0, n_jobs=-1)
optimized_GBM.fit(X_train, y_train)
evalute_result = optimized_GBM.cv_results_
print('result:{0}'.format(evalute_result))
print('best score:'.format(optimized_GBM.best_score_))
cv_params = {'max_depth': [1,2,3, 4, 5, 6, 7, 8, 9, 10],
'min_child_weight': [1, 2, 3, 4, 5, 6]}
other_params = {'learning_rate': 0.1, 'n_estimators': 25, 'max_depth':
5, 'min_child_weight': 1, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha':
0, 'reg_lambda': 1}
model = xgb.XGBClassifier(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params,
scoring='accuracy', cv=5, verbose=0, n_jobs=-1)
optimized_GBM.fit(X_train, y_train)
evalute_result = optimized_GBM.cv_results_
print('result:{0}'.format(evalute_result))
print('best score:{0}'.format(optimized_GBM.best_score_))
cv_params = {'reg_alpha': [0,0.05, 0.1, 1, 2, 3], 'reg_lambda': [0,
0.05, 0.1, 1, 2, 3]}
other_params = {'learning_rate': 0.1, 'n_estimators': 15, 'max_depth':
2, 'min_child_weight': 1, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha':
0, 'reg_lambda':0.05}
model = xgb.XGBClassifier(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params,
scoring='accuracy', cv=4, verbose=0, n_jobs=-1)
optimized_GBM.fit(X_train, y_train)
evalute_result = optimized_GBM.cv_results_
print('result:{0}'.format(evalute_result))
print('best score:{0}'.format(optimized_GBM.best_score_))
cv_params = {'learning_rate': [0.01, 0.05, 0.07, 0.1, 0.2,0.3,0.4,0.5]}
other_params = {'learning_rate': 0.1, 'n_estimators': 25, 'max_depth':
3, 'min_child_weight': 2, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha':
0, 'reg_lambda':0.05}
model = xgb.XGBClassifier(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params,
scoring='accuracy', cv=4, verbose=0, n_jobs=-1)
optimized_GBM.fit(X_train, y_train)
evalute_result = optimized_GBM.cv_results_
print('result:{0}'.format(evalute_result))
print('best score:{0}'.format(optimized_GBM.best_score_))
python
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(dataSet, test_size=0.25,
random_state=42)
X_train = [x[0:720] for x in train_set]
y_train = [x[720] for x in train_set]
X_test = [x[0:720] for x in test_set]
y_test = [x[720] for x in test_set]
Xgb_train = xgb.DMatrix(X_train,y_train)
Xgb_test = xgb.DMatrix(X_test,y_test)
#%%
params =
{'objective':'multi:softmax','num_class':19,'booster':'gbtree','max_depth':5,
'eta':0.1, 'subsample':0.7, 'colsample_bytree':0.7}
num_round = 200
watchlist = [(Xgb_train,'train'), (Xgb_test,'test')]
model=xgb.train(params,Xgb_train,num_round,watchlist)
y_pred = model.predict(Xgb_test)
import matplotlib.pyplot as plt
plt.ylim(0,3)
plt.plot(train_mlogloss_, label='train_mlogloss')
plt.plot(test_mlogloss_, label='test_mlogloss')
plt.xlabel( 'epoch')
plt.ylabel( 'mlogloss')
plt.title('Loss chart')
plt.legend()
plt.savefig('E:\Machine Learning\ICM\pic\\loss_.jpg',dpi=600)
plt.show()
rom sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(dataSet_, test_size=0.25,
random_state=41)
X_train = [x[0:18] for x in train_set]
y_train = [x[18] for x in train_set]
X_test = [x[0:18] for x in test_set]
y_test = [x[18] for x in test_set]
Xgb_train = xgb.DMatrix(X_train,y_train)
Xgb_test = xgb.DMatrix(X_test,y_test)
params = {'objective':'multi:softmax','num_class':19,'booster':'gbtree'}
num_round = 200
watchlist = [(Xgb_train,'train'), (Xgb_test,'test')]
model=xgb.train(params,Xgb_train,num_round,watchlist)
y_pred = model.predict(Xgb_test)