这是我参与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)又是一个群。然而实际问题中,样本点数量可能有是成千上万,而且数据点维度都是高维的数据。在这种情况下,我们仅凭观察是无法发现规律的。
回到层次聚类(hierarchical clustering)中树状图的使用,通过 scipy 库提供功能,我们可以将样本点绘制成树状图。
该算法首先在欧氏距离的基础上找到彼此最接近的两个点。如果我们回顾一下图1,就可以看到 2 和 3 样本点彼此最接近,而 7 和 8 样本点则彼此最接近。因此这两个点之间将首先形成一个集群。在图 2 中,已经样点 2 和 3 连接表示他们位于一个群,以及点 8 和 7 的树状图。从图2 可以看出,8 和 7 样本点之间的欧氏距离大于 2 和 3 点之间的距离。
下一步是将两点形成的聚类与下一个最近的聚类或点连接起来,这又会形成另一个聚类。如果你看一下图表1,第 4 点离第 2 和第 3 点的聚类最近,因此在图表 2 中,将第 4 点与第 2 和第 3 点的树状图连接起来,从而得到新的树状图。这个过程一直持续到所有的点被连接在一起形成一个大的聚类。
当形成一个大的聚类后,可以在树状图同水平划线来来进行聚类,不同位置水平线会得到不同类别的聚类方式。
我们可以看到,没有任何水平线通过的最大垂直距离是由蓝线表示的。所以我们画一条新的水平红线,穿过蓝线,由于在两点上与蓝线相交,因此集群的数量将是 2。
基本上,这条水平线是一个阈值,它定义了成为一个独立集群所需的最小距离。如果我们再往下画一条线,成为一个新聚类所需的阈值就会降低,更多的聚类就会形成,如下图所示。
在上图中,水平线穿过四条垂直线,导致四个集群:6、7、8 和 10 点的集群,3、2、4 点的集群,9 和 5 点将被视为单点的集群。
下一步是导入聚类的类,并调用其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]