每次运行Python scikit learn后集群结果的变化

2024-09-28 23:31:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一堆句子,我想用scikit学习谱聚类对它们进行聚类。我已经运行了代码,结果没有问题。但是,每次运行都会得到不同的结果。我知道这是入会的问题,但我不知道如何解决。这是我的代码的一部分,运行在句子上:

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的代码:

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)

谢谢你的帮助。


Tags: 代码truedataenglishtf聚类句子fit
3条回答

使用k-means时,需要在KMeans中设置random_state参数(请参见documentation)。将其设置为int或^{}实例。

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不是一个确定性算法。它通常从一些随机初始化过程开始,这种随机性意味着不同的运行将从不同的点开始。播种伪随机数生成器可确保相同种子的随机性始终相同。

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

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

这是我从Kaggler中窃取的代码-除了将random_state设置为seed之外,还可以使用KMeans返回的k-mean模型对其他数据集进行聚类。这相当有效。但是,我找不到官方的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设置为int seed,也无法确保在不同的计算机上始终按相同的顺序对相同的数据进行分组。同一数据可以在一台计算机上群集为group 0,在另一台计算机上群集为group 1。但至少在使用相同的K-Means模型(在我的代码中是cluster_maker)时,我们确保来自另一个发行版的数据将以与原始数据集相同的方式进行集群。

如前所述,k-means通常通过随机化初始化来实现。你可以得到不同的结果。

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

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

相关问题 更多 >