核心内容摘要
唤醒内在的洪荒之力:日复一日,成就非凡
从零开始用Scipy的Dendrogram揭示数据层次结构的完整指南当你面对一堆看似杂乱无章的数据时是否曾想过这些数据内部可能隐藏着某种层次结构层次聚类算法正是解决这一问题的利器而Scipy库中的dendrogram树状图则是展示这种层次结构的绝佳工具。
本文将带你从基础概念出发通过一个完整的案例掌握如何使用Scipy的linkage和dendrogram函数来构建和解读层次聚类树状图。
层次聚类基础与核心概念层次聚类是一种无需预先指定聚类数量的无监督学习方法它通过计算数据点之间的相似度距离来构建树形结构。
与K-means等划分式聚类不同层次聚类能够展示数据在不同粒度下的分组情况。
核心概念解析凝聚式Agglomerative自底向上方法每个数据点初始为一个簇逐步合并最相似的簇分裂式Divisive自顶向下方法所有数据点初始为一个簇逐步分裂为更小的簇连接准则Linkage Criterion决定如何计算簇间距离的方法常见有单连接single两个簇中最近点之间的距离全连接complete两个簇中最远点之间的距离平均连接average两个簇所有点对距离的平均值Ward方法最小化合并后的簇内方差增量from scipy.cluster.hierarchy import linkage, dendrogram from matplotlib import pyplot as plt import numpy as np # 生成示例数据 np.random.seed(
data np.concatenate([ np.random.normal(loc[0,0], scale1, size(50,
), np.random.normal(loc[5,5], scale1, size(50,
) ]) # 计算连接矩阵 Z linkage(data, methodward)
数据准备与预处理实战在应用层次聚类前数据准备是至关重要的一步。
不合适的预处理可能导致聚类结果失真。
关键预处理步骤数据清洗处理缺失值删除或填充去除异常值使用IQR或Z-score方法特征标准化当特征量纲不同时必须进行标准化常用方法Z-score标准化、Min-Max归一化距离度量选择欧氏距离适用于连续变量余弦相似度适用于文本或高维稀疏数据马氏距离考虑特征间相关性from sklearn.preprocessing import StandardScaler # 标准化数据 scaler StandardScaler() data_scaled scaler.fit_transform(data) # 不同距离度量的效果对比 methods [euclidean, cityblock, cosine] fig, axes plt.subplots(1, 3, figsize(18,
) for ax, metric in zip(axes, methods): Z linkage(data_scaled, methodcomplete, metricmetric) dendrogram(Z, axax) ax.set_title(fMetric: {metric}) plt.tight_layout()
构建与解读树状图树状图是层次聚类的可视化呈现正确解读它需要理解几个关键元素树状图组成要素叶子节点代表原始数据点连接高度表示两个簇合并时的距离颜色阈值用于区分不同簇的视觉辅助解读技巧观察连接高度的突变点这通常表示自然的聚类分割水平切割树状图可以得到不同数量的簇簇内连接高度差异小表示簇内一致性高plt.figure(figsize(12,
) dendrogram(Z, truncate_modelastp, # 显示最后p个合并的簇 p12, # 显示12个叶节点 show_leaf_countsTrue, # 显示叶节点数量 leaf_rotation
, # 旋转叶标签 leaf_font_size
, # 叶标签字体大小 show_contractedTrue) # 显示收缩的叶节点 plt.title(层次聚类树状图) plt.xlabel(样本索引或(簇大小)) plt.ylabel(距离) plt.axhline(y5, ck, linestyle--) # 添加水平切割线 plt.show()
参数调优与高级技巧Scipy的dendrogram函数提供了丰富的参数来控制树状图的显示效果和聚类行为。
关键参数详解参数类型描述常用值pint控制显示的簇数量
truncate_modestr截断模式lastp, level, Nonecolor_thresholdfloat颜色区分阈值
7*max(Z[:,2])orientationstr树状图方向top, bottom, left, rightlabelslist叶节点标签自定义标签列表leaf_rotationfloat叶标签旋转角度
高级技巧动态颜色阈值根据数据特性自动设置颜色阈值自定义叶标签使用leaf_label_func参数添加丰富信息交互式可视化结合plotly实现可交互树状图# 自定义颜色阈值和标签 color_threshold
7 * max(Z[:,2]) plt.figure(figsize(15,
) dendrogram(Z, color_thresholdcolor_threshold, labels[f样本_{i} for i in range(len(data))], leaf_label_funclambda x: fID:{x}, above_threshold_colorgrey) # 高于阈值的连接颜色 plt.title(带自定义颜色和标签的树状图) plt.show()
实战案例鸢尾花数据集分析让我们通过经典的鸢尾花数据集来展示层次聚类的完整流程。
from sklearn.datasets import load_iris # 加载数据 iris load_iris() X iris.data y iris.target # 标准化并计算连接矩阵 scaler StandardScaler() X_scaled scaler.fit_transform(X) Z linkage(X_scaled, methodward) # 绘制树状图 plt.figure(figsize(12,
) dendrogram(Z, labelsy, orientationright) plt.title(鸢尾花数据集层次聚类) plt.xlabel(距离) plt.ylabel(鸢尾花种类) plt.show() # 提取聚类结果 from scipy.cluster.hierarchy import fcluster clusters fcluster(Z, t3, criterionmaxclust) # 评估聚类效果 from sklearn.metrics import adjusted_rand_score print(f调整兰德指数: {adjusted_rand_score(y, clusters):.3f})结果分析树状图清晰显示了三个主要簇与鸢尾花的三个种类基本吻合调整兰德指数接近1表明聚类结果与真实分类高度一致可以观察到setosa种类与其他两种区分明显versicolor和virginica有部分重叠
6.
常见问题与解决方案在实际应用中你可能会遇到以下典型问题问题1大数据集导致树状图难以阅读解决方案使用truncate_mode参数简化显示dendrogram(Z, truncate_modelevel, p
问题2如何确定最佳聚类数量解决方案结合轮廓系数和树状图高度变化from sklearn.metrics import silhouette_score # 尝试不同聚类数量 range_n_clusters range(2,
silhouette_scores [] for n_clusters in range_n_clusters: clusters fcluster(Z, n_clusters, criterionmaxclust) silhouette_scores.append(silhouette_score(X_scaled, clusters)) plt.plot(range_n_clusters, silhouette_scores) plt.xlabel(聚类数量) plt.ylabel(轮廓系数) plt.show()问题3处理高维数据解决方案先降维再聚类from sklearn.decomposition import PCA pca PCA(n_components
X_pca pca.fit_transform(X_scaled) Z_pca linkage(X_pca, methodward)
与其他聚类方法的对比层次聚类并非适用于所有场景了解其优缺点有助于做出正确选择对比表格方法优点缺点适用场景层次聚类可视化直观无需预设K值计算复杂度高(O(n³))中小数据集需要层次关系K-means计算效率高(O(n))需要预设K值对异常值敏感大数据集球形簇DBSCAN能发现任意形状簇抗噪声参数敏感高维效果差非凸形状含噪声数据选择建议当数据量1000且需要可视化解释时优先考虑层次聚类对于文本数据可尝试结合TF-IDF和余弦相似度在生物信息学等领域层次聚类仍是首选方法# 对比K-means和层次聚类 from sklearn.cluster import KMeans kmeans KMeans(n_clusters
kmeans_labels kmeans.fit_predict(X_scaled) hierarchical_labels fcluster(Z, 3, criterionmaxclust) fig, (ax1, ax
plt.subplots(1, 2, figsize(15,
) ax
scatter(X[:,0], X[:,1], ckmeans_labels) ax
set_title(K-means聚类) ax
scatter(X[:,0], X[:,1], chierarchical_labels) ax
set_title(层次聚类) plt.show()在实际项目中我经常发现层次聚类在探索性分析阶段特别有价值。
它提供的树状图不仅能展示最终聚类结果还能揭示数据在不同尺度下的组织结构这是其他聚类方法难以替代的。
当处理基因表达数据时通过调整颜色阈值和切割高度往往能发现意想不到的生物标记物组合。