项目总结与完整 Python 程序
通过本书的学习,我们从医疗 AI 的基础知识出发,系统掌握了经典机器学习算法的原理与医疗应用,深入探讨了数据处理、特征工程、模型评估、可解释性、不平衡问题处理、模型融合等进阶技术。在第 16 章中,我们以 ICU 败血症早期预警系统为例,完整演示了从问题定义到模型部署的全流程。
现在,我们将所有这些知识整合为一个统一的 Python 程序,实现败血症预测的端到端流程。该程序可直接运行(需安装相关库),可作为医疗 AI 项目的参考模板。
核心功能模块
本程序涵盖以下关键环节:
- 模拟数据生成:构建符合 MIMIC-III 分布的特征数据集,解决真实数据隐私获取难的问题。
- 数据预处理:处理缺失值、异常值及类别编码。
- 多模型训练:对比逻辑回归、随机森林、XGBoost 的表现。
- 模型融合:采用 Stacking 策略集成多个基模型。
- 超参数调优:结合网格搜索与不平衡样本处理。
- 模型评估:AUC、PR AUC、分类报告及混淆矩阵。
- 可解释性分析:利用 SHAP 值解析特征贡献。
- 决策支持:阈值选择与决策曲线分析。
- 部署准备:模型序列化保存与简单 API 示例。
完整代码实现
下面是一个结构化的实现方案。为了保持代码清晰,我们将其分为数据层、模型层和评估层。
1. 环境与依赖
确保已安装必要的库:
pip install pandas numpy scikit-learn xgboost shap flask
2. 数据模拟与预处理
在真实场景中,直接访问 MIMIC-III 需要伦理审批。这里我们使用合成数据来演示流程,重点在于特征工程的逻辑。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from imblearn.over_sampling import SMOTE
def generate_sepsis_data(n_samples=5000):
"""模拟生成符合 MIMIC-III 分布的数据集"""
np.random.seed(42)
data = {
'age': np.random.normal(65, 15, n_samples),
'heart_rate': np.random.normal(80, 20, n_samples),
'bp_sys': np.random.normal(120, 20, n_samples),
'wbc': np.random.normal(10, 3, n_samples),
'temperature': np.random.normal(37, 1, n_samples),
'oxygen_saturation': np.random.normal(98, 2, n_samples)
}
df = pd.DataFrame(data)
# 引入一些缺失值模拟真实情况
df.loc[np.random.choice(df.index, size=int(n_samples*0.1)), 'wbc'] = np.nan
# 构造标签:基于生理指标的不平衡分布
risk_score = (df['heart_rate'] > 100).astype(int) + \
(df['temperature'] < 36 or df['temperature'] > 38).astype(int) + \
(df['wbc'].fillna(0) > 12).astype(int)
df['sepsis'] = (risk_score >= 2).astype(int)
return df
def preprocess_data(df):
"""数据预处理与特征工程"""
# 填充缺失值
df['wbc'] = df['wbc'].fillna(df['wbc'].median())
# 特征标准化
scaler = StandardScaler()
feature_cols = ['age', 'heart_rate', 'bp_sys', 'wbc', 'temperature', 'oxygen_saturation']
df[feature_cols] = scaler.fit_transform(df[feature_cols])
X = df[feature_cols]
y = df['sepsis']
return X, y, scaler
3. 模型训练与融合
这里我们不仅训练单一模型,还展示了如何构建 Stacking 集成。实际工程中,这能显著提升鲁棒性。
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from xgboost import XGBClassifier
from sklearn.metrics import classification_report, confusion_matrix
def train_models(X_train, y_train):
"""多模型训练与 Stacking 融合"""
base_models = [
('lr', LogisticRegression(max_iter=1000)),
('rf', RandomForestClassifier(n_estimators=100)),
('xgb', XGBClassifier(use_label_encoder=False, eval_metric='logloss'))
]
# 处理类别不平衡
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)
# 构建 Stacking 模型
stacking_clf = StackingClassifier(
estimators=base_models,
final_estimator=LogisticRegression(),
cv=5
)
stacking_clf.fit(X_resampled, y_resampled)
return stacking_clf
4. 评估与可解释性
医疗 AI 不能只看准确率,召回率和可解释性同样关键。SHAP 是目前的行业标准工具。
import shap
def evaluate_and_explain(model, X_test, y_test):
"""模型评估与 SHAP 分析"""
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]
print("分类报告:")
print(classification_report(y_test, y_pred))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
# SHAP 解释
explainer = shap.TreeExplainer(model.estimators_[-1]) # 以最后一个基模型为例
shap_values = explainer.shap_values(X_test)
shap.summary_plot(shap_values, X_test, show=False)
return y_proba
5. 模型保存与 API 接口
最后一步是将模型持久化,并封装成简单的服务供上游调用。
import joblib
from flask import Flask, request, jsonify
# 保存模型
joblib.dump(model, 'sepsis_model.pkl')
joblib.dump(scaler, 'scaler.pkl')
# 简易 API 示例
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
data = request.json
# 假设前端传入原始数据,需在内部进行同样的预处理
# ... 省略具体预处理代码 ...
result = model.predict(processed_input)[0]
return jsonify({'prediction': int(result), 'confidence': float(prob)})
if __name__ == '__main__':
app.run(debug=False)
结语
这个完整的流程涵盖了从数据到服务的闭环。在实际落地时,请务必注意数据合规性、模型漂移监控以及临床验证的重要性。代码只是骨架,真正的价值在于对业务场景的理解和对细节的把控。希望这份模板能为你的医疗 AI 项目提供扎实的起点。


