每次运行Python scikit-learn后,聚类结果的变化

use*_*235 8 python cluster-analysis k-means spectral scikit-learn

我有一堆句子,我想用scikit-learn谱聚类来聚类它们.我运行代码并获得结果没有问题.但是,每次我运行它都会得到不同的结果.我知道这是启动的问题,但我不知道如何解决它.这是我在句子上运行的代码的一部分:

vectorizer = TfidfVectorizer(norm='l2',sublinear_tf=True,tokenizer=tokenize,stop_words='english',charset_error="ignore",ngram_range=(1, 5),min_df=1)
X = vectorizer.fit_transform(data)
# connectivity matrix for structured Ward
connectivity = kneighbors_graph(X, n_neighbors=5)
# make connectivity symmetric
connectivity = 0.5 * (connectivity + connectivity.T)
distances = euclidean_distances(X)
spectral = cluster.SpectralClustering(n_clusters=number_of_k,eigen_solver='arpack',affinity="nearest_neighbors",assign_labels="discretize")
spectral.fit(X)
Run Code Online (Sandbox Code Playgroud)

数据是句子列表.每次代码运行时,我的聚类结果都不同.如何使用光谱聚类获得一致的结果.我对Kmean也有同样的问题.这是我对Kmean的代码:

vectorizer = TfidfVectorizer(sublinear_tf=True,stop_words='english',charset_error="ignore")
X_data = vectorizer.fit_transform(data)
km = KMeans(n_clusters=number_of_k, init='k-means++', max_iter=100, n_init=1,verbose=0)
km.fit(X_data)
Run Code Online (Sandbox Code Playgroud)

我感谢你的帮助.

Rog*_*Fan 22

使用k-means时,您需要设置random_state参数KMeans(请参阅文档).将其设置为int或RandomState实例.

km = KMeans(n_clusters=number_of_k, init='k-means++', 
            max_iter=100, n_init=1, verbose=0, random_state=3425)
km.fit(X_data)
Run Code Online (Sandbox Code Playgroud)

这很重要,因为k-means不是确定性算法.它通常以一些随机初始化过程开始,这种随机性意味着不同的运行将从不同的点开始.播种伪随机数发生器可确保相同种子的随机性始终相同.

我不确定光谱聚类的例子.从文档上的random_state参数:"用于lobpcg固有的初始化的伪随机数发生器矢量分解时eigen_solver == 'amg'由所述K均值初始化和".虽然设置参数可能值得一试,但OP的代码似乎并未包含在这些情况中.


Ano*_*sse 6

正如其他人已经指出的,k-means 通常是通过随机初始化来实现的。这是故意的,你可以得到不同的结果。

该算法只是一种启发式算法。它可能会产生次优的结果。多次运行它会给你一个更好的机会找到一个好的结果。

在我看来,当每次运行的结果差异很大时,这表明数据根本不能很好地与 k-means 聚类。在这种情况下,您的结果并不比随机好多少。如果数据真的适合k-means聚类,结果会比较稳定!如果它们不同,则簇的大小可能不同,或者可能没有很好地分离;和其他算法可能会产生更好的结果。

  • 如果我使用 `n_init=10` 并指定 `random_state`,如 `n_init=10, random_state=0` ,这有意义吗?`n_init` 是 k-means 算法使用不同质心种子运行的次数。由于固定的“random_state”,质心是否会改变? (2认同)