Logo
Section 1 / 6

医疗领域的机器学习:诊断与治疗

探索机器学习在医疗保健领域的应用实现。

导入

医疗领域的机器学习:诊断与治疗

探索机器学习在医疗保健领域的应用实现。

1import numpy as np 2import pandas as pd 3import matplotlib.pyplot as plt 4from sklearn.preprocessing import StandardScaler 5from sklearn.model_selection import train_test_split, cross_val_score, StratifiedKFold 6from sklearn.ensemble import RandomForestClassifier 7from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc 8from sklearn.pipeline import Pipeline 9 10 11class MedicalDiagnosisPredictor: 12 def __init__(self): 13 """ 14 初始化医疗诊断预测器 15 16 模拟的医疗特征: 17 1. 年龄 18 2. 血压 19 3. 胆固醇水平 20 4. 血糖 21 5. 身体质量指数(BMI) 22 6. 家族病史 23 7. 吸烟状况 24 """ 25 # 设置随机种子以确保结果可复现 26 np.random.seed(42) 27 28 def generate_synthetic_medical_data(self, num_samples=1000): 29 """ 30 生成合成医疗数据集 31 32 数据生成策略: 33 - 模拟真实医疗特征的分布 34 - 创建具有相关性的特征 35 - 引入可控的疾病发生概率 36 """ 37 # 生成年龄(均值为45,标准差为15的正态分布) 38 age = np.random.normal(45, 15, num_samples) 39 age = np.clip(age, 18, 90) # 将年龄限制在18到90岁之间 40 41 # 生成血压(收缩压,正态分布) 42 blood_pressure = np.random.normal(120, 15, num_samples) 43 blood_pressure = np.clip(blood_pressure, 90, 180) # 限制在合理范围内 44 45 # 生成胆固醇水平 46 cholesterol = np.random.normal(200, 30, num_samples) 47 cholesterol = np.clip(cholesterol, 120, 300) 48 49 # 生成血糖水平 50 blood_sugar = np.random.normal(100, 20, num_samples) 51 blood_sugar = np.clip(blood_sugar, 70, 200) 52 53 # 生成BMI值 54 bmi = np.random.normal(25, 5, num_samples) 55 bmi = np.clip(bmi, 16, 45) 56 57 # 生成家族病史(二元变量:0或1) 58 family_history = np.random.binomial(1, 0.3, num_samples) 59 60 # 生成吸烟状态(二元变量:0或1) 61 smoking_status = np.random.binomial(1, 0.25, num_samples) 62 63 # 构建数据框 64 df = pd.DataFrame({ 65 'Age': age, 66 'BloodPressure': blood_pressure, 67 'Cholesterol': cholesterol, 68 'BloodSugar': blood_sugar, 69 'BMI': bmi, 70 'FamilyHistory': family_history, 71 'SmokingStatus': smoking_status 72 }) 73 74 # 生成目标变量(疾病风险) 75 # 风险随年龄、血压、胆固醇、血糖、BMI升高而增加 76 # 有家族病史或吸烟也会提高风险 77 probabilities = ( 78 0.1 * ((df['Age'] - 18) / (90 - 18)) + 79 0.15 * ((df['BloodPressure'] - 90) / (180 - 90)) + 80 0.15 * ((df['Cholesterol'] - 120) / (300 - 120)) + 81 0.15 * ((df['BloodSugar'] - 70) / (200 - 70)) + 82 0.15 * ((df['BMI'] - 16) / (45 - 16)) + 83 0.15 * df['FamilyHistory'] + 84 0.15 * df['SmokingStatus'] 85 ) 86 87 # 将概率归一化至[0, 1]区间 88 probabilities = (probabilities - probabilities.min()) / (probabilities.max() - probabilities.min()) 89 90 # 生成疾病风险标签(1 = 高风险,0 = 低风险) 91 df['DiseaseRisk'] = np.random.binomial(1, probabilities, num_samples) 92 93 return df 94 95 96 def preprocess_data(self, df): 97 """ 98 数据预处理:分离特征与目标变量 99 """ 100 # 分离特征和目标变量 101 X = df.drop('DiseaseRisk', axis=1) 102 y = df['DiseaseRisk'] 103 104 # 划分训练集和测试集 105 X_train, X_test, y_train, y_test = train_test_split( 106 X, y, test_size=0.2, random_state=42, stratify=y 107 ) 108 109 return X_train, X_test, y_train, y_test 110 111 112 def build_model(self, X_train, y_train): 113 """ 114 构建并训练随机森林分类器 115 """ 116 # 创建仅包含分类器的流水线(随机森林无需特征缩放) 117 pipeline = Pipeline([ 118 ('classifier', RandomForestClassifier(n_estimators=100, random_state=42)) 119 ]) 120 121 # 训练模型 122 pipeline.fit(X_train, y_train) 123 124 # 创建分层K折交叉验证 125 stratified_cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) 126 127 # 执行分层交叉验证 128 cv_scores = cross_val_score(pipeline, X_train, y_train, cv=stratified_cv, scoring='accuracy') 129 130 print(f"交叉验证得分: {cv_scores}") 131 print(f"平均交叉验证得分: {cv_scores.mean():.4f}") 132 133 return pipeline 134 135 136 def evaluate_model(self, model, X_test, y_test): 137 """ 138 使用多种指标评估模型性能 139 """ 140 # 进行预测 141 y_pred = model.predict(X_test) 142 y_prob = model.predict_proba(X_test)[:, 1] 143 144 # 输出分类报告 145 print("\n分类报告:") 146 print(classification_report(y_test, y_pred)) 147 148 # 绘制混淆矩阵(使用Matplotlib) 149 plt.figure(figsize=(10, 8)) 150 cm = confusion_matrix(y_test, y_pred) 151 152 # 使用Matplotlib绘制热力图 153 plt.imshow(cm, interpolation='nearest', cmap='Blues') 154 plt.title('混淆矩阵') 155 plt.colorbar() 156 157 # 添加文本标注 158 for i in range(cm.shape[0]): 159 for j in range(cm.shape[1]): 160 plt.text(j, i, format(cm[i, j], 'd'), ha='center', va='center', color='black') 161 162 # 设置坐标轴标签 163 plt.xticks(np.arange(len(set(y_test))), labels=[str(label) for label in set(y_test)], rotation=45) 164 plt.yticks(np.arange(len(set(y_test))), labels=[str(label) for label in set(y_test)]) 165 plt.ylabel('真实标签') 166 plt.xlabel('预测标签') 167 plt.tight_layout() 168 plt.show() 169 170 # 绘制ROC曲线 171 plt.figure(figsize=(10, 8)) 172 fpr, tpr, _ = roc_curve(y_test, y_prob) 173 roc_auc = auc(fpr, tpr) 174 175 plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC曲线 (AUC = {roc_auc:.2f})') 176 plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') # 对角线 177 plt.xlim([0.0, 1.0]) 178 plt.ylim([0.0, 1.05]) 179 plt.xlabel('假阳性率') 180 plt.ylabel('真阳性率') 181 plt.title('受试者工作特征(ROC)曲线') 182 plt.legend(loc="lower right") 183 plt.show() 184 185 # 绘制特征重要性(假设model['classifier']支持该属性) 186 if hasattr(model['classifier'], 'feature_importances_'): 187 importances = model['classifier'].feature_importances_ 188 feature_names = X_test.columns 189 190 plt.figure(figsize=(10, 8)) 191 indices = np.argsort(importances)[::-1] 192 plt.title('特征重要性') 193 plt.barh(range(len(indices)), importances[indices], align='center') 194 plt.yticks(range(len(indices)), [feature_names[i] for i in indices]) 195 plt.xlabel('相对重要性') 196 plt.tight_layout() 197 plt.show() 198 199 200 def run_workflow(self): 201 """ 202 执行完整的工作流程 203 """ 204 # 生成数据 205 print("正在生成合成医疗数据...") 206 df = self.generate_synthetic_medical_data(num_samples=1000) 207 print(f"数据集形状: {df.shape}") 208 print("\n样本数据:") 209 print(df.head()) 210 211 # 数据预处理 212 print("\n正在预处理数据...") 213 X_train, X_test, y_train, y_test = self.preprocess_data(df) 214 215 # 构建并训练模型 216 print("\n正在构建并训练模型...") 217 model = self.build_model(X_train, y_train) 218 219 # 评估模型性能 220 print("\n正在评估模型性能...") 221 self.evaluate_model(model, X_test, y_test) 222 223 return model, df 224 225 226# 运行工作流程 227if __name__ == "__main__": 228 predictor = MedicalDiagnosisPredictor() 229 model, data = predictor.run_workflow()

高级机器学习概念

金融领域的机器学习:欺诈检测