Kmean聚类集群中的顶级术语

时间:2017-11-23 09:39:16

标签: python scikit-learn cluster-analysis k-means

我正在使用python Kmean聚类算法用于集群文档。我创建了一个术语 - 文档矩阵

   from sklearn.feature_extraction.text import TfidfVectorizer
   from sklearn.cluster import KMeans
   vectorizer = TfidfVectorizer(tokenizer=tokenize, encoding='latin-1',
                          stop_words='english')
    X = vectorizer.fit_transform(token_dict.values())

然后我使用以下代码

应用了Kmean聚类
 km = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
 y=km.fit(X)

我的下一个任务是查看每个群集中的顶级术语,搜索googole建议许多人使用km.cluster_centers_.argsort()[:,:: - 1]来查找顶部术语使用以下代码创建集群:

 print("Top terms per cluster:")
 order_centroids = km.cluster_centers_.argsort()[:, ::-1]
 terms = vectorizer.get_feature_names()
 for i in range(true_k):
     print("Cluster %d:" % i, end='')
     for ind in order_centroids[i, :10]:
         print(' %s' % terms[ind], end='')
         print()

现在我的问题是,根据我的理解,km.cluster_centers_返回集群中心的协调,例如,如果有100个要素和三个集群,它将返回一个3行和100列的矩阵,表示质心为每个集群。我希望了解如何在上面的代码中使用它来确定集群中的顶级术语。 谢谢任何评论表示赞赏 Nadeem

2 个答案:

答案 0 :(得分:3)

您对群集中心的形状和含义是正确的。因为您正在使用Tf-Idf矢量化器,所以您的“特征”是给定文档中的单词(并且每个文档都是它自己的向量)。因此,当您对文档向量进行聚类时,质心的每个“特征”表示该单词与其的相关性。 “word”(在词汇表中)=“feature”(在你的向量空间中)=“column”(在你的质心矩阵中)

get_feature_names调用获取列索引到它所代表的单词的映射(所以从文档中可以看出......如果这不能按预期工作,只需将vocabulary_矩阵反转为得到相同的结果)。

然后.argsort()[:, ::-1]行将每个质心转换为其中最“相关”(高值)列的排序(降序)列表,因此最相关的词(因为词=列)。 / p>

其余代码只是打印,我确信不需要任何解释。所有代码实际上都是按照其中最有价值的特征/单词的降序对每个质心进行排序,然后将这些列映射回原始单词并打印出来。

答案 1 :(得分:0)

比赛进行得有点晚,但是我有同样的问题,但是找不到满意的答案。

这就是我所做的:

from sklearn.cluster import MiniBatchKMeans
from sklearn.feature_extraction.text import TfidfVectorizer

# documents you are clustering
docs = ['first document', 'second', 'thrid doc', 'etc.']

# init vectorizer
tfidf = TfidfVectorizer()

# fit vectorizer
tfidf.fit(docs)

# create vecs for your sents
vecs = tfidf.transform(docs)

# fit your kmeans cluster to vecs
# don't owrry about the hyperparameters
clusters = MiniBatchKMeans(
    n_clusters=16, 
    init_size=1024, 
    batch_size=2048, 
    random_state=20
).fit_predict(vecs)

# get dict of {keyword id: keyword name}
labels = tfidf.get_feature_names()

def get_cluster_keywords(vecs, clusters, docs, labels, top_n=10):
    # init a dict where we will count term occurence
    cluster_keyword_ids = {cluster_id: {} for cluster_id in set(clusters)}
    
    # loop through the vector, cluster and content of each doc
    for vec, i, sent in zip(vecs, clusters, docs):
        
        # inspect non zero elements of rows of sparse matrix
        for j in vec.nonzero()[1]:
            
            # check we have seen this keword in this cluster before
            if j not in cluster_keywords[i]:
                cluster_keyword_ids[i][j] = 0
            
            # add a count
            cluster_keyword_ids[i][j] += 1

    # cluster_keyword_ids contains ids
    # we need to map back to keywords
    # do this with the labels param
    return {
        cluster_id: [
            labels[keyword_id] # map from kw id to keyword
            
            # sort through our keyword_id_counts
            # only return the top n per cluster
            for keyword_id, count in sorted(
                keyword_id_counts.items(),
                key=lambda _id, count: count, # sort from highest count to lowest
                reverse=True
            )[:top_n]
        ] for cluster_id, keyword_id_counts in cluster_keyword_ids.items()
    }