泰迪杯作为数据挖掘挑战赛,本届竞赛提供了三个大数据类型题目,其中AC都涉及文本处理以及智能问答系统,需要选手对这方面有一定了解才好上手。因此,B题数据分析处理就作为了大多数选手的选择。本文将为大家带来详细的B题解题思路,并尽可能为大家找到小技巧,可以规避大规模计算的。
基于穿戴装备的身体活动监测
作为大数据竞赛,首先第一步就是进行数据清洗工作,需要对给出的数据进行。对于本题目,由于涉及数据量过大,我们下面以P001为例进行说明。
数据清洗主要包含缺失值直接使用python【】或matlab【】自带函数查找。对于异常值可以分为阈值处理或者模型处理。
功能 | Python | MATLAB |
判断单个值是否为NaN | pd.isna(val) / np.isnan(val) | isnan(val) |
判断数组中位置 | df.isna() / df.isnull() | isnan(A) |
筛选含缺失值的行 | df[df.isna().any(axis=1)] | A(any(isnan(A),2), :) |
Python代码 | Matlab代码 |
import pandas as pd # 1. 读取数据 file_path = r'G:\1\B题-全部数据\附件1\P001.csv' df = pd.read_csv(file_path) # 2. 显示缺失值统计 print("每列缺失值数量:") print(df.isnull().sum()) # 3. 删除包含缺失值的行 df_cleaned = df.dropna() # 4. 输出处理结果 print(f"\n原始数据行数: {len(df)}") print(f"删除缺失值后的数据行数: {len(df_cleaned)}") print(f"共删除了 {len(df) - len(df_cleaned)} 行含缺失值的数据。") | % 1. 读取数据 filePath = 'G:\1\B题-全部数据\附件1\P001.csv'; data = readtable(filePath); % 2. 显示每列缺失值数量 disp('每列缺失值数量:'); disp(sum(ismissing(data))); % 3. 删除含缺失值的行 data_cleaned = rmmissing(data); % 4. 输出行数对比 originalRows = height(data); cleanedRows = height(data_cleaned); fprintf('\n原始数据行数: %d\n', originalRows); fprintf('删除缺失值后的数据行数: %d\n', cleanedRows); fprintf('共删除了 %d 行缺失值数据。\n', originalRows - cleanedRows); |
阈值处理:查阅文献,找到理论存在X Y Z方向加速度最大值,将该值设定为阈值超过该数据的认定为异常数据,方便起见直接删除处理。下表来自网络收集仅供参考
传感器量程 | 最大可记录加速度(每轴) |
±2g | 约 ±2 × 9.8 = ±19.6 m/s² |
±4g | 约 ±4 × 9.8 = ±39.2 m/s² |
±8g | 约 ±8 × 9.8 = ±78.4 m/s² |
±16g | 约 ±16 × 9.8 = ±156.8 m/s² |
模型处理:首先对X Y Z方向加速度进行分布方式检验,不同的分布方式对应不同的检验模型。正态分布数据使用3σ原则判定,非正态分布使用箱线图判定,将部分边缘值判定为异常值。(运行时间长、可以误判,不是太推荐)
下面进行每个问题详细的解题
问题一,统计分析志愿者的活动情况
具体问题:根据加速度记录数据,统计汇总附件1中各个志愿者的身体活动信息,数值保留小数点后4位。记录总时长(小时)睡眠总时长(小时)高等强度运动总时长(小时)中等强度运动总时长(小时)低等强度运动总时长(小时)静态活动总时长(小时)。
对于问题一单纯的进行统计分析即可,难度在于我们需要对100个1G左右文件分别进行分析,并存储于结果表格,我自己写了其中一个的记录代码,大家可以自行尝试,单一文件运行时间为10min+【13th Gen Intel(R) Core(TM) i7-13700HX 2.10 GHz 32.0 GB】
因此,本问题通过对数据分析发现,同一秒内记录次数为100次,我们可以单独计算不同活动类型以及出现的次数,计算频数以及利用频数计算时间长度,就可以有效规避大量无用计算。
单一文件计算时间为100s左右,提升了十倍的计算效率
% 3. 计算不同活动类型
unique_annotations = unique(annotations); % 获取不同类型的活动
num_annotations = length(unique_annotations); % 活动类型数量
类型名称 | 出现次数 |
7030 sleeping;MET 0.95 | 3810002 次 |
home activity;eating;13030 eating sitting alone or with someone;MET 1.5 | 74004 次 |
home activity;household chores;preparing meals/cooking/washing dishes;5035 kitchen activity general cooking/washing/dishes/cleaning up;MET 3.3 | 954511 次 |
home activity;miscellaneous;sitting;11580 office work such as writing and typing (with or without eating at the same time);MET 1.5 | 144105 次 |
home activity;miscellaneous;sitting;9055 sitting/lying talking in person/using a mobile phone/smartphone/tablet or talking on the phone/computer (skype chatting);MET 1.5 | 308709 次 |
home activity;miscellaneous;sitting;9060 sitting/lying reading or without observable/identifiable activities;MET 1.3 | 338112 次 |
home activity;miscellaneous;standing;9050 standing talking in person on the phone/computer (skype chatting) or using a mobileo phone/smartphone/tablet;MET 1.8 | 7501 次 |
home activity;miscellaneous;standing;9050 standing talking in person/on the phone/computer (skype chatting) or using a mobile phone/smartphone/tablet;MET 1.8 | 49103 次 |
以下为单一文件运行时间为10min+仅供参考
% 读取数据
data = readtable('G:\1\B题-全部数据\附件1\P001.csv');
% 转换时间格式
data.time = datetime(data.time, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
% 计算时间差
time_diff = [0; seconds(diff(data.time))]; % 相邻时间戳的时间差(秒)
% 设置时间差阈值,超出该阈值的时间认为是无效时间段
time_threshold = 300; % 假设超过300秒的时间差认为是无效
% 筛选出有效的时间差(小于阈值的时间段)
valid_time_diff = time_diff(time_diff <= time_threshold);
% 提取MET值
MET_values = extractMETValues(data.annotation);
% 检查MET值的分布
disp('MET Values Summary:');
disp(['High Intensity Count (MET >= 6.0): ', num2str(sum(MET_values >= 6.0))]);
disp(['Moderate Intensity Count (3.0 <= MET < 6.0): ', num2str(sum(MET_values >= 3.0 & MET_values < 6.0))]);
disp(['Low Intensity Count (1.6 <= MET < 3.0): ', num2str(sum(MET_values >= 1.6 & MET_values < 3.0))]);
disp(['Sleep Count (MET < 1.0): ', num2str(sum(MET_values < 1.0))]);
% 计算每个活动的时长(只计算有效时间段)
[high_intensity, moderate_intensity, low_intensity, static_activity, sleep] = categorizeActivity(MET_values, valid_time_diff);
% 统计总时长(单位为小时)
total_duration = sum(valid_time_diff) / 3600; % 总时长,单位:小时
% 获取志愿者ID
volunteer_id = 'P001'; % 当前示例为P001,实际中可以根据需要循环处理多个志愿者
% 构建结果表格
result = table({volunteer_id}, total_duration, sleep / 3600, high_intensity / 3600, moderate_intensity / 3600, low_intensity / 3600, static_activity / 3600, ...
'VariableNames', {'VolunteerID', 'TotalDuration', 'SleepDuration', 'HighIntensityDuration', 'ModerateIntensityDuration', 'LowIntensityDuration', 'StaticActivityDuration'});
% 保存为 Excel 文件
writetable(result, 'result_1.xlsx', 'WriteRowNames', true);
%% 辅助函数:提取MET值
function MET_values = extractMETValues(annotations)
MET_values = NaN(height(annotations), 1);
for i = 1:height(annotations)
% 匹配MET值
expr = 'MET (\d+\.\d+)'; % 查找MET后的浮动数值
tokens = regexp(annotations{i}, expr, 'tokens');
if ~isempty(tokens)
MET_values(i) = str2double(tokens{1}{1});
else
MET_values(i) = NaN; % 如果没有找到MET值,设置为NaN
end
end
end
%% 辅助函数:根据MET值分类活动
function [high, moderate, low, static, sleep] = categorizeActivity(MET_values, valid_time_diff)
% 处理NaN值,确保分类时不会出错
MET_values(isnan(MET_values)) = 0; % 将NaN值转为0(不计入任何活动)
% 根据MET值分类活动,直接加和有效时间差
high = sum(MET_values >= 6.0 .* valid_time_diff); % 直接加和有效时间段
moderate = sum((MET_values >= 3.0 & MET_values < 6.0) .* valid_time_diff);
low = sum((MET_values >= 1.6 & MET_values < 3.0) .* valid_time_diff);
static = sum((MET_values >= 1.0 & MET_values < 1.6) .* valid_time_diff);
sleep = sum(MET_values < 1.0 .* valid_time_diff);
end
问题二,构建身体活动 MET 值估计模型
根据附件 1 中 100 位志愿者的性别、年龄及时间与加速度计数据,构建一个机器学习模型,实现实时估计个体在某个时间段内的 MET 值。
MET=F(Y,X,T,x,y,z)
具体问题1:对附件 2 中 20 位志愿者的性别、年龄信息及时间与加速度计数据进行 MET 值预测。
具体问题2:将 20 位志愿者的 MET 值预测结果进行整理,统计汇总各个志愿者的运动强度信息,数值保留小数点后 4 位。
第二小问类似于问题一的步骤直接使用相同的代码改变文件名、路径就可以实现,本节主要针对问题二第一小问进行讲解。
训练数据问题:由于将附件1全部数据合并数量级过于庞大,可以进行随即采样,每个样本仅随机选取100000行数据,大概10MB左右数据集,进行训练。代码跑通后可尝试增加训练数据集。
模型问题:大家可以参考文末的我整理的预测模型大纲,理论上任何一个都是可以求解该题目,差别在于预测精度。下面我们以最简单易懂的回归模型为例进行说明【实际代码使用模型可能会更复杂一些,以增加预测精度】
1、数据处理:加速度数据和志愿者的年龄、性别信息进行整理合并
2、构建输入特征:加速度的统计特征、性别、年龄等。
3、构建目标变量:每个时间段对应的MET值
4、模型选择:使用回归模型(如线性回归、随机森林回归或支持向量机回归等)来预测MET值。
5、精度检验:使用MSE、RMSE、MAE等评估指标来衡量模型预测精度【时间宽裕、机器允许理论上可以使用多模型精度对比,择优选择】
问题三,基于加速度计数据的睡眠阶段智能识别
具体问题:设计并实现一个算法,该算法能够根据个体的加速度计数据,准确识别和分析个体的睡眠阶段及睡眠状态,为改善睡眠质量提供科学依据。
该部分首先使用类似于聚类分析模型对睡眠模式进行分类,根据加速度模长的变化趋势和预定义的阈值,识别睡眠阶段(如快速眼动期、深度睡眠期、浅睡眠期等)。
通过机器学习(如K-means聚类、随机森林等)对睡眠模式进行分类
问题四,基于加速度计数据的久坐行为健康预警
具体问题:基于附件 1 文件夹中 100 位志愿者的加速度计数据及对应的活动行为,自动识别久坐行为状态,并在适当的时候发出预警,帮助用户了解和改善自己的活动习惯。
设置静态行为的阈值(<1.0MET < 1.6),并结合时间段(每次静态行为超过30分钟则认为是久坐)。对每位志愿者的加速度数据进行久坐行为检测。
问题三四仅由于还未开始实践、仅为初步思路,后续会根据实际求解过程进行完善。