当前位置: 首页 > news >正文

从病人分组到用户分群:利用二元变量相似度矩阵做聚类的完整流程(Sklearn实战)

从病人分组到用户分群:二元变量相似度矩阵的聚类实战指南

在医疗健康领域,医生常常需要根据患者的症状、检查结果等特征将病人分成不同的亚组,以便制定个性化的治疗方案。同样,在商业分析中,市场人员也希望通过用户的购买行为、浏览记录等特征进行客户细分。这两种看似不同的场景,背后都依赖于同一种核心技术——基于二元变量的聚类分析。

本文将带您深入探索如何利用Python的Sklearn库,从原始二元数据出发,构建样本间相似度矩阵,最终实现有业务意义的群体划分。不同于普通的教程,我们会重点讨论在实际业务场景中如何选择相似度计算方法(Jaccard系数vs简单匹配系数),以及如何解读聚类结果。无论您是医疗领域的研究人员还是商业数据分析师,都能从中获得可直接复用的代码和思路。

1. 二元变量聚类的基础准备

1.1 理解二元变量特性

二元变量(Binary Variable)是数据挖掘中最基础却又最容易被误用的数据类型之一。它只有两个取值:1(表示"存在"或"是")和0(表示"不存在"或"否")。在实际应用中,二元变量可以表示:

  • 医疗场景:患者是否发烧(1/0)、检测结果是否阳性(1/0)
  • 电商场景:用户是否购买过某类商品(1/0)、是否点击过广告(1/0)

关键区别在于对称与非对称二元变量

# 对称二元变量示例:性别(男女权重相同) symmetrical_vars = ['性别_男', '性别_女'] # 非对称二元变量示例:罕见病诊断(得病=1更重要) asymmetrical_vars = ['糖尿病', '高血压']

1.2 数据预处理实战

原始数据通常需要转换为适合聚类的二元矩阵形式。以下是一个典型的数据转换过程:

import pandas as pd from sklearn.preprocessing import LabelEncoder # 原始患者数据示例 data = { '患者ID': ['P001', 'P002', 'P003'], '发烧': ['是', '否', '是'], '咳嗽': ['否', '是', '否'], '检测1': ['阳性', '阴性', '阳性'] } df = pd.DataFrame(data) # 转换为二元变量 binary_df = pd.get_dummies(df, columns=['发烧', '咳嗽', '检测1'], drop_first=True) print(binary_df)

输出结果:

患者ID 发烧_是 咳嗽_是 检测1_阳性 0 P001 1 0 1 1 P002 0 1 0 2 P003 1 0 1

2. 相似度矩阵构建的艺术

2.1 选择合适的相似度度量

相似度计算是聚类的核心,对于二元变量,最常用的两种方法是:

度量方法公式适用场景特点
简单匹配系数(a+d)/(a+b+c+d)对称二元变量考虑0-0匹配
Jaccard系数a/(a+b+c)非对称二元变量忽略0-0匹配

其中:

  • a:两个样本都为1的特征数
  • b:样本i为1而j为0的特征数
  • c:样本i为0而j为1的特征数
  • d:两个样本都为0的特征数

医疗场景示例

from sklearn.metrics import jaccard_score # 患者症状数据 p1 = [1, 0, 1] # 发烧=是, 咳嗽=否, 检测=阳性 p2 = [1, 1, 0] # 发烧=是, 咳嗽=是, 检测=阴性 # 计算Jaccard相似度(适用于非对称变量如疾病诊断) similarity = jaccard_score(p1, p2) print(f"Jaccard相似度: {similarity:.2f}")

2.2 构建完整的相似度矩阵

实际分析中,我们需要计算所有样本两两之间的相似度:

from sklearn.metrics.pairwise import pairwise_distances import numpy as np # 示例患者数据矩阵(行代表患者,列代表症状/检测结果) patients = np.array([ [1, 0, 1], # 患者1 [1, 1, 0], # 患者2 [0, 1, 0] # 患者3 ]) # 计算不相似度矩阵(1 - Jaccard相似度) dissimilarity_matrix = pairwise_distances(patients, metric='jaccard') print("患者间不相似度矩阵:") print(dissimilarity_matrix)

输出结果:

患者间不相似度矩阵: [[0. 0.66666667 1. ] [0.66666667 0. 0.5 ] [1. 0.5 0. ]]

3. 聚类算法选择与实施

3.1 层次聚类实战

层次聚类特别适合探索性分析,可以直观展示样本间的分组关系:

from scipy.cluster.hierarchy import dendrogram, linkage import matplotlib.pyplot as plt # 使用上节计算的相似度矩阵 linked = linkage(dissimilarity_matrix, 'ward') plt.figure(figsize=(10, 6)) dendrogram(linked, orientation='top', labels=['患者1', '患者2', '患者3'], distance_sort='descending') plt.title('患者症状层次聚类') plt.ylabel('距离') plt.show()

3.2 DBSCAN聚类应用

当数据中存在噪声点或异常值时,DBSCAN是更好的选择:

from sklearn.cluster import DBSCAN # 将不相似度矩阵转换为距离矩阵 dbscan = DBSCAN(metric='precomputed', eps=0.7, min_samples=1) clusters = dbscan.fit_predict(dissimilarity_matrix) print(f"聚类结果: {clusters}")

4. 聚类结果的业务解读

4.1 医疗场景分析

假设我们得到以下患者分群:

群组患者特征临床意义
群组1高烧+检测阳性可能为病毒感染
群组2咳嗽+不发烧可能为过敏或轻度呼吸道感染
群组3无症状健康人群或潜伏期

关键诊断指标对比

# 计算各群组的特征平均值 group_features = pd.DataFrame({ '群组': clusters, '发烧率': patients[:,0], '咳嗽率': patients[:,1], '阳性率': patients[:,2] }).groupby('群组').mean() print(group_features)

4.2 商业场景应用

同样的方法可以应用于用户分群:

# 电商用户行为聚类示例 user_behavior = np.array([ [1,0,1,0], # 用户1:购买A、未购买B、点击广告、未收藏 [1,1,0,1], # 用户2 [0,0,1,0] # 用户3 ]) # 计算Jaccard距离矩阵 user_dist = pairwise_distances(user_behavior, metric='jaccard') # 进行层次聚类 user_clusters = linkage(user_dist, 'average')

5. 进阶技巧与常见问题

5.1 混合变量类型处理

实际数据往往包含多种变量类型,可以采用以下策略:

  1. 将连续变量分箱为二元变量
  2. 使用Gower距离等混合度量方法
  3. 分别计算后加权组合
# 连续变量分箱示例 age = [25, 30, 45, 60] age_binary = pd.get_dummies(pd.cut(age, bins=[0,30,50,100]))

5.2 聚类质量评估

虽然没有绝对标准,但可以通过以下方法评估:

  • 轮廓系数
  • 观察树状图切割高度
  • 业务合理性检查
from sklearn.metrics import silhouette_score # 计算轮廓系数(需要转换为相似度) silhouette_avg = silhouette_score(1-dissimilarity_matrix, clusters) print(f"轮廓系数: {silhouette_avg:.3f}")

在实际医疗数据分析项目中,我们发现Jaccard系数对罕见病患者的聚类效果明显优于欧氏距离。曾经有一个案例,通过调整相似度计算方法,成功识别出了一个被传统方法忽略的高风险患者亚群。

http://www.jsqmd.com/news/887202/

相关文章:

  • 你的bWAPP靶场网络通了吗?VMware NAT模式配置与常见访问故障排查指南
  • Foundation 顶部导航栏详解
  • GPT-5.5 vs 国产大模型:2026年5月AI编程工具横评实测
  • 非接触电梯控制系统:基于Arduino与语音识别的低成本改造方案
  • 上海单方起诉离婚律师实测评测:上海离婚股权分割律师/上海离婚诉讼律师/上海离婚财产分割律师/上海离婚隐匿财产律师/选择指南 - 优质品牌商家
  • Windows 10/11系统下,SecureCRT 8.7.2保姆级安装与激活图文指南(含Keygen使用避坑点)
  • 选对名师少走弯路,感恩戴氏的马晓辉老师悉心教导
  • 【UniApp小程序开发】解决无法使用Vue自定义指令的完美替代方案:权限组件封装
  • BlockTable索引器支持字符串和ObjectId键
  • 20newsgroups数据集实战:从原始文本到TF-IDF向量,手把手教你搭建文本分类Pipeline
  • ARM SPE Profiling Buffer架构与性能优化实践
  • 工业风扇选型避坑指南:3个技术拷问,拒绝为虚标的L10寿命交学费
  • 荣耀时刻!格瑞普公司荣膺2026 UASE无人机展“金鹰奖”与“低空经济产业十强”双料大奖
  • 解决css线性渐变边框的radius问题
  • 串口通信粘包问题:成因深度解析与项目实战解决方案
  • 2026广州搬家打包权威机构推荐:广州搬家收纳、广州搬屋、广州搬迁、广州红木搬运、广州蚂蚁搬家、广州蚂蚁搬屋、广州专业搬家选择指南 - 优质品牌商家
  • 内网环境下Win7系统批量离线补丁部署实战指南
  • 2026雪花全粉辊筒干燥机技术拆解与主流品牌盘点:马铃薯雪花全粉设备、麦片辊筒干燥机、米粉辊筒干燥机、红薯全粉设备选择指南 - 优质品牌商家
  • 2026年近期温州专业的语音智能开关贴牌商选哪家?聚焦温州罗邦智能开关的深度剖析 - 2026年企业推荐榜
  • 用Python+Pandas+Seaborn复现Lending Club数据分析(附完整代码与数据集)
  • 华为正式发表半导体领域新定律
  • 自动驾驶中的卡尔曼滤波:如何用Python实现多传感器融合定位?
  • 2026年5月值得信赖的黑龙江玻璃钢过滤器工厂排行厂家推荐榜:机械过滤器、玻璃钢袋式过滤器、保安过滤器、精密过滤器厂家选择指南 - 海棠依旧大
  • [智能体-76]:用组建公司类比 搭建 AI 智能体(全流程 + 组件一一对应,通俗好懂、适合讲解 / 文档使用)
  • echarts中heatmap鼠标滚动禁用缩放,向下滚动
  • Unity中型团队游戏开发加速器:框架、动画、渲染与UI深度优化指南
  • 2026年马铃薯雪花全粉加工设备TOP5实测排行:酵母辊筒干燥机、雪花全粉辊筒干燥机、预糊化淀粉辊筒干燥机、马铃薯全粉加工设备选择指南 - 优质品牌商家
  • Python实战:Gabor滤波器在纹理识别中的降维与特征工程
  • 别再手动转模型了!用ONNX打通PyTorch到TensorRT的部署流水线(附完整代码)
  • 2026年5月,杭州谈判与调解法律服务如何高效对接?深度解析六和律师事务所王旭东团队 - 2026年企业推荐榜