如何自动确定聚类数量?

我一直在尝试下面的脚本:

from sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.cluster import KMeansfrom sklearn.metrics import adjusted_rand_scoreimport textractimport osfolder_to_scan = '/media/sf_Documents/clustering'dict_of_docs = {}# Gets all the files to scan with textractfor root, sub, files in os.walk(folder_to_scan):    for file in files:        full_path = os.path.join(root, file)        print(f'Processing {file}')        try:            text = textract.process(full_path)            dict_of_docs[file] = text        except Exception as e:            print(e)vectorizer = TfidfVectorizer(stop_words='english')X = vectorizer.fit_transform(dict_of_docs.values())true_k = 3model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)model.fit(X)print("Top terms per cluster:")order_centroids = model.cluster_centers_.argsort()[:, ::-1]terms = vectorizer.get_feature_names()for i in range(true_k):    print("Cluster %d:" % i,)    for ind in order_centroids[i, :10]:        print(' %s' % terms[ind],)

这个脚本会扫描一个包含扫描文档图片的文件夹,提取文本然后对文本进行聚类。我知道这些文档有三种不同的类型,所以我将true_k设置为3。但是,如果我有一个包含未知文档的文件夹,其中可能有从1到100种不同的文档类型,该怎么办呢?


回答:

这是一个难以捉摸的领域,因为在没有真实标签的情况下,很难衡量你的聚类算法的效果有多“好”。为了进行自动选择,你需要有一个指标来比较KMeans在不同n_clusters值下的表现。

一个常用的选择是轮廓系数。你可以在这里找到更多关于它的详细信息:这里。这是scikit-learn的文档:

轮廓系数是通过每个样本的平均 intra-cluster 距离(a)和平均最近的 cluster 距离(b)计算得出的。样本的轮廓系数为(b – a)/ max(a, b)。需要说明的是,b 是样本与其不属于的最近 cluster 之间的距离。请注意,轮廓系数仅在标签数量为 2 <= n_labels <= n_samples – 1 时定义。

因此,你只能计算n_clusters >= 2的轮廓系数,这可能对你来说是一个限制,鉴于你的问题描述。

这是你如何在一个虚拟数据集上使用它(你可以根据自己的代码进行调整,这只是为了提供一个可复制的示例):

from sklearn.datasets import load_irisfrom sklearn.cluster import KMeansfrom sklearn.metrics import silhouette_scoreiris = load_iris()X = iris.datasil_score_max = -1 #这是可能的最低分数for n_clusters in range(2,10):  model = KMeans(n_clusters = n_clusters, init='k-means++', max_iter=100, n_init=1)  labels = model.fit_predict(X)  sil_score = silhouette_score(X, labels)  print("The average silhouette score for %i clusters is %0.2f" %(n_clusters,sil_score))  if sil_score > sil_score_max:    sil_score_max = sil_score    best_n_clusters = n_clusters

这将返回:

The average silhouette score for 2 clusters is 0.68The average silhouette score for 3 clusters is 0.55The average silhouette score for 4 clusters is 0.50The average silhouette score for 5 clusters is 0.49The average silhouette score for 6 clusters is 0.36The average silhouette score for 7 clusters is 0.46The average silhouette score for 8 clusters is 0.34The average silhouette score for 9 clusters is 0.31

因此,你将得到best_n_clusters = 2(注意:实际上,Iris有三个类别…)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注