什么是层次聚类
层次聚类是一种基于相似性度量将数据集中的对象分层次进行组织的聚类方法,它不需要事先指定聚类个数,而是通过计算数据点之间的相似性或距离来动态地构建聚类层次结构,具体来说,层次聚类可以分为两种主要类型:
- 凝聚层次聚类 : 从每个数据点作为单独的类开始,然后逐步合并具有最小距离(或最大相似性)的类,直到所有数据点都被合并为一个类为止, 这种方法产生的是一个树形的聚类结构,称为树状图或树状聚类图
- 分裂层次聚类 : 与凝聚层次聚类相反,它从所有数据点作为一个类开始,然后逐步将其分割为子类,直到每个数据点都成为一个独立的类为止, 这种方法也形成一个树形结构,但其分裂的过程相对较少被使用
层次聚类方法的优点包括不需要事先确定聚类的数量、可以生成层次化的聚类结构、对初始值不敏感等,然而,它的计算复杂度较高,尤其是在处理大数据集时可能会变得不实际,适用于小样本数据
什么是相关系数
相关系数是衡量两个变量之间线性关系强弱及方向的统计量,具体参考往期文章相关系数矩阵创立
代码实现
层次聚类简单可视化
from scipy.cluster.hierarchy import dendrogram, linkage
from scipy.cluster.hierarchy import fcluster
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(42)
data = np.random.rand(10, 10) # 生成10x10的随机数据矩阵
# 使用scipy的linkage方法进行层次聚类
linked = linkage(data, 'average')
# 生成树状图
plt.figure(figsize=(10, 7))
dendrogram(linked,
orientation='top',
labels=range(1, 11),
distance_sort='descending',
show_leaf_counts=True)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Sample index')
plt.ylabel('Distance')
plt.show()
# 获取聚类标签
max_d = 1.2 # 设置距离阈值
clusters = fcluster(linked, max_d, criterion='distance')
# 打印聚类标签
print("Cluster labels:")
print(clusters)
这里,通过层次聚类方法对随机生成的数据进行聚类,并将聚类结果以树状图的形式进行可视化展示,最后利用fcluster函数返回每个样本的类别,这个类别是根据距离阈值确定的,类似于水平线切割法选择一条水平线,根据线与树状图的交点来判断类别,只是这里会根据阈值自动返回类别,比如这里返回结果解读为样本点1、2和7属于类别 1,样本点3、4和5属于类别3,其它类似,共存在5个类别,会发现可视化只能解读数据分类结果,但是不能体现原始数据,所以接下来引入边缘作图,绘制原始数据的热力图同时在边缘绘制树状图
热力图+树状图展示层次聚类
# 使用seaborn的clustermap方法绘制热力图并在xy轴作树状图
g = sns.clustermap(data,
method='average', # 使用平均链接法
cmap='coolwarm', # 使用coolwarm颜色映射
figsize=(10, 10), # 设置图表大小
annot=True, # 显示实际数值
fmt=".2f") # 数值格式保留两位小数
# 调整树状图和热力图的显示
g.ax_heatmap.set_title('Hierarchical Clustering Heatmap')
g.ax_heatmap.set_xlabel('Sample index')
g.ax_heatmap.set_ylabel('Sample index')
plt.show()
使用 seaborn 的 clustermap 方法绘制了一个热力图,并在热力图的行和列两侧显示了对应的层次聚类树状图,其中x轴和y轴分别对应原始数据的列和行这里由于生成的数据格式为array默认从0开始,然后边缘可视化中的树状图分别为对应的分类形式,如左侧树状图就为生成数据每个样本的分类形式可以发现实际上和第一个简单可视化的树状图是一模一样的,上方树状图为每列数据的分类形式,热力图中的数值代表我们样本的具体数值,通过这种可视化形式可以同时了解原始数据和分类形式,但是在实际运用中可能我们只想了解每个样本的聚类形式即可(每行)甚至不想展示实际的数值,还想直接确定具体的聚类结果,就需要对其进行一定的参数调整
# 使用 seaborn 的 clustermap 方法绘制热力图,只显示左侧树状图
g = sns.clustermap(data,
method='average', # 使用平均链接法
cmap='coolwarm', # 使用coolwarm颜色映射
figsize=(10, 10), # 设置图表大小
annot=False, # 不显示实际数值
row_cluster=True, # 聚类行
col_cluster=False, # 不聚类列
row_colors=[plt.cm.tab20(cluster/float(max(clusters))) for cluster in clusters]) # 行颜色
# 调整树状图和热力图的显示
g.ax_heatmap.set_title('Hierarchical Clustering Heatmap')
g.ax_heatmap.set_xlabel('Sample index')
g.ax_heatmap.set_ylabel('Sample index')
plt.show()
这里,只关心行的聚类情况,并且希望通过颜色直观展示每个聚类结果,相同的颜色为同一个类别根据前文fcluster函数返回每个样本的类别clusters确定
g = sns.clustermap(data,
method='average', # 使用平均链接法
cmap='coolwarm', # 使用coolwarm颜色映射
figsize=(10, 10), # 设置图表大小
annot=False, # 不显示实际数值
row_colors=[plt.cm.tab20(cluster/float(max(clusters))) for cluster in clusters], # 行颜色
col_colors=[plt.cm.tab20(cluster/float(max(clusters))) for cluster in clusters]) # 列颜色
# 调整树状图和热力图的显示
g.ax_heatmap.set_title('Hierarchical Clustering Heatmap')
g.ax_heatmap.set_xlabel('Sample index')
g.ax_heatmap.set_ylabel('Sample index')
plt.show()
这里加上列的柱状图,更加完善,更多的参数美化读者自行研究,可以发现实际上这个和相关系数矩阵相同,接下来我们利用实际数据做一个层次聚类与相关系数的混合边缘作图
层次聚类与相关系数的混合边缘作图
import pandas as pd
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 设置随机种子,以确保每次运行结果一致
np.random.seed(0)
# 生成数据
num_samples = 100 # 样本数量
num_features = 11 # 特征数量
# 生成一个形状为 (num_samples, num_features) 的随机数据集
data = np.random.rand(num_samples, num_features)
# 创建 DataFrame
columns = [f"特征_{i+1}" for i in range(num_features)]
df = pd.DataFrame(data, columns=columns)
corr = df.corr()
# 进行层次聚类并得到聚类标签
linked = linkage(corr, method='average')
clusters = fcluster(linked, t=4, criterion='maxclust')
g = sns.clustermap(corr,
method='average', # 使用平均链接法
cmap='coolwarm', # 使用coolwarm颜色映射
figsize=(10, 10), # 设置图表大小
annot=True,
fmt=".2f",
row_cluster=True, # 聚类行
col_cluster=False, # 不聚类列
row_colors=[plt.cm.tab20(cluster/float(max(clusters))) for cluster in clusters]) # 行颜色
# 调整树状图和热力图的显示
g.ax_heatmap.set_title('Hierarchical Clustering Heatmap')
g.ax_heatmap.set_xlabel('Sample index')
g.ax_heatmap.set_ylabel('Sample index')
plt.show()
代码实现了数据生成、相关性分析和聚类可视化,为理解和分析多维数据集中特征之间关系提供帮助
往期推荐
PDP(部分依赖图)、ICE(个体条件期望)解释机器学习模型保姆级教程
论文可视化设计:掌握 Seaborn 15 种精美数据可视化
微信群 |ChatGPT群
无需科学上网、同步官网所有功能、价格美观
微信号 | deep_ML
欢迎添加作者微信进入Python交流群
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考