K-means 聚类在肺炎患者分型中的应用(简单示例)
临床上肺炎有多种类型(比如细菌性、病毒性、支原体性),症状和治疗方案差异很大。我们可以用 K-means 根据患者的几个关键指标自动分组,帮助医生快速判断类型。
完整代码
import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler import pandas as pd # 1. 生成模拟的肺炎患者数据(3个关键指标) # 特征说明: # 体温(℃)、白细胞计数(×10⁹/L)、咳嗽持续天数 np.random.seed(42) # 固定随机数,结果可重复 # 三种肺炎类型的典型数据(中心值) centers = [ [38.5, 15, 5], # 细菌性肺炎:中高热、白细胞高、咳嗽中等时间 [39.2, 8, 3], # 病毒性肺炎:高热、白细胞正常、咳嗽时间短 [37.8, 10, 10] # 支原体肺炎:低热、白细胞略高、咳嗽时间长 ] # 生成150个患者数据(加一点波动模拟个体差异) n_samples = 50 # 每种类型50人 X = [] for center in centers: # 给每个中心值加随机波动(模拟真实数据的差异) cluster = np.random.normal(loc=center, scale=[0.3, 2, 1.5], size=(n_samples, 3)) X.append(cluster) X = np.vstack(X) # 合并成一个数组 # 2. 数据标准化(消除单位影响) scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 每个特征变成均值0、标准差1 # 3. 用K-means聚类(已知有3种类型,直接设k=3) kmeans = KMeans(n_clusters=3, random_state=42) clusters = kmeans.fit_predict(X_scaled) # 得到每个患者的聚类结果 # 4. 可视化聚类结果(用前两个特征画图,简单直观) plt.figure(figsize=(10, 6)) colors = ['red', 'green', 'blue'] # 三种聚类用三种颜色 labels = ['细菌性肺炎', '病毒性肺炎', '支原体肺炎'] # 推测的类型 for i in range(3): # 提取第i类患者的数据 cluster_data = X[clusters == i] # 画散点图(x轴:体温,y轴:白细胞) plt.scatter(cluster_data[:, 0], cluster_data[:, 1], c=colors[i], label=labels[i], alpha=0.7) # 标记聚类中心(转回原始单位) centers_original = scaler.inverse_transform(kmeans.cluster_centers_) plt.scatter(centers_original[:, 0], centers_original[:, 1], c='black', marker='*', s=200, label='中心值') plt.xlabel('体温(℃)') plt.ylabel('白细胞计数(×10⁹/L)') plt.title('K-means聚类:肺炎患者分型') plt.legend() plt.grid(alpha=0.3) plt.show() # 5. 输出每种类型的特征总结(方便医生参考) print("聚类结果分析:") features = ['体温(℃)', '白细胞计数(×10⁹/L)', '咳嗽持续天数'] for i in range(3): cluster_data = X[clusters == i] print(f"\n类型{i+1}({len(cluster_data)}人):") for j, feature in enumerate(features): print(f" {feature}:{np.mean(cluster_data[:, j]):.1f}") |
K-means 肺炎患者分型代码详细分析
这段代码通过 K-means 聚类算法对肺炎患者进行自动分型,帮助理解不同类型肺炎的特征差异。下面我们逐部分解析代码的功能和意义:
一、基础库导入
import numpy as np # 用于数值计算和数组操作 import matplotlib.pyplot as plt # 用于数据可视化 from sklearn.cluster import KMeans # 导入K-means聚类算法 from sklearn.preprocessing import StandardScaler # 用于数据标准化 import pandas as pd # 用于数据处理(本示例中未充分使用) |
这些是数据科学领域的常用库,sklearn(scikit-learn)提供了成熟的机器学习算法实现。
二、模拟数据生成
2.1 随机种子设置
np.random.seed(42) # 固定随机数种子,确保每次运行结果完全一致 |
这一步是为了让实验可重复,每次运行代码都会得到相同的随机数据。
2.2 定义肺炎类型中心值
centers = [ [38.5, 15, 5], # 细菌性肺炎:中高热、白细胞高、咳嗽中等时间 [39.2, 8, 3], # 病毒性肺炎:高热、白细胞正常、咳嗽时间短 [37.8, 10, 10] # 支原体肺炎:低热、白细胞略高、咳嗽时间长 ] |
这里定义了三种肺炎的典型特征
- 特征 1:体温(℃)
- 特征 2:白细胞计数(×10⁹/L)
- 特征 3:咳嗽持续天数
这些中心值基于医学常识:细菌性肺炎常伴随白细胞升高,病毒性肺炎多为高热,支原体肺炎咳嗽时间较长。
2.3 生成带波动的患者数据
n_samples = 50 # 每种类型50人 X = [] for center in centers: # 生成符合正态分布的随机数据,围绕中心值波动 cluster = np.random.normal( loc=center, # 中心值(均值) scale=[0.3, 2, 1.5], # 各特征的波动幅度(标准差) size=(n_samples, 3) # 生成50行3列的数据 ) X.append(cluster) X = np.vstack(X) # 合并成一个150×3的数组(150个患者,3个特征) |
这段代码模拟了真实世界的患者数据:
- 每个特征都围绕 "典型值" 有一定波动(比如体温波动 ±0.3℃)
- 不同特征的波动幅度不同(白细胞计数波动更大)
- 最终生成 150 个患者的完整数据集
三、数据预处理:标准化
scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 每个特征变成均值0、标准差1 |
标准化的核心作用:
- 消除不同特征的单位和数值范围差异(比如体温是 37-40,白细胞是 5-20)
- 让三个特征在聚类时 "权重相等",避免数值大的特征(如白细胞)主导聚类结果
- 标准化公式:新值 = (原始值 - 特征均值) / 特征标准差
四、K-means 聚类实现
kmeans = KMeans(n_clusters=3, random_state=42) # 创建K-means模型,指定3个聚类 clusters = kmeans.fit_predict(X_scaled) # 拟合模型并得到每个样本的聚类标签 |
- n_clusters=3:根据医学知识,我们已知肺炎主要分 3 种类型
- fit_predict():返回一个长度为 150 的数组,每个元素是 0、1 或 2(表示该患者属于第 0/1/2 类)
五、聚类结果可视化
5.1 绘图设置
plt.figure(figsize=(10, 6)) # 设置图表大小 colors = ['red', 'green', 'blue'] # 三种聚类用三种颜色 labels = ['细菌性肺炎', '病毒性肺炎', '支原体肺炎'] # 推测的类型 |
5.2 绘制散点图
for i in range(3): # 提取第i类患者的原始数据(非标准化) cluster_data = X[clusters == i] # 绘制散点图:x轴为体温,y轴为白细胞计数 plt.scatter( cluster_data[:, 0], # 取第0列:体温 cluster_data[:, 1], # 取第1列:白细胞 c=colors[i], # 点的颜色 label=labels[i], # 图例标签 alpha=0.7 # 点的透明度(避免重叠看不清) ) |
这里用原始数据绘图(而非标准化后的数据),是为了让医生能直观理解数值(比如体温 38℃而不是 0.5)。
5.3 标记聚类中心
# 将标准化后的聚类中心转回原始数据范围 centers_original = scaler.inverse_transform(kmeans.cluster_centers_) # 绘制聚类中心(黑色星号) plt.scatter( centers_original[:, 0], # 中心的体温值 centers_original[:, 1], # 中心的白细胞值 c='black', marker='*', # 星号标记 s=200, # 点的大小 label='中心值' ) |
聚类中心代表了每类患者的 "典型特征",转回原始单位后更具临床意义。
5.4 完善图表
plt.xlabel('体温(℃)') # x轴标签 plt.ylabel('白细胞计数(×10⁹/L)') # y轴标签 plt.title('K-means聚类:肺炎患者分型') # 图表标题 plt.legend() # 显示图例 plt.grid(alpha=0.3) # 显示网格线(透明度0.3) plt.show() # 显示图表 |
六、聚类结果统计分析
print("聚类结果分析:") features = ['体温(℃)', '白细胞计数(×10⁹/L)', '咳嗽持续天数'] for i in range(3): # 提取第i类患者的所有数据 cluster_data = X[clusters == i] # 输出该类患者的数量 print(f"\n类型{i+1}({len(cluster_data)}人):") # 输出每个特征的平均值 for j, feature in enumerate(features): print(f" {feature}:{np.mean(cluster_data[:, j]):.1f}") |
这段代码计算并输出每类患者的特征平均值,方便医生快速掌握各类肺炎的典型特征:
- 细菌性肺炎:白细胞计数较高(~15×10⁹/L)
- 病毒性肺炎:体温最高(~39℃)
- 支原体肺炎:咳嗽时间最长(~10 天)
七、代码的实际意义
- 辅助诊断:帮助医生根据基础指标快速判断肺炎类型,尤其是在检测条件有限的基层医院
- 治疗指导:不同类型肺炎治疗方案不同(细菌性用抗生素,病毒性可能用抗病毒药)
- 算法验证:聚类结果与医学常识高度吻合,说明 K-means 能有效发现数据中的模式
通过这个例子可以看到,聚类算法能从临床数据中自动发现规律,为医疗决策提供数据支持。