2025亚太中文赛项 B题疾病的预测与大数据分析保姆级教程思路分析
2025亚太中文赛项 B题保姆级教程思路分析
DS数模-亚太中文赛项赛 B题保姆级教程思路分析
B题 疾病的预测与大数据分析
下面我将以背景介绍、数据集分析、问题分析的步骤来给大家讲解B题的具体思路。
1 背景介绍
- 本题基于2025年APMCM数学建模竞赛B题,聚焦于心血管疾病(CVD)、中风和肝硬化三种重大疾病的预测与预防分析。背景核心包括:
- 疾病危害性
- 心血管疾病是全球第一大死因(占全球死亡31%),中风为第二大死因(占11%),肝硬化则是晚期肝病的严重后果。
- 目标导向
国家卫健委提出医疗质量安全改进目标,要求通过数据分析实现疾病的早期发现和管理。 - 任务要求
需利用提供的三个临床数据集(heart.csv、stroke.csv、cirrhosis.csv)完成:
- 数据预处理与统计分析(问题1)
- 构建疾病预测模型(问题2)
- 分析多疾病关联风险(问题3)
- 提出WHO预防建议(问题4)
这里需要注意几点:
- 数据集包含结构化临床指标(如年龄、性别、生化指标等),部分含缺失值(如NA)。
- 需关注特征间的相关性(如胆固醇、血压与心血管疾病)和潜在混杂因素。
- 多病关联:需挖掘共同风险因子(如高血压、糖尿病)和共病概率计算。
- 模型可解释性(WHO建议需基于明确依据)
2 数据集分析
题目给了这几个数据源:
数据集深度解析与预处理方案:
1 心脏病数据集 (heart.csv)
字段分析:
字段列表 = [
"Age", "Sex", "ChestPainType", "RestingBP", "Cholesterol",
"FastingBS", "RestingECG", "MaxHR", "ExerciseAngina",
"Oldpeak", "ST_Slope", "HeartDisease"
]
预处理:
import pandas as pd
import numpy as np
# 读取数据
heart_df = pd.read_csv("heart.csv")
# 1. 缺失值处理
heart_df["Cholesterol"] = heart_df["Cholesterol"].replace(0, np.nan) # 0值视为缺失
heart_df["Cholesterol"] = heart_df["Cholesterol"].fillna(heart_df["Cholesterol"].median())
# 2. 异常值处理
Q1 = heart_df["RestingBP"].quantile(0.25)
Q3 = heart_df["RestingBP"].quantile(0.75)
IQR = Q3 - Q1
heart_df = heart_df[~((heart_df["RestingBP"] < (Q1 - 1.5 * IQR)) |
(heart_df["RestingBP"] > (Q3 + 1.5 * IQR)))]
# 3. 特征编码
heart_df = pd.get_dummies(heart_df, columns=["Sex", "ChestPainType", "RestingECG", "ST_Slope", "ExerciseAngina"])
# 4. 标准化数值特征
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
num_features = ["Age", "RestingBP", "Cholesterol", "MaxHR", "Oldpeak"]
heart_df[num_features] = scaler.fit_transform(heart_df[num_features])
2. 中风数据集 (stroke.csv)
字段分析:
字段列表 = [
"id", "gender", "age", "hypertension", "heart_disease", "ever_married",
"work_type", "Residence_type", "avg_glucose_level", "bmi",
"smoking_status", "stroke"
]
预处理:
# 读取数据
stroke_df = pd.read_csv("stroke.csv")
# 1. 缺失值处理
stroke_df["bmi"] = stroke_df["bmi"].fillna(stroke_df["bmi"].median())
# 2. 异常值处理
stroke_df = stroke_df[stroke_df["age"] <= 100] # 过滤异常年龄
stroke_df = stroke_df[stroke_df["bmi"].between(15, 50)] # BMI合理范围
# 3. 特征工程
# 创建年龄分段特征
stroke_df["age_group"] = pd.cut(stroke_df["age"],
bins=[0, 30, 50, 70, 100],
labels=["<30", "30-50", "50-70", "70+"])
# 4. 编码分类变量
cat_cols = ["gender", "ever_married", "work_type", "Residence_type", "smoking_status", "age_group"]
stroke_df = pd.get_dummies(stroke_df, columns=cat_cols)
# 5. 处理高基数特征
from sklearn.feature_extraction import FeatureHasher
fh = FeatureHasher(n_features=5, input_type="string")
hashed_features = fh.transform(stroke_df["work_type"].astype(str))
stroke_df[["work_hash1", "work_hash2", "work_hash3", "work_hash4", "work_hash5"]] = pd.DataFrame(hashed_features.toarray())
3. 肝硬化数据集 (cirrhosis.csv)
字段分析:
字段列表 = [
"ID", "N_Days", "Status", "Drug", "Age", "Sex", "Ascites", "Hepatomegaly",
"Spiders", "Edema", "Bilirubin", "Cholesterol", "Albumin", "Copper",
"Alk_Phos", "SGOT", "Tryglicerides", "Platelets", "Prothrombin", "Stage"
]
预处理:
# 读取数据
cirrhosis_df = pd.read_csv("cirrhosis.csv")
# 1. 缺失值处理
# 对生化指标使用KNN填充
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
bio_features = ["Bilirubin", "Cholesterol", "Albumin", "Copper", "Alk_Phos", "SGOT", "Tryglicerides", "Platelets"]
cirrhosis_df[bio_features] = imputer.fit_transform(cirrhosis_df[bio_features])
# 2. 处理分类变量
binary_cols = ["Sex", "Ascites", "Hepatomegaly", "Spiders", "Edema"]
cirrhosis_df[binary_cols] = cirrhosis_df[binary_cols].map({"Y":1, "N":0, "S":0.5})
# 3. 时间特征转换
# 将生存时间转换为年
cirrhosis_df["Years"] = cirrhosis_df["N_Days"] / 365.25
# 4. 创建复合指标
cirrhosis_df["MELD_Score"] = 3.78*np.log(cirrhosis_df["Bilirubin"]) + 11.2*np.log(cirrhosis_df["Prothrombin"]) + 9.57*np.log(cirrhosis_df["Creatinine"]) + 6.43
推荐可视化方法及Python代码模板
特征分布直方图(数值型变量)
import matplotlib.pyplot as plt
import seaborn as sns
def plot_numeric_dist(df, feature, bins=30):
plt.figure(figsize=(10, 6))
sns.histplot(data=df, x=feature, kde=True, bins=bins)
plt.title(f'Distribution of {feature}')
plt.xlabel(feature)
plt.ylabel('Frequency')
plt.show()
# 示例:心脏病数据集中的年龄分布
# plot_numeric_dist(heart_df, 'Age')
多变量关系散点图矩阵
def plot_scatter_matrix(df, features):
sns.pairplot(df[features], diag_kind='kde')
plt.suptitle('Scatter Matrix of Selected Features', y=1.02)
plt.show()
# 示例:心脏病数据集关键特征关系
# features = ['Age', 'RestingBP', 'Cholesterol', 'MaxHR', 'HeartDisease']
# plot_scatter_matrix(heart_df, features)
3 问题分析
问题1:数据预处理与基础统计分析详细建模过程
建模过程:
1. 数据清洗与预处理
核心任务:处理缺失值、异常值、数据转换
2. 探索性数据分析(EDA)
核心任务:理解数据分布、特征关系
3. 统计建模与因素分析
核心任务:识别影响患病概率的关键因素
推荐算法:
- 逻辑回归(可解释性强)
- 随机森林(特征重要性分析)
- XGBoost(高性能预测)
4. 结果解释与可视化
def visualize_results(result_df):
# 特征重要性比较
plt.figure(figsize=(12, 8))
result_df = result_df.sort_values('RF_Importance', ascending=False).head(10)
plt.barh(result_df['Feature'], result_df['RF_Importance'], color='skyblue')
plt.xlabel('Feature Importance')
plt.title('Top 10 Important Features (Random Forest)')
plt.gca().invert_yaxis()
plt.show()
# 逻辑回归系数可视化
plt.figure(figsize=(12, 8))
result_df = result_df.sort_values('LR_Odds_Ratio', ascending=False).head(10)
plt.barh(result_df['Feature'], result_df['LR_Odds_Ratio'], color='salmon')
plt.xlabel('Odds Ratio')
plt.title('Top 10 Risk Factors (Logistic Regression)')
plt.gca().invert_yaxis()
plt.show()
# 多模型比较
fig, ax = plt.subplots(figsize=(14, 8))
result_df = result_df.sort_values('RF_Importance', ascending=False).head(10)
width = 0.25
x = np.arange(len(result_df['Feature']))
ax.bar(x - width, result_df['RF_Importance'], width, label='Random Forest')
ax.bar(x, result_df['XGB_Importance'], width, label='XGBoost')
ax.bar(x + width, result_df['LR_Odds_Ratio']/result_df['LR_Odds_Ratio'].max(),
width, label='Logistic Regression (Scaled)')
ax.set_ylabel('Importance/Effect')
ax.set_title('Feature Importance Comparison')
ax.set_xticks(x)
ax.set_xticklabels(result_df['Feature'], rotation=45, ha='right')
ax.legend()
plt.tight_layout()
plt.show()
建模流程总结
- 数据清洗:处理缺失值、异常值、分类变量编码
- 探索性分析:分布可视化、相关性分析
- 统计建模:
- 逻辑回归:识别风险因素(OR值)
- 随机森林:特征重要性排序
- XGBoost:高性能验证
- 结果解释:多模型比较可视化,识别关键影响因素
其中更详细的思路、各题目思路、代码、讲解视频、成品论文及其他相关内容,可以看下方卡片获取!