KMeans向量化实现更新了群集质心 Numpy Pro

问题描述

我将在python中实现kmeans。在一次迭代中,我计算了每150个点的中心标签:

label = 
array([0,1,2,3,4,5,6,7,5],dtype=int64)

和最初的8个中心:

centers =
array([[5.1,3.5,1.4,0.2],[4.9,3.,[4.7,3.2,1.3,[4.6,3.1,1.5,[5.,3.6,[5.4,3.9,1.7,0.4],3.4,0.3],0.2]])

X是虹膜数据X.shape =(150,4):

X =
array(  [5.1,3.8,[5.1,3.7,1.,3.3,0.5],[4.8,1.9,1.6,[5.2,...

现在,我想基于当前的中心标签来更新中心。这意味着迭代标签中的唯一值。然后提取X中的所有对应点,并基于所有提取的点计算中心。最后更新中心。例如,在第一次迭代中,提取带有标签0的X中的所有元素。然后计算center(每个维度的均值)。然后将center [0]更新为新中心。以此类推,标签1、2 ...

这是原始kmeans算法的一次迭代。我的问题是我该如何以numpy向量化的方式编写此步骤,而不是循环遍历。

解决方法

更新中心

您可以使用boolean array indexingcomputation along an axis仅显式地遍历群集,而不是遍历每个数据点。

K = 8
for k in range(K):
    centers[k] = X[label==k].mean(axis=0)

更新标签

这也可以通过遍历所有集群来完成:

distances = np.empty(shape=(X.shape[0],K))
for k in range(K):
    distances[:,k] = np.sqrt(np.sum((X - centers[k])**2,axis=1))
labels = distances.argmin(axis=1)

但是通过利用矩阵乘法是成对的点积,也可以在没有显式循环的情况下完成。

squared_distances = np.sum(centers**2,axis=1) + (np.sum(X**2,axis=1) - 2*centers @ X.T).T
squared_distances[np.isclose(squared_distances,0)] = 0  # self-distance can become slightly negative with this method (floating point precision problem)
distances = np.sqrt(squared_distances)
labels = distances.argmin(axis=1)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...