为什么kmeans每次都给出完全相同的结果?

我已经重新运行 kmeans 4 次并得到

enter image description here

从其他答案,我明白了

每次 K-Means 初始化质心时,它都是随机生成的。

你能解释一下为什么每次结果都完全相同吗?

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt 
from sklearn.cluster import KMeans
%config InlineBackend.figure_format = 'svg' # Change the image format to svg for better quality
don = pd.read_csv('https://raw.githubusercontent.com/leanhdung1994/Deep-Learning/main/donclassif.txt.gz', sep=';')

fig, ax = plt.subplots(nrows=2, ncols=2, figsize= 2 * np.array(plt.rcParams['figure.figsize']))

for row in ax:
    for col in row:
        kmeans = KMeans(n_clusters = 4)
        kmeans.fit(don)
        y_kmeans = kmeans.predict(don)
        col.scatter(don['V1'], don['V2'], c = y_kmeans, cmap = 'viridis')
        centers = kmeans.cluster_centers_
        col.scatter(centers[:, 0], centers[:, 1], c = 'red', s = 200, alpha = 0.5);

plt.show()
stack overflow Why does kmeans give exactly the same results everytime?
原文答案
author avatar

接受的答案

我发布@AEF 的评论以将此问题从未答复列表中删除。

随机初始化并不一定意味着随机结果。最简单的示例:k=1 的 k-means 总是在一步中找到平均值,无论中心在哪里初始化。


答案:

作者头像

他们不一样。他们很相似。 K-means 是一种算法,它在某种程度上迭代地移动质心,以便它们在拆分数据时变得越来越好,虽然这个过程是确定性的,但你必须为这些质心选择初始值,这通常是随机完成的。随机开始,并不意味着最终的质心是随机的。他们会汇聚到一些相对较好且通常相似的东西上。

通过这个简单的修改查看您的代码:

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt 
from sklearn.cluster import KMeans
%config InlineBackend.figure_format = 'svg' # Change the image format to svg for better quality
don = pd.read_csv('https://raw.githubusercontent.com/leanhdung1994/Deep-Learning/main/donclassif.txt.gz', sep=';')

fig, ax = plt.subplots(nrows=2, ncols=2, figsize= 2 * np.array(plt.rcParams['figure.figsize']))

cc = []

for row in ax:
    for col in row:
        kmeans = KMeans(n_clusters = 4)
        kmeans.fit(don)
        cc.append(kmeans.cluster_centers_)
        y_kmeans = kmeans.predict(don)
        col.scatter(don['V1'], don['V2'], c = y_kmeans, cmap = 'viridis')
        centers = kmeans.cluster_centers_
        col.scatter(centers[:, 0], centers[:, 1], c = 'red', s = 200, alpha = 0.5);

plt.show()

cc

如果您查看这些质心的确切值,它们将如下所示:

[array([[ 4.97975722,  4.93316461],
        [ 5.21715504, -0.18757547],
        [ 0.31141141,  0.06726803],
        [ 0.00747797,  5.00534801]]),
 array([[ 5.21374245, -0.18608103],
        [ 0.00747797,  5.00534801],
        [ 0.30592308,  0.06549162],
        [ 4.97975722,  4.93316461]]),
 array([[ 0.30066361,  0.06804847],
        [ 4.97975722,  4.93316461],
        [ 5.21017831, -0.18735444],
        [ 0.00747797,  5.00534801]]),
 array([[ 5.21374245, -0.18608103],
        [ 4.97975722,  4.93316461],
        [ 0.00747797,  5.00534801],
        [ 0.30592308,  0.06549162]])]

相似但不同的价值观。

还:

查看 KMeans 的默认参数。有一个叫做 n_init:

k-means 算法将使用不同质心种子运行的次数。最终的结果将是 n_init 连续运行在惯性方面的最佳输出。

默认情况下它等于 10。这意味着每次运行 k-means 它实际上运行 10 次并选择最好的结果。与单次 k-means 运行的结果相比,这些最佳结果将更加相似。

作者头像

每当随机化是 Scikit-learn 算法的一部分时,可以提供 random_state 参数来控制所使用的随机数生成器。请注意,仅仅存在 random_state 并不意味着总是使用随机化,因为它可能取决于另一个参数,例如洗牌,正在设置。

传递的值将影响函数返回结果的可重复性(fit、split 或任何其他函数,如 k_means)。 random_state 的值可能是:

供参考: https://scikit-learn.org/stable/glossary.html#term-random_state