2021 机器学习算法—层次聚类法(Hierachical clustering)

1,100 阅读6分钟

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

为了分享此篇文章,个人做了大量的工作,所以未经本人同意,请勿转载,在此表示感谢!

层次聚类法(Hierachical clustering)

现在时代节奏越来越快,大家都喜欢吃快餐,看短视频,当然可以节省很多时间去干自己愿意做的事。但是大家也很难沉下心来去做好一件事。注意力也很难集中,可能遇事容易急躁。其实很多事不是一下子就能立竿见影,甚至有的时候是上下波动,即使努力了返回退步,这时候就需要我们坚持,累了烦了就休息一会儿,娱乐一下,只要坚持下来,相信会会有成效的。

有两种类型的分层聚类,分别是聚合式(Agglomerative)分裂式(Divisive)

  • 聚合式: 数据点的聚类是采用自下而上的方法,从单个数据点开始
  • 分裂式(Divisive) : 所有的数据点都被视为一个大聚类,聚类过程涉及到将一个大聚类分成几个小聚类

在这篇文章中,我们将重点讨论涉及自下而上方法的聚类。

聚类的一般步骤

以下是聚类的步骤。

  • 开始时,将每个数据点视为一个聚类。开始时的聚类数量为 K 就是数据点的数量
  • 通过连接两个最接近的数据点形成一个簇(类),从而形成 K-1 个簇(类)
  • 通过连接两个最接近的聚类,形成更多的聚类,从而形成 K-2 聚类。
  • 重复以上三个步骤,直到所有样本点形成一个大的聚类
  • 形成了一个聚类,就可以利用树状图用于不同任务来划分成多个聚类

有不同的方法来寻找群组之间的距离。距离本身可以是欧几里得距离或曼哈顿距离。以下是测量两个集群之间距离的一些备选方法

  • 测量两个聚类中最接近的点之间的距离
  • 测量两个群组中最远的点之间的距离
  • 测量两个集群的中心点之间的距离
  • 测量两个簇之间所有可能的组合点之间的距离,并取其平均值

树状图在分层聚类中的作用

一个大聚类由小聚类组合而成,组合关系可用树状图来表示,就被用来将聚类实际分割成多个相关数据点的聚类。让我们来看看它到底是怎么做的。

接下来我们用 numpy 数组表示的数据点集合,如下所示。

X = np.array([[5,3],
    [10,15],
    [15,12],
    [24,10],
    [30,30],
    [85,70],
    [71,80],
    [60,78],
    [70,55],
    [80,91],])
import matplotlib.pyplot as plt

labels = range(1, 11)
plt.figure(figsize=(10, 7))
plt.subplots_adjust(bottom=0.1)
plt.scatter(X[:,0],X[:,1], label='True Position')

for label, x, y in zip(labels, X[:, 0], X[:, 1]):
    plt.annotate(
        label,
        xy=(x, y), xytext=(-3, 3),
        textcoords='offset points', ha='right', va='bottom')
plt.show()

将样本点绘制到图上便于观察,并且给每个点一个标注,表示该样本点具体是哪一个点。

在上图中,我们不难发现样布点明显分为 2 群,图的做左下方(1-5)为一群而图右上方(6-10)又是一个群。然而实际问题中,样本点数量可能有是成千上万,而且数据点维度都是高维的数据。在这种情况下,我们仅凭观察是无法发现规律的。

002.png

回到层次聚类(hierarchical clustering)中树状图的使用,通过 scipy 库提供功能,我们可以将样本点绘制成树状图。

001.png

该算法首先在欧氏距离的基础上找到彼此最接近的两个点。如果我们回顾一下图1,就可以看到 2 和 3 样本点彼此最接近,而 7 和 8 样本点则彼此最接近。因此这两个点之间将首先形成一个集群。在图 2 中,已经样点 2 和 3 连接表示他们位于一个群,以及点 8 和 7 的树状图。从图2 可以看出,8 和 7 样本点之间的欧氏距离大于 2 和 3 点之间的距离。

006.png

下一步是将两点形成的聚类与下一个最近的聚类或点连接起来,这又会形成另一个聚类。如果你看一下图表1,第 4 点离第 2 和第 3 点的聚类最近,因此在图表 2 中,将第 4 点与第 2 和第 3 点的树状图连接起来,从而得到新的树状图。这个过程一直持续到所有的点被连接在一起形成一个大的聚类。

007.png

当形成一个大的聚类后,可以在树状图同水平划线来来进行聚类,不同位置水平线会得到不同类别的聚类方式。

009.png

我们可以看到,没有任何水平线通过的最大垂直距离是由蓝线表示的。所以我们画一条新的水平红线,穿过蓝线,由于在两点上与蓝线相交,因此集群的数量将是 2。

基本上,这条水平线是一个阈值,它定义了成为一个独立集群所需的最小距离。如果我们再往下画一条线,成为一个新聚类所需的阈值就会降低,更多的聚类就会形成,如下图所示。

在上图中,水平线穿过四条垂直线,导致四个集群:6、7、8 和 10 点的集群,3、2、4 点的集群,9 和 5 点将被视为单点的集群。

010.png

下一步是导入聚类的类,并调用其fit_predict方法来预测每个数据点所属的聚类。

from sklearn.cluster import AgglomerativeClustering

cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='ward')
cluster.fit_predict(X)

在上面的代码中,我们从 sklearn.cluster 库中导入 AgglomerativeClustering类。使用n_clusters参数将参数的数量设置为 2,而亲和力设置为 euclidean(数据点之间的距离)。最后链接参数被设置为 ward,这使得集群之间的变异最小。

接下来我们从AgglomerativeClustering 类的变量 cluster 中调用 fit_predict 方法。这个方法返回每个数据点所属的聚类的名称。,看看数据点是如何被聚类的。

print(cluster.labels_)

输出是一个由10个元素组成的一维数组,对应于分配给我们10个数据点的聚类。

[1 1 1 1 1 0 0 0 0]

008.png