Numpy 如何从联合/距离矩阵中计算聚类分配
聚类是一种常见的数据分析技术,用于将数据集中的观测值划分为几个不同的组或类别。其中一种常用的方法是层次聚类,它可以通过一系列的步骤,将数据集中的观测值聚集为一个或多个群集。在层次聚类的过程中,我们需要通过联合矩阵或距离矩阵来表示每个观测值或群集之间的相似度。本文将介绍如何使用Numpy库来计算基于距离/联合矩阵的聚类分配。
阅读更多:Numpy 教程
距离矩阵和联合矩阵的介绍
在层次聚类中,我们需要制定一个度量来表示不同观测值之间的距离或相似度。通常情况下,我们使用欧几里得距离(Euclidian distance)或曼哈顿距离(Manhattan distance)来度量。在计算距离矩阵时,我们需要将每个观测值的距离计算出来,并组成一个矩阵。下面是一个例子:
import numpy as np
# 假设我们有4个观测值
x1 = np.array([1,2,3])
x2 = np.array([4,5,6])
x3 = np.array([7,8,9])
x4 = np.array([10,11,12])
# 计算每对观测值之间的欧几里得距离
dist_matrix = np.zeros((4,4))
for i in range(4):
for j in range(i+1, 4):
dist = np.linalg.norm(eval(f'x{i+1}-x{j+1}'))
dist_matrix[i,j] = dist
dist_matrix[j,i] = dist
print(dist_matrix)
输出的距离矩阵为:
array([[ 0. , 5.19615242, 10.39230485, 15.58845727],
[ 5.19615242, 0. , 5.19615242, 10.39230485],
[10.39230485, 5.19615242, 0. , 5.19615242],
[15.58845727, 10.39230485, 5.19615242, 0. ]])
距离矩阵中的每个元素表示两个观测的距离。由于距离是对称的,因此矩阵沿着对角线对称。实际上,距离矩阵可以通过距离公式自动计算得出,如下所示:
from scipy.spatial.distance import pdist, squareform
dist_matrix = squareform(pdist(np.vstack((x1,x2,x3,x4))))
不同之处在于这里是使用了SciPy库中的pdist和squareform函数,它们可以自动计算和转换距离矩阵以优化性能。
另一个常用的矩阵形式是联合矩阵(linkage matrix)。一个联合矩阵是从距离矩阵中生成的,它表示了在聚类过程中如何合并不同的观测值或群集,从而形成一个或多个新的群集。联合矩阵通常由四列组成,分别代表两个合并的群集的索引和它们之间的距离,以及新的群集的大小。下面是一个示例:
from scipy.clusterimport hierarchy
# 假设我们有4个观测值
x1 = np.array([1,2,3])
x2 = np.array([4,5,6])
x3 = np.array([7,8,9])
x4 = np.array([10,11,12])
# 计算每对观测值之间的欧几里得距离
dist_matrix = squareform(pdist(np.vstack((x1,x2,x3,x4))))
# 执行层次聚类并生成联合矩阵
Z = hierarchy.linkage(dist_matrix)
print(Z)
输出的联合矩阵为:
array([[ 0. , 1. , 5.19615242, 2. ],
[ 2. , 3. , 5.19615242, 2. ],
[ 4. , 5. , 5.19615242, 2. ]])
联合矩阵中的每一行表示一次合并。例如,第一行[0, 1, 5.19615242, 2]表示将第0个点和第1个点合并成一个新的点,并且它们之间的距离为5.19615242,新的点中包含了原来两个点的合并。
从联合矩阵中计算聚类分配
一旦我们有了联合矩阵或距离矩阵,我们就可以使用Numpy库中的函数来计算聚类分配。其中,fcluster函数是最常用的一个函数,它可以根据给定的联合矩阵或距离矩阵以及阈值来计算聚类分配。下面是一个示例:
from scipy.cluster.hierarchy import fcluster
# 假设我们有4个观测值
x1 = np.array([1,2,3])
x2 = np.array([4,5,6])
x3 = np.array([7,8,9])
x4 = np.array([10,11,12])
# 计算每对观测值之间的欧几里得距离
dist_matrix = squareform(pdist(np.vstack((x1,x2,x3,x4))))
# 执行层次聚类并生成联合矩阵
Z = hierarchy.linkage(dist_matrix)
# 根据给定的阈值计算聚类分配
clusters = fcluster(Z, 3, criterion='maxclust')
print(clusters)
输出的聚类分配为:
array([1, 1, 2, 3], dtype=int32)
在上面的示例中,我们使用了阈值3来计算聚类分配。这意味着我们将数据集划分为最多3个群集。由于数据集中有4个观测值,因此我们得到了3个不同的聚类分配。具体来说,第1个观测值和第2个观测值被分配到了第1个群集中,第3个观测值被分配到了第2个群集中,第4个观测值被分配到了第3个群集中。
在实际应用中,我们可以使用一些指标来确定最佳的阈值,如肘部法则(elbow method)和轮廓系数(silhouette coeficient)。这些方法可以帮助我们找到最优的聚类分配,以探索数据集的内在结构。
总结
本文介绍了如何使用Numpy库来计算基于联合/距离矩阵的聚类分配。具体来说,我们介绍了如何计算距离矩阵和联合矩阵,并且通过示例展示了如何使用fcluster函数来计算聚类分配。聚类分析是一种常用的数据分析技术,它可以帮助我们探索数据集的内在结构,并且有助于在数据挖掘、图像分析、自然语言处理等领域中实现高效的机器学习算法。Numpy库提供了丰富的聚类分析工具和函数,可以帮助我们更好地理解和分析数据集。
极客教程