介绍
在机器学习和自然语言处理中,一种高效的方法是主题建模。文本语料库是一组文档的示例。该技术涉及发现出现在文本中的抽象主题。这种方法突显了文本体系的潜在结构,揭示了可能不会立即显现的主题和模式。
为了分析大规模文档集合(例如数千条推文)的内容,主题建模算法依赖于统计技术来发现文本中的模式。这些算法通过检查文档中的词频和词共现来将文档分类为少数几个主题。因此,内容看起来更有组织和可理解,更容易识别数据中的潜在主题和模式。
潜在狄利克雷分配(LDA)、潜在语义分析和非负矩阵分解是一些常规的主题建模技术。然而,本博文使用BERT进行主题建模。
了解更多:使用潜在狄利克雷分配(LDA)进行主题建模
学习目标
以下是使用BERT进行主题建模的学习目标,以项目符号形式给出:
- 了解主题建模的基础知识以及在自然语言处理中的应用。
- 了解BERT的基础知识以及它如何创建文档嵌入。
- 对文本数据进行预处理,以便为BERT模型准备数据。
- 利用[CLS]标记从BERT的输出中提取文档嵌入。
- 使用聚类方法(如K均值)对相关材料进行分组并找到潜在主题。
- 利用合适的度量标准评估生成的主题的质量。
通过这个学习目标的帮助,参与者将获得使用BERT进行主题建模的实践经验。利用这些知识,他们将能够分析和提取大规模文本数据中隐藏的主题。
本文是数据科学博文马拉松的一部分。
加载数据
这是澳大利亚广播公司八年来在Kaggle上提供的可访问内容。它包含两个重要的列:publish_date:文章的发布日期,格式为yyyyMMdd。headline_text是标题文本的英文翻译。这是主题模型将使用的知识。
import pandas as pd
# 读取数据集
data = pd.read_csv('../input/abc-news-sample/abcnews_sample.csv')
data.head()
# 创建一个新列,包含每个标题文本的长度
data["headline_text_len"] = data["headline_text"].apply(lambda x : len(x.split()))
print("最长的标题有:{}个单词".format(data.headline_text_len.max()))
# 可视化长度分布
import seaborn as sns
import matplotlib.pyplot as plt
sns.displot(data.headline_text_len, kde=False)
for idx in data.sample(3).index:
headline = data.iloc[idx]
print("标题 #{}:".format(idx))
print("发布日期:{}".format(headline.publish_date))
print("文本:{}\n".format(headline.headline_text))
主题建模
在这个例子中,我们将回顾BERT主题的关键要素以及构建强大主题模型所需的步骤。
了解更多:Python主题建模入门指南
训练
首先进行BERT主题的初始化。我们的文档是英文,所以将语言设置为英文。如果要使用支持多种语言的模型,可以将language替换为”multilingual”。
还将计算主题概率。然而,处理大规模数据集(>100,000个文档)时,这可能会极大地减慢BERT主题的速度。您可以加速模型,并关闭此功能。
import warnings
warnings.filterwarnings("ignore")
!pip install bertopic
%%time
from bertopic import BERTopic
model = BERTopic(verbose=True,embedding_model='paraphrase-MiniLM-L3-v2', min_topic_size= 7)
headline_topics, _ = model.fit_transform(data.headline_text)
为了防止在模型初始化时显示消息,将Verbose设置为True。速度和性能之间的最佳平衡的句子转换模型是paraphrase-MiniLM-L3-v2。我们将Min_topic_size设置为7,尽管默认值是10。随着这个值的增加,聚类或主题的数量减少。
主题提取和表示
freq = model.get_topic_info()
print("主题数量:{}".format( len(freq)))
freq.head()
在上表的三列中,按照大小/计数的递减顺序列出了所有的54个主题。
- 离群值被指定为-1,并由主题编号进行标识,该编号用作标识符。由于它们没有价值,应该避免这些问题。
- “count”一词指的是主题的词频。
- 主题以其给定的名称name来识别。
我们可以获取每个主题的前几个词及其相应的c-TF-IDF分数。分数越大,表示该词与主题的相关性越高。
a_topic = freq.iloc[1]["Topic"] # 选择第一个主题 model.get_topic(a_topic) # 显示词和它们的c-TF-IDF分数
从这个主题中,我们可以看出所有的词都与底层主题相关,该主题似乎与消防员有关。
主题可视化
通过主题可视化,您可以更多地了解每个主题。我们将关注从BERTopic引用的可视化选项,包括词项可视化、热带距离图和主题层次聚类等。
1. 主题词项
您可以使用c-TF-IDF分数为每个主题创建一个关键词条形图,这提供了一种有趣的方式来进行图形化比较。下面是主题六的相关可视化结果。
model.visualize_barchart(top_n_topics=6)
主题1与犯罪有关,因为其顶部短语是“man, charged murder jail over”。每个后续主题都可以很容易地得出相同的分析结论。水平条越长,与主题相关性越高。
2. 主题间距图
对于熟悉Latent Dirichlet Allocation的LDAvis库的用户来说,该库提供了一个交互式仪表板,显示与每个主题相关的词和分数。BERTopic通过其visualize_topics()方法实现了相同的功能,并进一步提供了案例之间的距离(长度越短,主题相关性越高)。
model.visualize_topics()
3. 可视化主题层次
如在主题距离图中所示,一些主题是相近的。您可能会想到的一个问题是如何减少主题数量。好消息是,您可以将这些主题按层次排列,以便选择正确的主题数量。可视化的方式使我们更容易理解它们之间的关系。
model.visualize_hierarchy(top_n_topics=30)
通过观察树状图的第一层(level 0),我们可以看到具有相似颜色的主题已经被分组。
- 主题7(健康、医院、心理)和14(死亡、崩溃、杀害)因其相似性而被合并。
- 主题6(农民、农场和农民)和16(牛、羊和肉)必须被分类为相似的主题。
- 这些细节可以帮助用户理解为什么将主题与彼此进行比较。
搜索主题
一旦我们训练了主题模型,我们就可以使用find_topics方法来搜索与给定的查询词或短语语义相关的主题。例如,我们可以查找与单词“政治”相关的前3个主题。
# 选择最相似的3个主题
similar_topics, similarity = model.find_topics("politics", top_n = 3)
- similar_topics中的主题索引从最相似到最不相似进行了排序。
- 相似性评分在similarity中按降序显示。
similar_topics
most_similar = similar_topics[0]
print("最相似的主题信息:\n{}".format(model.get_topic(most_similar)))
print("相似性得分:{}".format(similarity[0]))
很明显,“选举”、“特朗普”和“奥巴马”这样明确与政治有关的词语代表了最相关的话题。
模型序列化与加载
当您对模型的结果感到满意时,可以按照以下说明将其存储以进行额外的分析:
%%bash
mkdir './model_dir
# 将模型保存在之前创建的文件夹中,命名为'my_best_model'
model.save("./model_dir/my_best_model")
# 加载序列化的模型
my_best_model = BERTopic.load("./model_dir/my_best_model")
my_best_model
结论
总之,使用BERT进行主题建模为在文本数据中定位隐藏主题提供了一种有效的方法。尽管BERT最初是为各种自然语言处理应用程序开发的,但可以通过使用文档嵌入和聚类方法来进行主题建模。以下是本文的关键点:
- 主题建模的重要性在于使企业能够通过帮助他们理解海量非结构化文本数据中的潜在主题和模式,获取有深度的信息并做出明智的决策。
- 尽管BERT不是主题建模的传统方法,但它仍然可以提供用于发现潜在主题的有深度的文档嵌入。
- BERT通过从[CLS]标记的输出中删除语义数据来创建文档嵌入。这些嵌入为文档提供了一种密集的向量空间表示。
- 使用BERT进行主题建模是一个不断发展的领域,随着新的研究和技术进展,其性能不断提高。
总的来说,掌握使用BERT进行主题建模使数据科学家、研究人员和分析师能够从大规模文本语料库中提取和分析潜在主题,得出深入的结论和明智的决策。
常见问题与答案
本文中显示的媒体不归Analytics Vidhya所有,仅由作者自行决定使用。