2025年泰迪杯B题完整代码分享+问题一二三结果展示

泰迪杯作为数据挖掘挑战赛,本届竞赛提供了三个大数据类型题目,其中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左右,提升了十倍的计算效率

计算结果如下所示

ID

TotalTime

SleepTime

HighIntensityTime

ModerateIntensityTime

LowIntensityTime

StaticActivityTime

P001

24.7159

10.5833

0

3.7303

3.0009

7.4013

P002

16.1406

6.25

0.3567

1.1702

1.8108

6.5529

P003

20.5242

6.6667

0

6.7723

2.7376

4.3476

P004

18.9362

6.5

0

2.5809

3.1359

6.7194

P005

17.0661

4.3333

0

1.8884

3.9005

6.9439

P006

15.8555

4.0833

0

2.2976

3.5885

5.8861

P007

21.0392

8.25

0.4209

0.4161

5.0036

6.9486

P008

18.0499

6.6667

0.0461

1.9845

2.0668

7.2858

P009

8.5696

6

0

0.238

0.3069

2.0247

P010

18.6444

9.3333

0

1.9

5.4168

1.9942

P011

13.6566

6.1667

0

0.295

1.0817

6.1132

% 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 次

问题二,构建身体活动 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等评估指标来衡量模型预测精度【时间宽裕、机器允许理论上可以使用多模型精度对比,择优选择】

对于该问题,我们选择随机森林进行预测展示,主要分为三部

数据合并+模型训练+模型预测

import pandas as pd
import numpy as np
import os  用于创建文件夹
from tqdm import tqdm  导入tqdm进度条

文件路径
metadata_path = r'G:\1\B-全部数据\附件1\Metadata1.csv'
file_dir = r'G:\1\B-全部数据\附件1'  数据文件夹路径

输出目录路径
output_dir = r'G:\1\B-全部数据\附件1\result_2'

# 1. 检查并创建输出目录(如果不存在)
if not os.path.exists(output_dir):
    os.makedirs(output_dir)  创建目录

# 2. 读取Metadata1.csv文件,提取ID、性别、年龄信息
metadata = pd.read_csv(metadata_path)
metadata = metadata[['pid''age''sex']]  提取所需的列

# 3. 初始化合并后的数据框
all_data = pd.DataFrame()

# 4. 获取所有文件名(P001P100file_paths = [os.path.join(file_dir, f'P{i:03d}.csv'for in range(1101)]

# 5. 使用tqdm显示进度条
for file_path in tqdm(file_paths, desc="合并文件进度"unit="文件"ncols=100):
    # 6. 读取加速度数据文件,强制指定'time'列为字符串类型
    df = pd.read_csv(file_path, dtype={'time'str}, low_memory=False)

    # 7. 提取MET值(从annotation列中提取MET值)
    df['MET'] = df['annotation'].str.extract(r'MET (\d+\.\d+)').astype(float)  提取MET值并转为数字

    # 8. 合并志愿者ID、性别、年龄信息
    volunteer_id = file_path.split('\\')[-1].split('.')[0]  从文件名提取志愿者ID(如P001    volunteer_metadata = metadata[metadata['pid'] == volunteer_id].iloc[0]
    df['ID'] = volunteer_id
    df['Sex'] = volunteer_metadata['sex']
    df['Age'] = volunteer_metadata['age']

import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import joblib  用于模型保存和加载

# 1. 加载训练数据
train_data_path = r'G:\1\B-全部数据\附件3\result_2\merged_data.csv'
df = pd.read_csv(train_data_path)

# 2. 编码性别和年龄
df = df.dropna(subset=['MET'])  保证没有空值
le_sex = LabelEncoder()
le_age = LabelEncoder()
df['Sex'] = le_sex.fit_transform(df['Sex'])
df['Age'] = le_age.fit_transform(df['Age'])

# 3. 特征和标签
features = ['Sex''Age''x''y''z']
X = df[features]
y = df['MET']

# 4. 训练模型
model = RandomForestRegressor(n_estimators=100random_state=42)
model.fit(X, y)

import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import joblib  用于模型保存和加载

model = joblib.load('met_model.pkl')
le_sex = joblib.load('le_sex.pkl')
le_age = joblib.load('le_age.pkl')

# === 输入文件信息 ===
file_path = r'G:\1\B-全部数据\附件2\P101.csv'
pid = 'P1021'
age = '38-52'
sex = 'F'

# === 读取加速度数据 ===
df_test = pd.read_csv(file_path, dtype={'time'str})
df_test['Sex'] = le_sex.transform([sex])[0]
df_test['Age'] = le_age.transform([age])[0]

# === 构造特征矩阵 ===
df_test['Sex'] = df_test['Sex']
df_test['Age'] = df_test['Age']
X_test = df_test[['Sex''Age''x''y''z']]

# === 预测 MET  ===
df_test['MET_Pred'] = model.predict(X_test)

问题三,基于加速度计数据的睡眠阶段智能识别

具体问题设计并实现一个算法,该算法能够根据个体的加速度计数据,准确识别和分析个体的睡眠阶段及睡眠状态,为改善睡眠质量提供科学依据。

该部分首先使用类似于聚类分析模型对睡眠模式进行分类,根据加速度模长的变化趋势和预定义的阈值,识别睡眠阶段(如快速眼动期、深度睡眠期、浅睡眠期等)。

通过Kmeans初步进行聚类分析 得到结果如下所示

志愿者ID

睡眠总时长(小时)

睡眠模式一总时长(小时)

睡眠模式二总时长(小时)

睡眠模式三总时长(小时)

P101

7.5

0.2799

5.7886

1.4315

P102

6.5

1.0896

3.3584

2.052

P103

9.85

2.7317

4.3758

2.7425

P104

8.0833

1.0929

3.5192

3.4712

问题四,基于加速度计数据的久坐行为健康预警

具体问题:基于附件 1 文件夹中 100 位志愿者的加速度计数据及对应的活动行为,自动识别久坐行为状态,并在适当的时候发出预警,帮助用户了解和改善自己的活动习惯。

设置静态行为的阈值(<1.0MET < 1.6),并结合时间段(每次静态行为超过30分钟则认为是久坐)。对每位志愿者的加速度数据进行久坐行为检测。

问题三四仅由于还未开始实践、仅为初步思路,后续会根据实际求解过程进行完善。

图片

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值