层次聚类算法(Hierarchical Clustering Algorithm)是一种常用的无监督学习算法,用于将数据集划分成多个不同层次的簇。与K均值聚类不同,层次聚类不需要预先指定聚类数量,而是通过计算样本之间的相似度或距离来构建一个层次结构。
聚集层次算法有两种方式:
-
自下而上的合并(Agglomerate),其主要步骤如下:
- 将每个数据点视为单个群集。因此,开始时我们将拥有 n 个群集。开始时,数据点的数量也将为 n。
- 计算 n 个集群之间的距离,计算距离的方法通常有以下几种:
- 对于两个集群,取集群之间距离最近的两个样本点作为集群的距离。
- 对于两个集群,取集群之间距离最远的两个样本点作为集群的距离。
- 对于两个集群,分别计算两个集群内样本点的平均距离,然后计算这两个平均距离之间的距离。
- 找出距离最近的两个集群,进行合并。
- 通过以上三步,可以将样本点聚集想要的 K 个集群。
下面是一个该算法的 Python 实现:
import matplotlib.pyplot as plt import numpy as np# 设置了随机数种子,让随机数生成变得可重复,即在设置过后,每次运行代码得到的随机数都是一样的。 np.random.seed(0)cluster1 = np.random.randn(30, 2) + np.array([0, 7]) cluster2 = np.random.randn(30, 2) + np.array([8, 0]) cluster3 = np.random.randn(30, 2) + np.array([8, 8]) # 用于沿着垂直方向(行方向)堆叠数组,得到一个总的数据集 data = np.vstack([cluster1, cluster2, cluster3])# 1. 初始化每个数据点为一个独立的簇 def initialize_clusters(data):return [[point] for point in data]# 2. 计算簇中心之间的距离 def compute_distances(clusters):distances = np.zeros((len(clusters), len(clusters)))for i in range(len(clusters)):for j in range(len(clusters)):if i != j:# 使用欧式距离计算两个簇的距离distances[i][j] = np.sqrt(sum((np.mean(clusters[i],axis=0) - np.mean(clusters[j], axis=0)) ** 2))return distances# 找距离最近的两个簇 def find_closest_clusters(distances):min_distance = np.inf# 用于保存最近两个簇对应的索引closest_clusters = Nonefor i in range(len(distances)):for j in range(len(distances)):if i != j and distances[i][j] < min_distance:min_distance = distances[i][j]closest_clusters = i, jreturn closest_clusters# 3. 合并最近的两个簇为一个新的簇,并更新簇中心点 def merge_clusters(clusters, closest_clusters):i, j = closest_clustersmerged_cluster = clusters[i] + clusters[j] # 将最近的两个簇更新为一个簇new_clusters = [cluster for idx, cluster in enumerate(clusters) ifidx not in (i, j)]# 这里将没有合并的簇放进新的簇列表里面new_clusters.append(merged_cluster)return new_clustersdef hierarchical_clustering(data, k):# 初始化每个数据点为一个独立的簇clusters = initialize_clusters(data)# 开始迭代合并最相似的簇while len(clusters) > k:# 计算簇中心之间的距离,并找到最近的两个簇distances = compute_distances(clusters)closest_clusters = find_closest_clusters(distances)# 合并最近的两个簇为一个新的簇,并更新簇中心点clusters = merge_clusters(clusters, closest_clusters)return clusters# 执行层次聚类算法 k = 4 clusters = hierarchical_clustering(data, k)# 打印聚类结果 for idx, cluster in enumerate(clusters):print(f"Cluster {idx + 1}: ", cluster)# 绘制聚类结果的图表 plt.figure(figsize=(8, 6)) colors = ["red", "green", "blue", "yellow"]for i in range(k):for p in clusters[i]:plt.scatter(x=p[0], y=p[1], color=colors[i])plt.xlabel("X") plt.ylabel("Y") plt.title("Hierarchical Clustering") plt.show()
-
自上而下的分解(Divisive)。