K-means 聚类在肺炎患者分型中的应用(简单示例)

发布于:2025-07-16 ⋅ 阅读:(32) ⋅ 点赞:(0)

        临床上肺炎有多种类型(比如细菌性、病毒性、支原体性),症状和治疗方案差异很大。我们可以用 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. 特征 1:体温(℃)
  2. 特征 2:白细胞计数(×10⁹/L)
  3. 特征 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)   # 生成503列的数据

    )

    X.append(cluster)

X = np.vstack(X)  # 合并成一个150×3的数组(150个患者,3个特征)

这段代码模拟了真实世界的患者数据:

  1. 每个特征都围绕 "典型值" 有一定波动(比如体温波动 ±0.3℃)
  2. 不同特征的波动幅度不同(白细胞计数波动更大)
  3. 最终生成 150 个患者的完整数据集

三、数据预处理:标准化

scaler = StandardScaler()

X_scaled = scaler.fit_transform(X)  # 每个特征变成均值0、标准差1

标准化的核心作用

  1. 消除不同特征的单位和数值范围差异(比如体温是 37-40,白细胞是 5-20)
  2. 让三个特征在聚类时 "权重相等",避免数值大的特征(如白细胞)主导聚类结果
  3. 标准化公式:新值 = (原始值 - 特征均值) / 特征标准差

四、K-means 聚类实现

kmeans = KMeans(n_clusters=3, random_state=42)  # 创建K-means模型,指定3个聚类

clusters = kmeans.fit_predict(X_scaled)  # 拟合模型并得到每个样本的聚类标签

  1. n_clusters=3:根据医学知识,我们已知肺炎主要分 3 种类型
  2. 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}")

这段代码计算并输出每类患者的特征平均值,方便医生快速掌握各类肺炎的典型特征:

  1. 细菌性肺炎:白细胞计数较高(~15×10⁹/L)
  2. 病毒性肺炎:体温最高(~39℃)
  3. 支原体肺炎:咳嗽时间最长(~10 天)

七、代码的实际意义

  1. 辅助诊断:帮助医生根据基础指标快速判断肺炎类型,尤其是在检测条件有限的基层医院
  2. 治疗指导:不同类型肺炎治疗方案不同(细菌性用抗生素,病毒性可能用抗病毒药)
  3. 算法验证:聚类结果与医学常识高度吻合,说明 K-means 能有效发现数据中的模式

通过这个例子可以看到,聚类算法能从临床数据中自动发现规律,为医疗决策提供数据支持。


网站公告

今日签到

点亮在社区的每一天
去签到