层次聚类算法的实现

1.作者介绍

杨金花,女,西安工程大学电子信息学院,21级硕士研究生
研究方向:基于学习方法的运动目标检测
电子邮件:2902551510@qq.com

孟莉苹,女,西安工程大学电子信息学院,2021级硕士研究生,张宏伟人工智能课题组
研究方向:机器视觉与人工智能
电子邮件:2425613875@qq.com

2.层次聚类算法介绍

2.1 层次聚类算法原理

 聚类就是对大量未知标注的数据集,按照数据内部存在的数据特征将数据集划分为多个不同的类别,使类别内的数据比较相似,类别之间的数据相似度比较小。
 层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法。算法流程展示如图所示。

在这里插入图片描述

2.2 层次聚类算法步骤

假设有6个样本点{A,B,C,D,E,F},对于层次聚类来说,步骤如下:
(1)假设每个样本点都为一个簇类,计算每个簇类间的相似度,得到相似矩阵;
(2)寻找各个类之间最近的两个类,即若B和C的相似度最高,合并簇类B和C为一个簇类。现在我们还有五个簇类,分别为A,BC,D,E,F;
(3)更新簇类间的相似矩阵,若簇类BC和D的相似度最高,合并簇类BC和D为一个簇类。现在我们还有四个簇类,分别为A,BCD,E,F;
(4)更新簇类间的相似矩阵,若簇类E和F的相似度最高,合并簇类E和F为一个簇类。现在我们还有3个簇类,分别为A,BCD,EF。
(5)重复第四步,簇类BCD和簇类EF的相似度最高,合并该两个簇类,现在我们还有2个簇类,分别为A,BCDEF。
(6)最后合并簇类A和BCDEF为一个簇类,层次聚类算法结束。
层次聚类实现过程如图2所示。

图2. 层次聚类实现过程示例图

2.3 层次聚类算法分类

自顶向下的层次聚类算法(Divisive):
Divisive 层次聚类:又称自顶向下(top-down)的层次聚类,最开始所有的对象均属于一个cluster,每次按一定的准则将某个cluster 划分为多个cluster,如此往复,直至每个对象均属于某一个cluster。实现过程示意图如下。

图3. Divisive实现过程示例图

自底向上的层次聚类算法(Agglomerative):
Agglomerative 层次聚类:又称自底向上(bottom-up)的层次聚类,每一个对象最开始都是一个cluster,每次按一定的准则将最相近的两个cluster合并生成一个新的cluster,如此往复,直至最终所有的对象都属于一个cluster。

图4. Divisive实现过程示例图

3.层次聚类算法实现(代码如下)

3.1 相关包导入

from scipy.cluster.hierarchy import linkage     #导入linage函数用于层次聚类
from scipy.cluster.hierarchy import dendrogram  #dendrogram函数用于将聚类结果绘制成树状图
from scipy.cluster.hierarchy import fcluster    #fcluster函数用于提取出聚类的结果
from sklearn.datasets import make_blobs         #make_blobs用于生成聚类算法的测试数据
from sklearn.cluster import AgglomerativeClustering  #自底向上层次聚类算法
import matplotlib.pyplot as plt                 #导入matplotlib绘图工具包

3.2 生成测试数据集

#生成测试数据
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4, random_state=0)
plt.figure(figsize=(10, 8))
plt.scatter(X[:, 0], X[:, 1], c='b')
plt.show()
#from scipy.cluster.hierarchy import linkage

图5. 测试数据可视化展示

3.3 层次聚类实现&画出树状图

#层次聚类实现
#from scipy.cluster.hierarchy import dendrogram
Z = linkage(X,  method='ward', metric='euclidean')
print(Z.shape)
print(Z[: 5])

#画出树状图
#from scipy.cluster.hierarchy import fcluster
plt.figure(figsize=(10, 8))
dendrogram(Z, truncate_mode='lastp', p=20, show_leaf_counts=False, leaf_rotation=90, leaf_font_size=15,
           show_contracted=True)
plt.show()

图6. 树状图可视化展示

3.4 获取聚类结果

#根据临界距离返回聚类结果
d = 15
labels_1 = fcluster(Z, t=d, criterion='distance')
print(labels_1[: 100])  # 打印聚类结果
print(len(set(labels_1)))  # 看看在该临界距离下有几个 cluster

#根据聚类数目返回聚类结果
k = 3
labels_2 = fcluster(Z, t=k, criterion='maxclust')
print(labels_2[: 100])
list(labels_1) == list(labels_2)  # 看看两种不同维度下得到的聚类结果是否一致

#聚类的结果可视化,相同的类的样本点用同一种颜色表示
plt.figure(figsize=(10, 8))
plt.scatter(X[:, 0], X[:, 1], c=labels_2, cmap='prism')
plt.show()

图7. 聚类结果可视化展示

3.5完整代码

from scipy.cluster.hierarchy import linkage     #导入linage函数用于层次聚类
from scipy.cluster.hierarchy import dendrogram  #dendrogram函数用于将聚类结果绘制成树状图
from scipy.cluster.hierarchy import fcluster    #fcluster函数用于提取出聚类的结果
from sklearn.datasets import make_blobs         #make_blobs用于生成聚类算法的测试数据
from sklearn.cluster import AgglomerativeClustering  #自底向上层次聚类算法
import matplotlib.pyplot as plt                 #导入matplotlib绘图工具包

#生成测试数据
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4, random_state=0)
plt.figure(figsize=(10, 8))
plt.scatter(X[:, 0], X[:, 1], c='b')
plt.show()
#from scipy.cluster.hierarchy import linkage

#层次聚类实现
#from scipy.cluster.hierarchy import dendrogram
Z = linkage(X,  method='ward', metric='euclidean')
print(Z.shape)
print(Z[: 5])


#画出树状图
#from scipy.cluster.hierarchy import fcluster
plt.figure(figsize=(10, 8))
dendrogram(Z, truncate_mode='lastp', p=20, show_leaf_counts=False, leaf_rotation=90, leaf_font_size=15,
           show_contracted=True)
plt.show()

# 根据临界距离返回聚类结果
d = 15
labels_1 = fcluster(Z, t=d, criterion='distance')
print(labels_1[: 100])  # 打印聚类结果
print(len(set(labels_1)))  # 看看在该临界距离下有几个 cluster

# 根据聚类数目返回聚类结果
k = 3
labels_2 = fcluster(Z, t=k, criterion='maxclust')
print(labels_2[: 100])
list(labels_1) == list(labels_2)  # 看看两种不同维度下得到的聚类结果是否一致

# 聚类的结果可视化,相同的类的样本点用同一种颜色表示
plt.figure(figsize=(10, 8))
plt.scatter(X[:, 0], X[:, 1], c=labels_2, cmap='prism')
plt.show()

3.6 对比不同方法聚类效果

from time import time
import numpy as np
from sklearn.datasets import make_blobs
from scipy.cluster.hierarchy import linkage, fcluster
from sklearn.metrics.cluster import adjusted_mutual_info_score
import matplotlib.pyplot as plt

#生成样本点
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels = make_blobs(n_samples=750, centers=centers,
                       cluster_std=0.4, random_state=0)


#可视化聚类结果
def plot_clustering(X, labels, title=None):
    plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='prism')
    if title is not None:
        plt.title(title, size=17)
    plt.axis('off')
    plt.tight_layout()

#进行 Agglomerative 层次聚类
linkage_method_list = ['single', 'complete', 'average', 'ward']

plt.figure(figsize=(10, 8))
ncols, nrows = 2, int(np.ceil(len(linkage_method_list) / 2))
plt.subplots(nrows=nrows, ncols=ncols)
for i, linkage_method in enumerate(linkage_method_list):
    print('method %s:' % linkage_method)
    start_time = time()
    Z = linkage(X, method=linkage_method)
    labels_pred = fcluster(Z, t=3, criterion='maxclust')
    print('Adjust mutual information: %.3f' % adjusted_mutual_info_score(labels, labels_pred))
    print('time used: %.3f seconds' % (time() - start_time))
    plt.subplot(nrows, ncols, i + 1)
    plot_clustering(X, labels_pred, '%s linkage' % linkage_method)
plt.show()

图8. 不同聚类方法结果展示

AMI评估结果
该量越接近于 1 则说明聚类算法产生的类越接近于真实情况。从右图的AMI量的表现来看,Single-link 方法下的层次聚类结果最差,它几乎将所有的点都聚为一个 cluster,而其他两个 cluster 则都仅包含个别稍微有点偏离中心的样本点,而另外三种聚类方法效果都还可以。结果如下图

图9. AMI评估结果

4.参考链接

博客参考链接:
https://cloud.tencent.com/developer/article/1800586

  • 60
    点赞
  • 390
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 层次聚类是一种无监督学习算法,它可以将数据集中的样本分成具有相似性的若干个簇。以下是使用Python实现层次聚类算法的示例代码: ``` import numpy as np from scipy.spatial.distance import pdist from scipy.cluster.hierarchy import dendrogram, linkage # 生成一个样本数据集 X = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]]) # 计算距离矩阵 dist_matrix = pdist(X) # 使用“ward”方法进行层次聚类 Z = linkage(dist_matrix, 'ward') # 生成树状图 dendrogram(Z) # 显示树状图 import matplotlib.pyplot as plt plt.show() ``` 在上面的代码中,我们首先生成了一个样本数据集,然后使用`pdist`函数计算距离矩阵。接着,我们使用`linkage`函数使用“ward”方法进行层次聚类。最后,我们使用`dendrogram`函数生成树状图并使用`matplotlib`库显示出来。 需要注意的是,由于层次聚类算法的时间复杂度较高,因此对于大规模数据集的应用,可能需要使用其他更加高效的算法。 ### 回答2: 层次聚类是一种聚类算法,其主要目标是将数据样本分成不同的组或类。它的实现方式在Python中可以使用scikit-learn或者其他机器学习库来完成。 在Python中,一个常用的层次聚类算法实现方法是使用scikit-learn库中的AgglomerativeClustering类。该类需要指定聚类的参数,例如聚类的数量或者距离度量方式。下面是一个简单的示例代码: ```python from sklearn.cluster import AgglomerativeClustering import numpy as np # 生成示例数据 X = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]]) # 定义层次聚类模型并拟合数据 model = AgglomerativeClustering(n_clusters=2) model.fit(X) # 输出每个数据点所属的聚类编号 print(model.labels_) ``` 在上面的代码中,首先导入必要的库,然后生成示例数据X。接下来定义一个AgglomerativeClustering对象,并指定聚类的数量为2。然后调用fit函数拟合数据。 最后输出每个数据点所属的聚类编号。这里将输出一个长度为6的数组,代表每个数据点属于哪个聚类。 以上是层次聚类算法在Python中的一种实现方式。你可以根据自己的需求选择其他合适的聚类算法和库,根据数据的特点进行调整、优化和评估。 ### 回答3: 层次聚类算法(Hierarchical Clustering)是一种基于距离的聚类算法,通过逐步合并样本或聚类,构建一个树状结构,最终将所有样本或聚类划分为不同的簇。在Python中,可以使用scikit-learn库中的AgglomerativeClustering来实现层次聚类算法。 步骤如下: 1. 导入必要的库: ``` from sklearn.cluster import AgglomerativeClustering ``` 2. 准备数据: ``` X = [[1, 2], [3, 4], [1, 4], [2, 2], [3, 3]] ``` 3. 创建层次聚类对象: ``` agg_clustering = AgglomerativeClustering(n_clusters=2) ``` 4. 进行聚类: ``` labels = agg_clustering.fit_predict(X) ``` 5. 输出结果: ``` print(labels) ``` 这样就可以得到每个样本所属的簇的标签。层次聚类算法基于距离计算,通过不断合并样本或聚类,构建出一个树状结构。在这个树状结构中,可以根据需要选择合适的层次作为最终的聚类结果。 总结一下,层次聚类算法是一种基于距离的聚类算法,通过逐步合并样本或聚类,构建一个树状结构,将所有样本或聚类划分为不同的簇。在Python中,可以使用scikit-learn库中的AgglomerativeClustering来实现算法
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值