在Python Sklearn和Scipy中的聚合分级聚类法

438 阅读6分钟

简介

在本教程中,我们将看到在Python Sklearn和Scipy中实现聚类分层的方法。首先,我们将简单了解什么是分层聚类以及聚类的工作原理。然后,我们将创建我们自己的样本数据集,展示在Scipy中创建树状图和在Sklearn中实现聚类的例子。

什么是层次聚类?

层次聚类是一种无监督的聚类算法,用于创建具有树状层次结构的聚类。在这种聚类方法中,不需要向算法提供聚类的数量。 与此相反,其他的算法,如K-Mean,产生的是没有层次的平面聚类,我们也必须选择聚类的数量,开始。

什么是层次聚类中的树状图?

层次聚类创造了一个树状的图形结构,称为树枝图,它显示了表示聚类之间层次关系的合并/拆分序列。

树枝图的一个很好的现实世界的例子是表示动物王国的分类,如下图所示:

agglomerative clustering sklearn and scipy

(来源)

层次聚类的类型

分层聚类算法可以分为两种类型

  1. 分裂聚类--它采取自上而下的方法,在开始时整个数据观察被认为是一个大聚类。然后再把它分成两个聚类,然后是三个聚类,以此类推,直到每个数据最终成为一个独立的聚类。
  2. 聚合聚类它采取自下而上的方法,在开始时假定单个数据观察是一个聚类。然后,它开始将数据点合并到聚类中,直到最后用所有数据点创建一个最终的聚类。

理想情况下,分化和聚集的分层聚类都会产生相同的结果。然而,聚集聚类的计算速度很快,因此我们将在文章中进一步介绍。

聚合式聚类

正如我们前面所讨论的,聚类遵循一种自下而上的方法,首先将每个数据点放在自己的聚类中。然后,它将这些单独的聚类合并成越来越大的聚类,直到所有的数据点都被归入一个单一的聚类,也称为根,或者直到满足某些终止条件。

这就产生了我们上面讨论过的基于树状图的数据点表示法:

聚合聚类法的算法

1)每个数据点被分配为一个单独的聚类

  1. 确定距离测量并计算出距离矩阵

  2. 确定合并聚类的联系标准

  3. 更新距离矩阵

5)重复这个过程,直到每个数据点成为一个聚类

聚合式聚类的参数

聚合分层聚类可以有多种变化,这取决于亲和力和联系。让我们更详细地了解这一点。

亲和力

亲和力指的是计算数据点或聚类之间的距离或相似性所使用的方法。常见的有--

  • 欧几里得
  • 曼哈顿
  • 余弦法

链接

聚类是通过使用不同类型的标准或知识作为链接函数而形成的。联结方法使用我们上面讨论的亲和力。

不同的联结方法产生不同的层次聚类结果,它们列举如下

  • 单一的
  • 完整的
  • 平均值
  • 病房

以聚类数量为输入的聚类法

从根本上讲,聚类法不需要输入聚类的数量。然而,使用聚类法产生像K-means那样的平面聚类时,有可能将聚类的数量作为输入。虽然这里没有关于如何确定聚类数量的明确规则,但有一个很好的技巧,可以通过使用树状图来估计什么是好的聚类数量。我们将在下面的实际例子中看到这一点。

用Scipy和Sklearn进行聚类划分

现在让我们看看我们如何通过使用Python的Scipy和Sklearn包来实现聚类分级聚类。为了这个目的,我们将创建我们自己的玩具数据集样本,以便更好地进行可视化和理解。

导入库

首先,让我们导入所需的库,如下所示。

在[0]中:

import pandas as pd
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_blobs

数据集

这里我们使用Scikit Learn的sklearn.datasets包中的make_blobs模块来创建一个有两个特征的50个数据点的自定义玩具数据集。

在[1]中:

X, y = make_blobs(n_samples=50, centers=2, n_features=2,random_state=3)
df=pd.DataFrame(X,y)
df=df.rename(columns={0: "X1", 1:"X2"})
df.head()

输出[1]:

X1X2
1-3.336072-1.644337
00.0921663.139081
1-5.5525740.455115
0-0.2979075.047579
00.4193083.574362

在[2]:

plt.scatter(X[:, 0], X[:, 1], label=y)
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")

输出[2]:

agglomerative hierarchical clustering scipy and sklearn example

用Python Scipy创建树状图

Python Scipy在scipy.cluster.hierarchy包中有endrogramlinkage模块,可以用来创建聚类的endrogram图。

在这里,我们首先创建一个链接对象,方法为ward,亲和度量为euclidean,然后用它来创建树状图。

在[3]中:

#Dendrogram plot

输出[3]:

agglomerative hierarchical clustering dendrogram with scipy

用树状图确定聚类的数量

如果你想创建平坦的聚类,我们可以通过分析上述树状图来确定聚类的数量。我们首先假设水平线向两边延伸,因此,它们也会与垂直线相交。现在我们必须找出没有任何水平线穿过的最高的垂直线。

在上面的树状图中,这样的垂直线就是蓝线。现在我们在这条垂直线上画一条水平线,如下图所示。这条水平线在两个地方切断了垂直线,这意味着最优的集群数量是2。

另一种方法是直观地看到哪条垂直线显示出最大的跳跃。因为垂直线表示两个集群之间的距离或相似度,大跳表示这两个集群不是很相似。再一次通过这条垂直线画出水平线,它的切口数量就是最佳的集群数量。同样在我们的例子中,它是蓝色的线,水平线在两个地方切割,所以集群的数量是2。

(然而,应该注意的是,这些方法并不总是能保证最优的集群数量,它只是一个指导原则。)

agglomerative hierarchical clustering dendrogram with scipy - 1

用Sklearn进行聚类分析

我们现在使用sklearn.cluster包中的AgglomerativeClustering模块,通过传递集群数量为2(在上一节中确定)来创建平面集群。我们再次使用euclidean和ward作为参数。

这样就产生了两个聚类,从视觉上我们可以说,结果是好的,符合预期。

In[4]:

cluster_ea = AgglomerativeClustering(n_clusters=2, linkage='ward',affinity='euclidean')


Out[4]:

agglomerative hierarchical clustering with sklearn