用Python构建居民健康画像:从问卷数据到SVM分类实战

当健康管理遇上机器学习,数据科学正在重新定义我们对个体健康的理解方式。想象一下,通过一份简单的问卷数据,就能预测一个人的慢性病风险,并为其量身定制健康建议——这正是数学建模竞赛中深圳杯A题试图解决的问题,也是医疗健康领域数据应用的典型场景。本文将带你用Python完整复现这一过程,从原始问卷清洗到SVM模型构建,最终生成可解释的健康分类报告。

1. 健康数据分析的基础准备

1.1 环境配置与数据加载

健康数据分析的第一步是搭建合适的Python环境。推荐使用Anaconda创建独立环境,避免包版本冲突:

conda create -n health_analysis python=3.8
conda activate health_analysis
pip install pandas scikit-learn matplotlib seaborn

加载数据时,需要特别注意医疗数据的特殊性。原始问卷通常包含大量分类变量和缺失值:

import pandas as pd

# 加载原始问卷数据
raw_data = pd.read_excel('health_survey.xlsx', sheet_name='A2')

# 显示数据结构概览
print(f"数据集维度:{raw_data.shape}")
print("前5行样本:\n", raw_data.head())

典型健康问卷数据包含以下字段类型:

  • 人口统计学特征 :年龄、性别、职业等
  • 生活习惯指标 :吸烟频率、饮酒量、运动时长
  • 饮食记录 :各类食物摄入频率
  • 健康结局 :慢性病诊断结果

1.2 数据清洗与特征工程

医疗数据清洗需要遵循特殊原则。例如,对于"每周饮酒次数"这样的敏感问题,缺失值可能意味着被调查者不愿透露而非数据收集错误:

# 处理缺失值的策略示例
def clean_medical_data(df):
    # 连续变量用中位数填充
    num_cols = ['age', 'exercise_hours']
    df[num_cols] = df[num_cols].fillna(df[num_cols].median())
    
    # 分类变量新增'unknown'类别
    cat_cols = ['smoking_status', 'drinking_freq']
    df[cat_cols] = df[cat_cols].fillna('unknown')
    
    return df

cleaned_data = clean_medical_data(raw_data)

特征工程阶段需要将医学知识编码到特征中。例如,根据膳食指南将原始饮食记录转化为营养评分:

# 饮食健康评分计算示例
def calculate_diet_score(row):
    score = 0
    # 蔬菜水果摄入
    if row['vegetable_freq'] >= 5: score += 2
    elif row['vegetable_freq'] >= 3: score += 1
    
    # 红肉摄入控制
    if row['redmeat_freq'] <= 2: score += 1
    
    return score

cleaned_data['diet_score'] = cleaned_data.apply(calculate_diet_score, axis=1)

2. 探索性分析与可视化

2.1 健康指标分布分析

使用Seaborn绘制关键健康指标的分布图,可以直观发现人群健康趋势:

import seaborn as sns
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
sns.boxplot(x='health_status', y='age', data=cleaned_data)
plt.title('不同健康状况人群的年龄分布')
plt.show()

常见健康数据模式包括:

  • 年龄相关性 :慢性病患病率随年龄增长而上升
  • 性别差异 :男性吸烟率通常高于女性
  • 职业影响 :久坐职业人群运动量普遍不足

2.2 特征相关性热力图

计算Spearman相关系数(适用于有序分类变量)并可视化:

# 选择数值型特征计算相关性
numeric_cols = ['age', 'bmi', 'exercise_hours', 'diet_score']
corr_matrix = cleaned_data[numeric_cols].corr(method='spearman')

plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('健康特征相关性热力图')
plt.show()

提示:医疗数据相关性分析需谨慎解读,相关不等于因果。建议结合临床知识验证统计发现。

3. 构建SVM健康分类模型

3.1 数据预处理与划分

将分类变量转换为机器学习模型可处理的数值形式:

from sklearn.preprocessing import OrdinalEncoder
from sklearn.model_selection import train_test_split

# 定义分类变量编码规则
cat_cols = ['smoking_status', 'drinking_freq']
encoder = OrdinalEncoder(categories=[['never', 'occasional', 'regular', 'heavy', 'unknown']]*2)
cleaned_data[cat_cols] = encoder.fit_transform(cleaned_data[cat_cols])

# 划分特征和目标变量
X = cleaned_data.drop('health_status', axis=1)
y = cleaned_data['health_status']

# 数据集划分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42)

3.2 SVM模型训练与调优

使用网格搜索寻找最优核函数和正则化参数:

from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
    'C': [0.1, 1, 10],
    'kernel': ['linear', 'rbf'],
    'gamma': ['scale', 'auto']
}

# 创建并训练模型
svm_model = GridSearchCV(SVC(probability=True), param_grid, cv=5)
svm_model.fit(X_train, y_train)

# 输出最佳参数
print(f"最佳参数组合:{svm_model.best_params_}")
print(f"交叉验证准确率:{svm_model.best_score_:.3f}")

3.3 模型评估与解释

医疗模型评估需特别关注对少数类(如患病群体)的识别能力:

from sklearn.metrics import classification_report, confusion_matrix

# 测试集预测
y_pred = svm_model.predict(X_test)

# 输出分类报告
print(classification_report(y_test, y_pred))

# 绘制混淆矩阵
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.show()

关键评估指标解读:

  • 召回率(Recall) :正确识别出的实际患者比例
  • 精确率(Precision) :预测为患者中真正患病的比例
  • F1分数 :召回率和精确率的调和平均

4. 健康画像生成与应用

4.1 居民健康分类策略

基于SVM预测概率进行精细化分类:

# 获取预测概率
probs = svm_model.predict_proba(X_test)[:, 1]

# 定义风险等级阈值
low_risk = probs < 0.3
medium_risk = (probs >= 0.3) & (probs < 0.7)
high_risk = probs >= 0.7

# 统计各风险人群比例
print(f"低风险人群占比:{low_risk.mean():.1%}")
print(f"中风险人群占比:{medium_risk.mean():.1%}")
print(f"高风险人群占比:{high_risk.mean():.1%}")

4.2 个性化健康建议生成

为不同风险群体生成针对性的健康建议模板:

def generate_health_recommendation(row):
    if row['risk_level'] == 'high':
        return f"""尊敬的{row['age']}岁{row['gender']}性:
        根据分析,您患慢性病的风险较高。建议:
        1. 立即戒烟限酒
        2. 每周至少150分钟中等强度运动
        3. 增加蔬菜水果摄入至每日500g"""
    elif row['risk_level'] == 'medium':
        return "..."
    else:
        return "..."

# 应用建议生成函数
health_report = test_data.apply(generate_health_recommendation, axis=1)

4.3 模型部署与持续学习

将训练好的模型封装为可复用管道:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

# 创建完整管道
health_pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('svm', SVC(C=1, kernel='rbf', gamma='scale', probability=True))
])

# 保存模型到文件
import joblib
joblib.dump(health_pipe, 'health_risk_predictor.pkl')

在实际应用中,模型需要定期用新数据重新训练以保持预测准确性。建议设置自动化retraining流程,当数据分布变化超过阈值时触发模型更新。

更多推荐