具有初始质心的 Kmeans 在 Matlab 和 Python 环境中给出不同的输出

Kmeans with initial centroids give different outputs in Matlab and Python environment

Matlab 和 Python 环境中 Kmeans 的输入如下:

input = [1.11, 0.81, 0.61, 0.62, 0.62, 1.03, 1.16, 0.44, 0.42, 0.73, 0.74, 0.65, 0.59, 0.64, 0.98, 0.89, 0.62, 0.95, 0.88, 0.60, 0.61, 0.62, 0.62, 0.64, 0.98, 0.90, 0.64]

Matlab:

[idx, C] = kmeans(input',3,'Start',[0.3;0.9;1.5]);

输出

C = [0.596, 0.825, 1.035]

(idx==1) = 15, (idx==2) = 6, (idx==3) = 6

Python:

import numpy as np
from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=3, n_init=1, init=np.array([0.3,0.9,1.5]).reshape(-1,1)).fit(np.array(input).reshape(-1, 1))
idx = kmeans.labels_
C = kmeans.cluster_centers_

输出

C = [0.430, 0.969, 0.637]

(idx==0) = 2, (idx==1) = 10, (idx==2) = 15

显然,对于这些环境,输出质心和分类在 3 个集群中的输入点数是不同的。即使初始质心相同,这背后的原因是什么?

我写了一个最小的 kmeans 算法来用 matlab 测试你的数据集:

input = [1.11, 0.81, 0.61, 0.62, 0.62, 1.03, 1.16, 0.44, 0.42, 0.73, 0.74, 0.65, 0.59, 
         0.64, 0.98, 0.89, 0.62, 0.95, 0.88, 0.60, 0.61, 0.62, 0.62, 0.64, 0.98, 0.90, 
         0.64];

c     = [0.3;0.9;1.5]

for ii = 1:10
    [~,idx] = min(abs(c-input));         % pairwise euclidian distance
    c = accumarray(idx.',input,[],@mean) % compute the new centroid
end

第一次迭代后,索引 idx 表明每个值最接近的质心,如下所示:

 2   2   2   2   2   2   2   1   1   2...

最后一个质心(1.5 这里)从来不是最接近的值!因此,为了保留 3 个组,kmeans 算法必须以某种方式计算此质心的新值(因为很难计算空集的平均值)。看起来 python 和 matlab 有不同的实现。

如果您想避免此问题,请确保每个初始质心至少是数据集中一个元素的最接近值。

例如,您可以获取数据集的前三个不同值。