k-means聚类向量量化时不理解这些RuntimeWarnings

Don't understand these RuntimeWarnings during k-means clustering vector quantization

我正在尝试实施 K-Means 聚类算法,但我经常收到以下错误

C:\Users\andre\AppData\Roaming\Python\Python37\site-packages\numpy\core\fromnumeric.py:3257:
    RuntimeWarning: Mean of empty slice.
out=out, **kwargs)

C:\Users\andre\AppData\Roaming\Python\Python37\site-packages\numpy\core\_methods.py:161:
    RuntimeWarning: invalid value encountered in double_scalars
ret = ret.dtype.type(ret / rcount)

我将问题追溯到我的代码部分,该部分试图通过取平均值来找到新的质心。 'Points' 将变成一个空数组,导致我陷入 while 循环。我不明白为什么。

import numpy as np
from copy import deepcopy

def compute_euclidean_distance(vec1,vec2,ax):
    return np.linalg.norm(vec1 - vec2, axis = ax)

def initalise_centroids(dataset, k):
    rand_x = np.random.randint(np.min(dataset),np.max(dataset), size =k)
    rand_y = np.random.randint(np.min(dataset),np.max(dataset), size =k)
    centroids = np.array(list(zip(rand_x,rand_y)), dtype=np.float32)
    return centroids

def kmeans(dataset, k):
    err = 0
    cent = initalise_centroids(dataset,k)
    cOld = np.zeros(cent.shape)
    clusters = np.zeros(len(dataset))
    err = compute_euclidean_distance(cent, cOld, None)
    count = 0

    while err !=0:

        for i in range(len(dataset)):
            dist = compute_euclidean_distance(dataset[i], cent, 1)
            cluster = np.argmin(dist)
            clusters[i] = cluster

        cOld= deepcopy(cent)

        for i in range(k):
            points = [dataset[j] for j in range(len(dataset)) if clusters [j] == i ]
            cent[i] = np.mean(points,axis =0)

        err = compute_euclidean_distance(cent, cOld, None)
        print(err)
        count +=1

    return cent,clusters,err

我注意到两件事:

  1. 您的循环 while err != 0 很可能永远不会到达。通常用户会设置一个错误阈值,当实际错误低于该值时,循环将退出。在 Sklearn 的 Kmeans 文档中,您可以在 tol 参数中看到这一点。
  2. 您的第二个 for loop 假设每个集群都会分配一些点。情况可能并非如此。例如,我 运行 您的代码具有以下输入 [(1,100),(1,100),(100,100)], 2。你会认为该算法会收敛到前两个点和最后一个点的两个集群。
    但是当算法第一次初始化 运行dom 聚类中心时,它分配了 [[29,78],[62,25]]。在这种情况下,我所有的点都首先分配到集群 0
    因此,当您的第二个循环遍历 range(k) 的所有值时,簇 1 没有任何点,这就是您可能会在输出中看到 nan 值的原因。

您可能需要查看其他聚类中心初始化算法,例如 k-means++

希望对您有所帮助!