随着文本数据量持续激增,组织和理解这些信息变得越来越具有挑战性。这就是文本聚类(一种无监督机器学习技术)发挥作用的地方。它允许我们根据内容将相似的文档分组在一起——而无需事先了解类别。
本文向你介绍了文本聚类世界,探讨了实用的三阶段流程,并为第 2 部分的主题建模奠定了基础。
为什么需要文本聚类?
文本聚类是发现大型文本数据集中隐藏模式和主题的重要工具,具有广泛的应用范围:
安装依赖项
建议在新的虚拟环境(如conda或venv)中开始,然后在该环境中安装所需的依赖项。
pip install sentence-transformers xformers bertopic datasets openai datamapplot plotly
数据集:arXiv NLP
为了实现这一目标,我们将使用来自 Hugging Face 的arXiv NLP 数据集的子分类版本,该数据集由Maarten Grootendorst编写,他是《Hands-On Large Language Models》一书的作者之一,该数据集包括:
加载数据集
# Load data from huggingface
from datasets import load_dataset
dataset = load_dataset("maartengr/arxiv_nlp")["train"]
# Extract metadata
abstracts = dataset["Abstracts"]
titles = dataset["Titles"]
这个数据集非常适合进行聚类探索,因为它涵盖了自然语言处理(NLP)领域内的多种主题。
三阶段流程:实际工作原理
让我们将技术流程分解为三个关键阶段:文档嵌入、降维和聚类。
阶段一:文档嵌入
第一步是将文本转换为能够捕捉语义意义的数值表示(嵌入)。为了获得最佳结果,我们从Hugging Face上的大规模文本嵌入基准(MTEB)排行榜中选择嵌入模型,该排行榜使用有效性度量(V-measure)指标专门评估模型在聚类性能上的表现。
在聚类任务中,表现最佳的模型展现出了一个有趣的权衡。观察聚类任务的“平均”列,我们可以在性能(分数范围在53-58之间)与实际限制(如模型大小和内存使用量)之间做出明智的决策。例如,虽然NV-Embed-v2取得了最高分(58.46),但stella-en-400M-v5模型在资源需求显著降低(4.35亿参数对比78亿)的情况下提供了具有竞争力的性能(56.7)。
在选择模型时,我们需要平衡三个关键因素:
对于大多数实际应用而言,像stella-en-400M-v5这样的模型提供了一个极佳的折衷方案——它提供了强大的聚类性能(平均分数为55.16),同时效率更高,仅使用1.62GB内存和8192个嵌入维度。这使得它成为了一个实际的选择,除非你绝对需要更大模型所带来的边际性能提升。因此,在本次练习中,我们将使用stella-en-400M-v5模型。
加载模型
from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer('dunzhang/stella_en_400M_v5', trust_remote_code=True)
embeddings = embedding_model.encode(abstracts, show_progress_bar=True)
创建嵌入
embeddings = embedding_model.encode(abstracts, show_progress_bar=True)
检查所得嵌入的维度
embeddings.shape
输出:(44949,1024)
以下图表将帮助我们更好地理解这一阶段所发生的事情。
虽然MTEB排行榜上显示stella-en-400M-v5模型的维度为8192,但实际实现中输出的嵌入维度为1024。这并不是需要担心的差异——模型开发者发现,1024维与8192维的性能几乎相同,MTEB分数仅相差微不足道的0.001。
阶段二:降维
高维嵌入可能计算成本高昂,并且经常包含噪声。我们使用统一流形近似和投影(UMAP)来降低维度。
与PCA相比,UMAP在文本聚类中更受欢迎,因为它:
虽然PCA更简单且更快,但UMAP捕捉复杂非线性关系的能力使其更适合用于文本嵌入降维。接下来,让我们看看代码的实际应用。
from umap import UMAP
# We reduce the input embeddings from 1024 dimenions to 10 dimenions
umap_model = UMAP(
n_components=10, # Reduces dimensionality while preserving essential structure
min_dist=0.0, # Controls how tightly points cluster together
metric='cosine', # Measures similarity between embeddings using cosine distance
random_state=42
)
# These parameters were chosen to optimize cluster separation while maintaining semantic relationships.
reduced_embeddings = umap_model.fit_transform(embeddings)
检查降维后嵌入的维度
reduced_embeddings.shape
输出:(44949, 10)
对发生的事情进行图形化表示。
每行仍然代表一个文档,但现在只有10个维度,而不是原来的1024个。
阶段三:聚类
最后,我们使用带噪声的应用程序的基于密度的空间层次聚类(HDBSCAN)对降维后的嵌入进行聚类。
HDBSCAN的优点包括:
由于HDBSCAN能够处理噪声数据,因此它特别适合用于文本聚类。让我们来看看它的实际应用效果。
from hdbscan import HDBSCAN
# We fit the model and extract the clusters
hdbscan_model = HDBSCAN(
min_cluster_size=50, # Ensures statistically significant groupings
metric='euclidean', # Measures distance in reduced space
cluster_selection_method='eom' # Optimizes cluster boundary detection
).fit(reduced_embeddings)
clusters = hdbscan_model.labels_
# How many clusters did we generate?
len(set(clusters))
聚类数量:159
以下图表展示了文档是如何被聚类的。
检查聚类结果
在应用HDBSCAN之后,我们将通过手动检查文档样本,随后使用plotly库进行交互式3D UMAP可视化,以理解我们聚类的语义结构,从而继续检查这些聚类。
通过文档抽样进行手动聚类检查
这种方法允许我们通过打印来自代表性文档的摘要片段来检查聚类内容,从而帮助验证我们聚类结果的语义一致性。
我们将通过查看每个组中的代表性文档来检查聚类的语义一致性。现在让我们以第2个聚类为例进行说明:
import numpy as np
# Print first three documents in cluster 0
cluster = 2
for index in np.where(clusters==cluster)[0][:3]:
print(abstracts[index][:300] + "... \n")
输出:
This article presents SLAM, an Automatic Solver for Lexical Metaphors like
?d\'eshabiller* une pomme? (to undress* an apple). SLAM calculates a
conventional solution for these productions. To carry on it, SLAM has to
intersect the paradigmatic axis of the metaphorical verb ?d\'eshabiller*?,
where ...
Using a corpus of 17,000+ financial news reports (involving over 10M words),
we perform an analysis of the argument-distributions of the UP and DOWN verbs
used to describe movements of indices, stocks and shares. In Study 1
participants identified antonyms of these verbs in a free-response task an...
Contemporary research on computational processing of linguistic metaphors is
divided into two main branches: metaphor recognition and metaphor
interpretation. We take a different line of research and present an automated
method for generating conceptual metaphors from linguistic data. Given the
ge...
3D UMAP可视化:理解文档聚类分布
这一交互式可视化展示了降维后我们的文档在3D空间中的分布情况,不同的颜色代表由clusters变量确定的各个不同的聚类。
import pandas as pd
import plotly.express as px
from umap import UMAP
# Reduce 384-dimensional embeddings to 3 dimensions
reduced_embeddings_3d = UMAP(
n_components=3,
min_dist=0.0,
metric='cosine',
random_state=42
).fit_transform(embeddings)
# Create dataframe with 3D coordinates
df_3d = pd.DataFrame(
reduced_embeddings_3d,
columns=["x", "y", "z"]
)
df_3d["title"] = titles
df_3d["cluster"] = [str(c) for c in clusters]
# Create 3D scatter plot
fig = px.scatter_3d(
df_3d,
x='x',
y='y',
z='z',
color='cluster',
title='3D UMAP Visualization of Document Clusters',
opacity=0.7,
color_continuous_scale='viridis',
size_max=0.5,
hover_data=['title'] # Show title on hover
)
# Update layout
fig.update_layout(
width=900,
height=700,
showlegend=True
)
fig.show()
输出:
让我们放大到第2个聚类,以查看基于隐喻的NLP论文的研究论文标题。
结论
我们的文本聚类流程成功地将44,949篇arXiv NLP论文组织成了语义上连贯的组,这一结果通过手动检查和3D可视化得到了验证。
这三个阶段使我们能够有效地将相关论文分组,这在“检查”部分中清晰的隐喻研究聚类中得到了体现。