我正在尝试实现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)
我将问题追溯到我的代码部分,该部分尝试通过取平均值来查找新质心。 “点”将变成一个空数组,导致我陷入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
答案 0 :(得分:0)
我注意到两件事:
while err != 0
很可能永远不会到达。通常,用户将设置一个错误阈值,以便当实际错误低于该值时,循环将退出。在Sklearn的Kmeans文档中,您可以在tol
参数中看到这一点。for loop
假定每个聚类将分配一些点。事实并非如此。例如,我使用以下输入[(1,100),(1,100),(100,100)], 2
运行了您的代码。您会认为该算法将收敛为前两个点和最后一个点的两个聚类。[[29,78],[62,25]]
。在这种情况下,我的所有点首先都分配到了群集0
中。range(k)
的所有值时,群集1
没有任何意义,这就是为什么您可能在输出中看到nan
值的原因。 您可能希望查看其他群集中心初始化算法,例如k-means++
希望有帮助!