共计 2241 个字符,预计需要花费 6 分钟才能阅读完成。
初识 CKD 数据集
慢性肾病 (CKD) 数据集记录了患者的关键生理指标与诊断结果,是早期肾病筛查和风险预测的重要依据。这类数据常包含缺失值、单位不统一等问题,且正负样本比例悬殊(健康人远多于患者),给建模带来双重挑战。医疗数据的特殊性还要求我们格外注意数据泄露问题,任何预处理步骤都必须在训练集上独立完成。
数据初探与清洗
原始数据通常长这样(模拟输出):
import pandas as pd
print(df_original.describe())
输出示例:
age bp sg ... pcv wbcc rbcc
count 350.0 348.0 324.0 ... 329.0 294.0 303.0
mean 51.5 76.5 1.0 ... 38.5 8400.0 4.7
std 17.1 13.1 0.0 ... 9.1 2900.0 0.8
min 2.0 50.0 1.0 ... 16.0 2200.0 2.1
25% 42.0 70.0 1.0 ... 32.0 6700.0 4.1
...
清洗后数据的对比:
print(df_cleaned.describe())
age bp sg ... pcv wbcc rbcc
count 400.0 400.0 400.0 ... 400.0 400.0 400.0
mean 51.2 76.7 1.0 ... 38.6 8370.0 4.7
std 16.9 12.8 0.0 ... 8.9 2850.0 0.8
min 2.0 50.0 1.0 ... 16.0 2200.0 2.1
25% 41.8 70.0 1.0 ... 32.0 6700.0 4.1
...
关键变化:
– 缺失值处理使所有特征样本量一致
– 血压 (bp) 单位统一为 mmHg
– 白细胞计数 (wbcc) 极端值被 Winsorize 处理
数据预处理实战
缺失值处理方案对比
from sklearn.impute import SimpleImputer, KNNImputer
# 方案 1:中位数填充
imputer_simple = SimpleImputer(strategy='median')
X_simple = imputer_simple.fit_transform(X_train)
# 方案 2:KNN 填充(更适合特征间有关联的数据)imputer_knn = KNNImputer(n_neighbors=5)
X_knn = imputer_knn.fit_transform(X_train)
建议:对于红细胞计数 (rbcc) 等实验室指标,KNN 效果通常更好
类别特征编码
from sklearn.preprocessing import OneHotEncoder, TargetEncoder
# 独热编码(增加维度但可解释性强)ohe = OneHotEncoder(sparse=False)
X_ohe = ohe.fit_transform(X_train[['rbc']])
# 目标编码(适合高基数特征)te = TargetEncoder()
X_te = te.fit_transform(X_train[['rbc']], y_train)
注意:目标编码必须仅在训练集上 fit!
数据标准化可视化
import matplotlib.pyplot as plt
plt.figure(figsize=(10,4))
plt.subplot(121)
plt.hist(X_train['wc'], bins=30, alpha=0.7)
plt.title('Before Scaling')
plt.subplot(122)
plt.hist(X_scaled['wc'], bins=30, color='orange', alpha=0.7)
plt.title('After Robust Scaling')
医疗数据推荐使用 RobustScaler,对异常值不敏感
模型构建与调优
XGBoost 基线模型
from xgboost import XGBClassifier
# 处理类别不平衡
model = XGBClassifier(scale_pos_weight=sum(y_train==0)/sum(y_train==1),
eval_metric='aucpr' # 医疗场景更关注精确率 - 召回率
)
model.fit(X_train, y_train)
特征重要性分析
import shap
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
shap.summary_plot(shap_values, X_test, plot_type='bar')
典型发现:血压 (bp)、血红蛋白(hg) 等特征贡献度最高
避坑指南
- 数据泄露防护
- 所有预处理器的 fit 只针对训练数据
- 验证集 / 测试集仅使用 transform
-
特别警惕目标编码、KNN 填充等操作
-
交叉验证要点
- 医疗数据建议使用 StratifiedKFold 保持类别比例
- 避免简单随机拆分导致某些 fold 无正样本
- 考虑按患者 ID 分组(防止同一患者数据出现在训练 / 测试集)
实践资源
扩展阅读:
–《医疗机器学习中的特征工程》
– XGBoost 官方文档的 scale_pos_weight 参数说明
– sklearn 文档中的 Pipeline 使用示例
写在最后
处理医疗数据就像给患者做体检——既要全面检查,又要特别小心操作规范。通过这次实践,最深刻的体会是:在数据预处理阶段花的时间,往往比调参带来的收益更大。下次遇到新数据集时,我会先花 1 小时仔细检查每个特征的分布和缺失情况,这比盲目跑模型要高效得多。
正文完
发表至: 未分类
近两天内

