西瓜书学习笔记——层次聚类(公式推导+举例应用)

文章目录

      • 算法介绍
      • 实验分析

算法介绍

层次聚类是一种将数据集划分为层次结构的聚类方法。它主要有两种策略:自底向上自顶向下
其中AGNES算法是一种自底向上聚类算法,用于将数据集划分为层次结构的聚类。算法的基本思想是从每个数据点开始,逐步合并最相似的簇,直到形成一个包含所有数据点的大簇。这个过程被反复执行,构建出一个层次化的聚类结构。这其中的关键就是如何计算聚类簇之间的距离。 但实际上,每个簇都是一个集合,故我们只需要计算集合与集合的距离即可。例如,给定聚类簇 C i C_i Ci C j C_j Cj,可通过下面的式子来计算距离:
d m i n ( C i , C j ) = min x ∈ C i , z ∈ C j   d i s t ( x , z ) (1) d_{min}(C_i,C_j)=\underset{x \in C_i,z\in C_j}{\text{min}} \ dist(x,z) \tag{1} dmin(Ci,Cj)=xCi,zCjmin dist(x,z)(1)
d m a x ( C i , C j ) = max x ∈ C i , z ∈ C j   d i s t ( x , z ) (2) d_{max}(C_i,C_j)=\underset{x \in C_i,z\in C_j}{\text{max}} \ dist(x,z) \tag{2} dmax(Ci,Cj)=xCi,zCjmax dist(x,z)(2)
d a v g ( C i , C j ) = 1 ∣ C i ∣ ∣ C j ∣ ∑ x ∈ C i ∑ z ∈ c j d i s t ( x , z ) (3) d_{avg }(C_i,C_j)=\frac{1}{|C_i||C_j|}\sum_{x\in C_i}\sum_{z\in c_j} dist(x,z) \tag{3} davg(Ci,Cj)=Ci∣∣Cj1xCizcjdist(x,z)(3)

其中 ∣ C i ∣ |C_i| Ci是集合 C i C_i Ci的元素个数。显然最小距离是由两个簇最近的样本点决定的;最大距离是由两个簇最远的样本点决定的;平均距离是由两个簇所有样本点共同决定的。

还有个更有效的计算集合距离的方法豪斯多夫距离:假设在同一样本空间的集合 X X X Z Z Z之间的距离可以通过以下式子计算:
dist ⁡ H ( X , Z ) = max ⁡ ( dist ⁡ h ( X , Z ) , dist ⁡ h ( Z , X ) ) (4) \operatorname{dist}_{\mathrm{H}}(X, Z)=\max \left(\operatorname{dist}_{\mathrm{h}}(X, Z), \operatorname{dist}_{\mathrm{h}}(Z, X)\right) \tag{4} distH(X,Z)=max(disth(X,Z),disth(Z,X))(4)

其中 dist ⁡ h ( X , Z ) = max ⁡ x ∈ X min ⁡ z ∈ Z ∥ x − z ∥ 2 \operatorname{dist}_{\mathrm{h}}(X, Z)=\max _{\boldsymbol{x} \in X} \min _{\boldsymbol{z} \in Z}\|\boldsymbol{x}-\boldsymbol{z}\|_2 disth(X,Z)=maxxXminzZxz2

豪斯多夫距离的应用涉及到形状匹配、图像匹配、模式识别等领域,它对于描述两个集合的整体形状之间的差异具有较好的效果。然而,由于计算豪斯多夫距离涉及到点之间的一一匹配,因此在实际应用中可能需要考虑一些优化算法以提高计算效率。

下图是AGNES算法流程图:
西瓜书学习笔记——层次聚类(公式推导+举例应用)_第1张图片

实验分析

数据集如下表所示:
在这里插入图片描述
读入数据集:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('data/4.0.csv')

定义距离函数:

# 定义豪斯多夫距离函数
def hausdorff_distance(cluster1, cluster2):
    max_distance1 = max(min(distance(p1, p2) for p1 in cluster1) for p2 in cluster2)
    max_distance2 = max(min(distance(p1, p2) for p2 in cluster2) for p1 in cluster1)
    return max(max_distance1, max_distance2)

# 定义距离函数
def distance(point1, point2):
    return ((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2) ** 0.5

AGNES算法:

# AGNES算法
def agnes(data):
    clusters = [[point] for point in data.values]

    while len(clusters) > 4:
        min_distance = float('inf')
        merge_indices = (0, 0)

        for i in range(len(clusters)):
            for j in range(i + 1, len(clusters)):
                cluster1 = clusters[i]
                cluster2 = clusters[j]

                current_distance = hausdorff_distance(cluster1, cluster2)

                if current_distance < min_distance:
                    min_distance = current_distance
                    merge_indices = (i, j)

        # 合并最近的两个簇
        merged_cluster = clusters[merge_indices[0]] + clusters[merge_indices[1]]
        clusters.pop(merge_indices[1])
        clusters[merge_indices[0]] = merged_cluster

    return clusters

绘制分类结果函数:

# 绘制分类结果
def plot_clusters(data, clusters):
    plt.figure(figsize=(8, 8))

    # 绘制原始数据点
    plt.scatter(data['Density'], data['Sugar inclusion rate'], color='black', label='Original Data')

    # 绘制分类结果
    for i, cluster in enumerate(clusters):
        cluster_data = pd.DataFrame(cluster, columns=['Density', 'Sugar inclusion rate'])
        plt.scatter(cluster_data['Density'], cluster_data['Sugar inclusion rate'], label=f'Cluster {i + 1}')

    # 添加标签和图例
    plt.title('AGNES Clustering Result')
    plt.xlabel('Density')
    plt.ylabel('Sugar inclusion rate')
    plt.legend()
    plt.show()

执行AGNES且画出分类结果:

# 执行层次聚类
result_clusters = agnes(data)

# 输出聚类结果
for i, cluster in enumerate(result_clusters):
    print(f'Cluster {i + 1}: {cluster}')
    
# 绘制分类结果图
plot_clusters(data, result_clusters)

西瓜书学习笔记——层次聚类(公式推导+举例应用)_第2张图片

你可能感兴趣的:(机器学习,学习,笔记,聚类)