19

我有一堆句子,我想使用 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)

数据是句子的列表。每次代码运行时,我的聚类结果都会有所不同。如何使用光谱聚类获得一致的结果。我对 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)

感谢您的帮助。

4

4 回答 4

31

使用 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)

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

不过,我不确定光谱聚类示例。来自参数的文档:“用于在K-Means 初始化random_state时初始化 lobpcg 特征向量分解的伪随机数生成器。” eigen_solver == 'amg'在这些情况下似乎不包含 OP 的代码,尽管设置参数可能值得一试。

于 2014-09-18T20:30:51.400 回答
6

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

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

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

于 2014-10-03T18:17:46.933 回答
1

我有一个类似的问题,但我希望来自另一个分布的数据集以与原始数据集相同的方式进行聚类。例如,原始数据集的所有彩色图像都在 中,原始数据集的cluster 0所有灰度图像都在cluster 1. 对于另一个数据集,我希望彩色图像/灰色图像也在cluster 0其中cluster 1

这是我从 Kaggler 窃取的代码 - 除了将 设置random_state为种子之外,您还使用返回的 k-mean 模型KMeans对其他数据集进行聚类。这工作得相当好。但是,我找不到scikit-Learn这样说的官方文件。

# reference - https://www.kaggle.com/kmader/normalizing-brightfield-stained-and-fluorescence
from sklearn.cluster import KMeans

seed = 42
def create_color_clusters(img_df,  cluster_count = 2, cluster_maker=None):
    if cluster_maker is None:
        cluster_maker = KMeans(cluster_count, random_state=seed)
        cluster_maker.fit(img_df[['Green', 'Red-Green', 'Red-Green-Sd']])

    img_df['cluster-id'] = np.argmin(cluster_maker.transform(img_df[['Green', 'Red-Green', 'Red-Green-Sd']]),-1)


    return img_df, cluster_maker

# Now K-Mean your images `img_df` to two clusters
img_df, cluster_maker = create_color_clusters(img_df, 2)
# Cluster another set of images using the same kmean-model
another_img_df, _ = create_color_clusters(another_img_df, 2, cluster_maker)

但是,即使设置random_state为 aint seed也不能确保相同的数据在机器上总是以相同的顺序分组。相同的数据可以group 0在一台机器上进行聚类,也可以group 1在另一台机器上进行聚类。但至少使用相同的 K-Means 模型(cluster_maker在我的代码中),我们确保来自另一个分布的数据将以与原始数据集相同的方式进行聚类。

于 2018-03-17T17:06:34.277 回答
0

通常,当运行具有许多局部最小值的算法时,通常采用随机方法并以不同的初始状态多次运行算法。这将为您提供多个结果,通常选择误差最低的结果为最佳结果。

当我使用 K-Means 时,我总是运行它几次并使用最好的结果。

于 2014-09-25T02:37:08.350 回答