更新:
- 新增预训练的transformer模型
- 通过传递可调用对象到
embedding_model
来使用任何嵌入模型的能力 - 长文档的分块选项
- 通过设置
ngram_vocab=True
在主题中使用短语
Top2Vec
Top2Vec是一种用于主题建模和语义搜索的算法。它能自动检测文本中存在的主题,并生成联合嵌入的主题、文档和词向量。一旦你训练了Top2Vec模型,你就可以:
- 获取检测到的主题数量。
- 获取主题。
- 获取主题大小。
- 获取层次化主题。
- 通过关键词搜索主题。
- 通过主题搜索文档。
- 通过关键词搜索文档。
- 寻找相似词。
- 寻找相似文档。
- 通过RESTful-Top2Vec暴露模型
有关其工作原理的更多详细信息,请参阅论文。
优势
- 自动找出主题数量。
- 不需要停用词列表。
- 无需词干提取/词形还原。
- 适用于短文本。
- 创建联合嵌入的主题、文档和词向量。
- 内置搜索功能。
它是如何工作的?
该算法的假设是,许多语义相似的文档表明存在一个潜在的主题。第一步是创建文档和词向量的联合嵌入。一旦文档和词被嵌入到向量空间中,算法的目标就是找到文档的密集聚类,然后识别哪些词吸引了这些文档聚集在一起。每个密集区域就是一个主题,而吸引文档到密集区域的词就是主题词。
算法步骤:
1. 使用Doc2Vec或Universal Sentence Encoder或BERT Sentence Transformer创建联合嵌入的文档和词向量。
相似的文档会被放置在彼此附近,并靠近最能区分它们的词。
2. 使用UMAP创建文档向量的低维嵌入。
高维空间中的文档向量非常稀疏,降维有助于找到密集区域。每个点代表一个文档向量。
3. 使用HDBSCAN找到文档的密集区域。
彩色区域是文档的密集区域。红色点是不属于特定聚类的离群点。
4. 对于每个密集区域,计算原始维度中文档向量的质心,这就是主题向量。
红色点是离群文档,不用于计算主题向量。紫色点是属于密集区域的文档向量,用于计算主题向量。
5. 找出与结果主题向量最接近的n个词向量。
按接近程度排序的最接近词向量成为主题词。
安装
安装Top2Vec的简单方法是:
pip install top2vec
要安装预训练的通用句子编码器选项:
pip install top2vec[sentence_encoders]
要安装预训练的BERT句子转换器选项:
pip install top2vec[sentence_transformers]
要安装索引选项:
pip install top2vec[indexing]
使用
from top2vec import Top2Vec
model = Top2Vec(documents)
重要参数:
-
documents
:输入语料库,应该是字符串列表。 -
speed
:此参数将决定模型训练的速度。 'fast-learn'选项是最快的,但会生成最低质量的向量。'learn'选项会学习更好质量的向量,但需要更长的训练时间。'deep-learn'选项会学习最佳质量的向量,但需要大量的训练时间。 -
workers
:用于训练模型的工作线程数量。更多的线程会导致更快的训练。
训练好的模型可以保存和加载。
model.save("filename")
model = Top2Vec.load("filename")
更多信息请查看API指南。
预训练嵌入模型
默认情况下,将使用Doc2Vec生成联合词和文档嵌入。但是,还有预训练的embedding_model
选项用于生成联合词和文档嵌入:
universal-sentence-encoder
universal-sentence-encoder-multilingual
distiluse-base-multilingual-cased
from top2vec import Top2Vec
model = Top2Vec(documents, embedding_model='universal-sentence-encoder')
对于大型数据集和词汇非常独特的数据集,doc2vec可能会产生更好的结果。这将从头开始训练一个doc2vec模型。这种方法与语言无关。但是,多种语言不会对齐。
使用通用句子编码器选项会快得多,因为这些是预训练的高效模型。通用句子编码器选项建议用于较小的数据集。它们也是英语或多语言模型覆盖的语言的大型数据集的好选择。它也建议用于多语言数据集。
distiluse-base-multilingual-cased预训练句子转换器建议用于多语言数据集和多语言通用句子编码器未覆盖的语言。转换器比通用句子编码器选项明显慢。
有关universal-sentence-encoder、universal-sentence-encoder-multilingual和distiluse-base-multilingual-cased的更多信息。
引用
如果你想在你的工作中引用Top2Vec,这是当前的参考:
@article{angelov2020top2vec,
title={Top2Vec: Distributed Representations of Topics},
author={Dimo Angelov},
year={2020},
eprint={2008.09470},
archivePrefix={arXiv},
primaryClass={cs.CL}
}
示例
训练模型
在20newsgroups数据集上训练Top2Vec模型。
from top2vec import Top2Vec
from sklearn.datasets import fetch_20newsgroups
newsgroups = fetch_20newsgroups(subset='all', remove=('headers', 'footers', 'quotes'))
model = Top2Vec(documents=newsgroups.data, speed="learn", workers=8)
获取主题数量
这将返回Top2Vec在数据中发现的主题数量。
>>> model.get_num_topics()
77
获取主题大小
这将返回与每个主题最相似的文档数量。主题按大小降序排列。
topic_sizes, topic_nums = model.get_topic_sizes()
返回:
-
topic_sizes
:与每个主题最相似的文档数量。 -
topic_nums
:将返回每个主题的唯一索引。
获取主题
这将按大小降序返回主题。
topic_words, word_scores, topic_nums = model.get_topics(77)
返回:
-
topic_words
:对于每个主题,返回前50个词,按与主题的语义相似度排序。 -
word_scores
:对于每个主题,返回前50个词与主题的余弦相似度得分。 -
topic_nums
:将返回每个主题的唯一索引。
搜索主题
我们将搜索与medicine最相似的主题。
topic_words, word_scores, topic_scores, topic_nums = model.search_topics(keywords=["medicine"], num_topics=5)
返回:
-
topic_words
:对于每个主题,返回前50个词,按与主题的语义相似度排序。 -
word_scores
:对于每个主题,返回前50个词与主题的余弦相似度得分。 -
topic_scores
:对于每个主题,将返回与搜索关键词的余弦相似度。 -
topic_nums
:将返回每个主题的唯一索引。
>>> topic_nums
[21, 29, 9, 61, 48]
>>> topic_scores
[0.4468, 0.381, 0.2779, 0.2566, 0.2515]
主题21是与"medicine"最相似的主题,余弦相似度为0.4468。(值可以从最不相似的0到最相似的1)
生成词云
使用主题编号,你可以生成词云。我们将为与我们的"医学"主题搜索最相似的前5个主题生成词云。
topic_words, word_scores, topic_scores, topic_nums = model.search_topics(keywords=["medicine"], num_topics=5)
for topic in topic_nums:
model.generate_topic_wordcloud(topic)
按主题搜索文档
我们将搜索主题48,这个主题似乎是关于科学的。
documents, document_scores, document_ids = model.search_documents_by_topic(topic_num=48, num_docs=5)
返回:
documents
:文档列表,最相似的排在前面。doc_scores
:文档与主题的语义相似度。文档和主题向量的余弦相似度。doc_ids
:文档的唯一标识。如果没有给定标识,则为原始语料库中文档的索引。
对于每个返回的文档,我们将打印其内容、得分和文档编号。
documents, document_scores, document_ids = model.search_documents_by_topic(topic_num=48, num_docs=5)
for doc, score, doc_id in zip(documents, document_scores, document_ids):
print(f"文档:{doc_id},得分:{score}")
print("-----------")
print(doc)
print("-----------")
print()
文档:15227,得分:0.6322
进化既是事实也是理论。进化理论代表了科学试图解释进化事实的尝试。进化理论不提供事实;它解释事实。可以安全地假设所有科学理论既不提供也不成为事实,而是解释事实。我建议你做一些适当的一般科学阅读。对于普通人来说,关于进化的一个很好的起点是斯蒂芬·杰·古尔德的《母鸡的牙齿和马的脚趾》[第253-262页]中的"进化作为事实和理论"。这本出版物中还有许多其他有用的信息。
文档:14515,得分:0.6186
这些"科学事实"到底是什么?我从未听说过这样的东西。科学从不证明或反驳任何理论 - 历史才会。
-蒂姆
文档:9433,得分:0.5997
证明任何理论是错误的方法都是一样的。你检查理论做出的预测,并试图观察它们。如果你没有观察到,或者你观察到理论预测不会发生的事情,那么你就有了一些反对该理论的证据。如果理论无法修改以包含新的观察结果,那么你就说它是错误的。
例如,人们过去相信地球是10,000年前创造的。但是,当证据表明这个理论的预测不是真实的时候,它就被放弃了。
文档:11917,得分:0.5845
关于它是否真实的重点是,当人们想要预测时,不会浪费时间去思考现实可能是什么。在这样一个系统中,不需要考虑原子是否存在或是否有其他东西在那里使测量表明有原子。
而且,每次物理学使用新模型时,人们不必重新写一个新的存在理论。
...
通过关键词语义搜索文档
搜索与"密码学"和"隐私"在语义上相似的文档内容。
documents, document_scores, document_ids = model.search_documents_by_keywords(keywords=["cryptography", "privacy"], num_docs=5)
for doc, score, doc_id in zip(documents, document_scores, document_ids):
print(f"文档:{doc_id},得分:{score}")
print("-----------")
print(doc)
print("-----------")
print()
文档:16837,得分:0.6112
... 电子邮件和账户隐私、匿名性、文件加密、学术计算机政策、相关立法和参考资料、电子前沿基金会(EFF),以及与使用互联网和全球网络相关的其他隐私和权利问题。 ...
文档:16254,得分:0.5722
... 总统今天宣布了一项新计划,该计划将联邦政府与行业联合起来,通过自愿计划来提高电话通信的安全性和隐私性,同时满足执法部门的合法需求。 ...
...
相似关键词
搜索与"空间"相似的词。
words, word_scores = model.similar_words(keywords=["space"], keywords_neg=[], num_words=20)
for word, score in zip(words, word_scores):
print(f"{word} {score}")
空间 1.0 美国航空航天局 0.6589 航天飞机 0.5976 探索 0.5448 行星 0.5391 任务 0.5069 发射 0.4941 望远镜 0.4821 天文 0.4696 约翰逊航天中心 0.4549 艾姆斯研究中心 0.4515 卫星 0.446 站 0.4445 轨道 0.4438 太阳 0.4386 天文学 0.4378 天文台 0.4355 设施 0.4325 推进 0.4251 航空航天 0.4226