如何可视化每个HDBSCAN群集上的热门术语

时间:2019-08-01 09:06:44

标签: python cluster-computing topic-modeling hdbscan

我目前正在尝试使用HDBSCAN对一堆电影数据进行聚类,以便将相似的内容分组在一起,并能够提出描述这些聚类的“主题”。我对HDBSCAN感兴趣,因为我知道它被认为是软集群,而不是K-Means,它更适合我的目标。

执行HDBSCAN之后,我能够找到带有电影的影片放置在每个群集中。我现在想要的是每个集群用哪些术语/单词表示。

我用KMeans做过类似的事情(下面的代码):

model = KMeans(n_clusters=70)
model.fit(text)
clusters=model.predict(text)
model_labels=model.labels_
output= model.transform(text)

titles=[]
for i in data['title']:
        titles.append(i)
genres=[]
for i in data['genres']:
        genres.append(i)

films_kmeans = { 'title': titles, 'info': dataset_list2, 'cluster': clusters, 'genre': genres }
frame_kmeans= pd.DataFrame(films_kmeans, index=[clusters])

print("Top terms per cluster:")
print()
#sort cluster centers by proximity to centroid
order_centroids = model.cluster_centers_.argsort()[:, ::-1] 
for i in range(70):
    print("Cluster %d:" % i),
    for ind in order_centroids[i, :5]:
        print(' %s' % tfidf_feature_names[ind]),
    print()
    print()

    print("Cluster %d titles:" % i, end='')
    for title in frame_kmeans.loc[i]['title'].values.tolist():
        print(' %s,' % title, end='')
    print() #add whitespace
    print() #add whitespace

print()

虽然这对于KMeans来说很好用,但我找不到类似的方法来对HDBSCAN进行此操作,因为我知道它没有群集中心。我一直在看文档,但是在这方面我还很陌生,我还无法解决我的问题。

任何想法将不胜感激!谢谢您的宝贵时间。

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,并从@ajmartin的建议中带头,下面的代码对我有用。 假设您有一个标签列表-label包含每个点的原始标签和一个HDBSCAN对象clusterer = hdbscan.HDBSCAN(min_cluster_size=10).fit(X)

from operator import itemgetter
from collections import defaultdict

def get_top_terms(k):
    top_terms = defaultdict(list)
    for c_lab, prob, text_lab in zip(clusterer.labels_, clusterer.probabilities_, label):
        top_terms[c_lab].append((prob, text_lab))

    for c_lab in top_terms:
        top_terms[c_lab].sort(reverse=True, key=itemgetter(0)) # sort the pair based on probability 

    # -- print the top k terms per cluster --    
    for c_lab in top_terms:
        print(c_lab, top_terms[c_lab][:k])
    return top_terms

# -- for visualization (add this snippet before plt.scatter(..))--
from collections import Counter

plt.figure(figsize=(16, 16))
plt.title('min_cluster_size=10')

plot_top=Counter() # to get only distinct labels, replace with a set and add a check here [1] 
top_terms = get_top_terms(10)

for i, lab, prob in zip(range(len(clusterer.labels_)),clusterer.labels_, clusterer.probabilities_): # pointwise iteration
    if plot_top[lab] < 10:      
        for el in top_terms[lab][:10]:
            if prob == el[0]: # [1] 
                plot_top[lab] += 1
                # x[i], y[i] are the projected points in 2D space 
                plt.annotate(el[1], (x[i],y[i]), horizontalalignment='center', verticalalignment='center', size=9.5)
                break

答案 1 :(得分:0)

参考HDBSCAN tutorial。对于通过算法聚类的每个样本,它还关联了一个概率,可以将其视为与聚类相关联的样本有多强。您可以过滤每个聚类的样本及其对应的概率;使用概率来确定每个聚类的最高点。该链接具有更多详细信息。