AGNES

AGNES(AGglomerative NESting 的简写)是一种采用自底向上聚合策略的层次聚类算法。

【工作过程】:

  1. 先将数据集中的每个样本看作一个初始聚类簇;
  2. 然后在算法运行的每一步中找出距离最近的两个聚类簇进行合并;
  3. 步骤(2)不断重复,直至达到预设的聚类簇的个数。

【关键】:如何计算聚类簇之间的距离。

实际上,每个簇是一个样本集合,因此,只需采用关于集合的某种距离即可。
最小距离: d m i n ( C i , C j ) = m i n x ∈ C i , z ∈ C j d i s t ( x , z ) , 最大距离: d m a x ( C i , C j ) = m a x x ∈ C i , z ∈ C j d i s t ( x , z ) , 平均距离: 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 ) . \text{最小距离:}d_{min}(C_i, C_j) = min_{x\in C_i,z\in C_j}dist(x,z), \\ \text{最大距离:}d_{max}(C_i, C_j) = max_{x\in C_i,z\in C_j}dist(x,z), \\ \text{平均距离:}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). 最小距离:dmin(Ci,Cj)=minxCi,zCjdist(x,z),最大距离:dmax(Ci,Cj)=maxxCi,zCjdist(x,z),平均距离:davg(Ci,Cj)=CiCj1xCizCjdist(x,z).
显然,最小距离由两个簇的最近样本决定,最大距离由两个簇的最远样本决定,而平均距离则由两个簇的所有样本共同决定。

当聚类簇距离为

  • d m i n d_{min} dmin:AGNES 算法被称为“单链接”(single-linkage);
  • d m a x d_{max} dmax:AGNES 算法被称为“全链接”(complete-linkage);
  • d a v g d_{avg} davg:AGNES 算法被称为“均链接”(average-linkage)。

此外,豪斯多夫距离(Hausdorff distance)也可用于集合间的距离计算。关于豪斯多夫距离的介绍可参考这篇博文豪斯多夫距离

【算法描述】:

  • 输入:样本集 D = { x 1 , x 2 , ⋯   , x n } D = \{x_1, x_2, \cdots, x_n\} D={x1,x2,,xn};聚类簇距离度量函数 dist;聚类簇数 k。
  • 输出:簇划分 C = { C 1 , C 2 , ⋯   , C k } C = \{C_1, C_2, \cdots, C_k\} C={C1,C2,,Ck}
  • 过程:
  1. 为每个样本创建一个簇;
  2. 计算距离矩阵;
  3. 开始合并簇过程,初始化聚类簇个数 q = n:
    1. 每次从距离矩阵中找出距离最近的两个聚类簇 C i C_i Ci C j C_j Cj,i < j;
    2. 合并这两个簇(优先合并到下标较小的簇 C i C_i Ci C i = C i ⋃ C j C_i = C_i \bigcup C_j Ci=CiCj
    3. 将聚类簇重新编号(合并到下标较小的簇可以减少重编号的次数);
    4. 删除距离矩阵的第 j 行与第 j 列;
    5. 计算合并后的簇 C i C_i Ci 与剩余其他簇之间的距离,并更新距离矩阵。
    6. q = q - 1。
    7. 直到 q == k 时,退出循环。
  4. 返回簇划分。

案例说明

iddensitysugar contentiddensitysugar contentiddensitysugar content
10.6970.460110.2450.057210.7480.232
20.7740.376120.3430.099220.7140.346
30.6340.264130.6390.161230.4830.312
40.6080.318140.6570.198240.4780.437
50.5560.215150.3600.370250.5250.369
60.4030.237160.5930.042260.7510.489
70.4810.149170.7190.103270.5320.472
80.4370.211180.3590.188280.4730.376
90.6660.091190.3390.241290.7250.445
100.2430.267200.2820.257300.4460.459

以上述数据集(《机器学习》西瓜集 4.0)为例,令 AGNES 算法一直执行到所有样本出现在同一个簇中,即 k = 1,即可得到下图所示的“树状图”(dendrogram),其中每层链接一组聚类簇。

AGNES 算法生成的树状图

观测树状图的合并结果,可以发现该合并结果是 AGNES 算法以“最大距离”作为距离度量标准进行合并。此外,在树状图的特定层次上进行分割,则可得到相应的簇划分结果。例如,以图中所示虚线分割树状图,将得到包含 7 个聚类簇的结果。

  • C1 = {x1, x26, x29};
  • C2 = {x2, x3, x4, x21, x22};
  • C3 = {x23, x24, x25, x27, x28, x30};
  • C4 = {x5, x7};
  • C5 = {x9, x13, x14, x16, 17};
  • C6 = {x6, x8, x10, x5, x18, x19, x20};
  • C7 = {x11, x12}。

将分割层逐步提升,则可得到聚类簇逐渐减小的聚类结果。下图显示 AGNES 算法产生 7 至 4 个聚类簇的划分结果。

不同k的聚类结果.jpg

代码实现

首先实现距离计算函数。

def get_dist(XA, XB, type='min'):
    if len(XA.shape) == 1:
        XA = np.array([XA])
    if len(XB.shape) == 1:
        XB = np.array([XB])
    dist = 0
    if type == 'min':
        dist = cdist(XA, XB, 'euclidean').min()
    elif type == 'max':
        dist = cdist(XA, XB, 'euclidean').max()
    else:
        dist = cdist(XA, XB, 'euclidean').sum() / XA.shape[0] / XB.shape[0]
    return dist

然后编写 AGNES 函数的实体:

  • 函数定义
def AGNES(dataset, k, dist_method='avg'):
  • 初始化所需变量
# 获取样本集长度
length = dataset.shape[0]
# 初始化聚类簇和距离矩阵
clusters, dist_matrix = [], np.mat(np.zeros((length, length)))
  • 为每个样本分配一个聚类簇
for data in dataset:
    clusters.append(data)
  • 计算距离矩阵
for i in range(length):
    for j in range(length):
        if i == j:
            dist = np.inf
        else:
            dist = get_dist(clusters[i], clusters[j], dist_method)
        dist_matrix[i, j] = dist
        dist_matrix[j, i] = dist
  • 设置当前聚类簇的个数,并开始合并过程
cluster_count = length
while cluster_count > k:
  • 找出距离最近的两个聚类簇
first, second = np.where(dist_matrix == dist_matrix.min())[0]
  • 合并这两个聚类簇
clusters[first] = np.vstack((cluters[first], clusters[second]))
  • 将聚类簇重新编号
for i in range(second + 1, cluster_count):
    clusters[i - 1] = clusters[i]
clusters.pop()
  • 删除距离矩阵的第 second 行与列
dist_matrix = np.delete(dist_matrix, second, axis=0)
dist_matrix = np.delete(dist_matrix, second, axis=1)
  • 重新计算距离矩阵第 first 簇与其他簇之间距离
for i in range(cluster_count - 1):
    if first == i:
        dist = np.inf
    else:
        dist = get_dist(clusters[first], clusters[i], dist_method)
    dist_matrix[first, i] = dist
    dist_matrix[i, first] = dist
  • q = q - 1
cluster_count -= 1
  • 返回簇划分
return clusters

【完整代码】:传送门

def AGNES(dataset, k, dist_method='avg'):
    length = dataset.shape[0]
    clusters = []
    dist_matrix = np.mat(np.zeros((length, length)))
    for data in dataset:
        clusters.append(data)
    for i in range(length):
        for j in range(length):
            if i == j:
                dist = np.inf
            else:
                dist = get_dist(clusters[i], clusters[j], dist_method)
            dist_matrix[i, j] = dist
            dist_matrix[j, i] = dist

    # 设置当前聚类簇的个数
    cluster_count = length
    
    while cluster_count > k:
        # 找出距离最近的两个聚类簇
        first, second = np.where(dist_matrix == dist_matrix.min())[0]
        
        # 合并这两个聚类簇
        clusters[first] = np.vstack((clusters[first], clusters[second]))
        
        # 重新编号聚类簇
        for i in range(second + 1, cluster_count):
            clusters[i - 1] = clusters[i]
        clusters.pop()
        
        # 删除距离矩阵的第 second 行与列
        dist_matrix = np.delete(dist_matrix, second, axis=0)
        dist_matrix = np.delete(dist_matrix, second, axis=1)        
        
        # 重新计算距离矩阵第 first 簇与其他簇之间距离
        for i in range(cluster_count - 1):
            if first == i:
                dist = np.inf
            else:
                dist = get_dist(clusters[first], clusters[i], dist_method)
            dist_matrix[first, i] = dist
            dist_matrix[i, first] = dist
        cluster_count -= 1
    return clusters

参考

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Agnes算法是一种层次聚类算法,它通过计算数据点之间的距离来将数据点逐步聚合成簇。在每一步中,算法会找到距离最近的两个数据点,然后将它们合并到一个新的簇中。这个新的簇将会作为下一步聚合的单个数据点。 在Agnes算法中,我们需要定义一个距离度量方法来衡量两个数据点之间的距离。常用的方法有欧氏距离、曼哈顿距离等。然后,我们需要定义一个合并标准来判断两个簇是否可以合并。常见的合并标准有最小距离、最大距离、平均距离等。 在Python中,可以使用SciPy库中的`scipy.cluster.hierarchy`模块来实现Agnes算法。首先,我们需要使用`scipy.spatial.distance`模块来计算数据点之间的距离。然后,我们可以使用`scipy.cluster.hierarchy.linkage`函数来进行层次聚类。这个函数会根据之前定义的距离度量方法和合并标准来计算簇的合并顺序。最后,我们可以使用`scipy.cluster.hierarchy.dendrogram`函数来可视化聚类结果。 下面是一个简单的示例代码: ```python import numpy as np from scipy.spatial.distance import pdist from scipy.cluster.hierarchy import linkage, dendrogram # 生成数据 data = np.random.rand(20, 2) # 计算距离 distances = pdist(data) # 进行层次聚类 clusters = linkage(distances) # 可视化聚类结果 dendrogram(clusters) # 展示结果 plt.show() ``` 通过运行上述代码,我们可以得到一个层次聚类的树状图,根据树状图可以判断数据点之间的聚类关系。 总之,Agnes算法是一种基于层次聚类的算法,可以将数据点逐步聚合成簇。Python中可以使用SciPy库来实现Agnes算法,并通过可视化来分析聚类结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值