UMAP+HDBSCAN+BERT句嵌入聚类时如何输出聚类点对应原始文本值
问题描述
基于句子嵌入做聚类时,需要将聚类标签映射回对应的原始文本,打印各聚类点对应的文本内容。
现有聚类实现代码如下:
umap_embeddings = umap.UMAP(n_neighbors=50, n_components=5, metric='cosine').fit_transform(embeddings) cluster = hdbscan.HDBSCAN(min_cluster_size=3, metric='euclidean', cluster_selection_method='eom').fit(umap_embeddings) # Prepare data umap_data = umap.UMAP(n_neighbors=15, n_components=2, min_dist=0.0, metric='cosine', random_state=24).fit_transform(embeddings) result = pd.DataFrame(umap_data, columns=['x', 'y']) result['labels'] = cluster.labels_ # Visualize clusters fig, ax = plt.subplots(figsize=(20, 10)) outliers = result.loc[result.labels == -1, :] clustered = result.loc[result.labels != -1, :] plt.scatter(outliers.x, outliers.y, color='#202020', s=25) plt.scatter(clustered.x, clustered.y, c=clustered.labels, s=25, cmap='hsv_r')
此前参考同类方案使用如下代码提取指定簇文本:
textdata_with_label_113 = textData[clusterer.labels_ == 113]
执行后返回的是嵌入向量值,无法得到需要的原始文本内容。
问题原因
索引时使用的textData变量存储的是句子嵌入向量,而非原始文本集合;同时没有保证嵌入矩阵、聚类标签数组、原始文本集合三者的索引一一对应,因此无法通过标签直接筛出原文。
实现方法
- 前置要求:在生成句子嵌入前,将所有待聚类的原始文本按输入顺序存入列表(示例命名为
raw_texts),严格保证列表元素顺序和送入UMAP、HDBSCAN训练的embeddings矩阵行顺序完全对齐,即raw_texts[i]为生成embeddings[i]的原始句子,中途如果对嵌入做筛选、打乱操作,必须同步对raw_texts做完全相同的处理。 - 索引逻辑:聚类完成后
cluster.labels_数组长度和embeddings、raw_texts长度完全一致,数组每个位置的标签值,对应该索引位置原始文本的聚类归属,直接通过布尔索引即可筛出目标簇的所有原文。
代码示例
基础列表方式提取
# 提前保留原始文本顺序(需在生成embeddings前执行) raw_texts = list(your_original_corpus) # 原有嵌入、聚类逻辑保持不变 # ...(省略已写的UMAP、HDBSCAN训练代码) # 提取标签为113的簇的所有原始文本 target_label = 113 cluster_texts = [text for idx, text in enumerate(raw_texts) if cluster.labels_[idx] == target_label] # 打印输出该簇全部文本 for text in cluster_texts: print(text)
Pandas方式提取
可以直接将原始文本作为列加入已有的结果DataFrame,后续查询更便捷:
result = pd.DataFrame(umap_data, columns=['x', 'y']) result['labels'] = cluster.labels_ # 按顺序加入原始文本列 result['raw_text'] = raw_texts # 提取标签为113的簇文本 textdata_with_label_113 = result[result['labels'] == 113]['raw_text'].tolist()
提示:如果需要提取离群点(标签值为-1的样本)的文本,只需要将判断条件中的目标标签值替换为-1即可。
内容的提问来源于stack exchange,提问作者Tam
相关产品推荐
相关产品推荐

