如何可视化每个 HDBSCAN 集群上的热门术语
How to visualise top terms on each HDBSCAN cluster
我目前正在尝试使用 HDBSCAN 对一堆电影数据进行聚类,以便将相似的内容分组在一起并能够提出 'topics' 来描述这些聚类。我对 HDBSCAN 很感兴趣,因为我知道它被认为是软聚类,而不是 K-Means,后者更适合我的目标。
执行 HDBSCAN 后,我能够找到每个集群中放置的电影。我现在想要的是 terms/words 代表每个集群。
我用 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 执行此操作,因为我知道它没有聚类中心。我一直在查看文档,但我对此还很陌生,无法解决我的问题。
任何想法将不胜感激!谢谢你的时间。
参考 HDBSCAN tutorial。对于算法聚类的每个样本,它还关联一个概率,该概率可以被认为是样本与聚类关联的强度。您可以过滤每个聚类的样本及其对应的概率;使用概率来确定每个集群的最高点。 link 有更多细节。
我 运行 遇到了类似的问题,并根据@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
我目前正在尝试使用 HDBSCAN 对一堆电影数据进行聚类,以便将相似的内容分组在一起并能够提出 'topics' 来描述这些聚类。我对 HDBSCAN 很感兴趣,因为我知道它被认为是软聚类,而不是 K-Means,后者更适合我的目标。
执行 HDBSCAN 后,我能够找到每个集群中放置的电影。我现在想要的是 terms/words 代表每个集群。
我用 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 执行此操作,因为我知道它没有聚类中心。我一直在查看文档,但我对此还很陌生,无法解决我的问题。
任何想法将不胜感激!谢谢你的时间。
参考 HDBSCAN tutorial。对于算法聚类的每个样本,它还关联一个概率,该概率可以被认为是样本与聚类关联的强度。您可以过滤每个聚类的样本及其对应的概率;使用概率来确定每个集群的最高点。 link 有更多细节。
我 运行 遇到了类似的问题,并根据@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