gensim文档-相似性查询

本文介绍了使用Gensim进行文档相似性查询的方法,包括如何建立LSI空间、转换查询到该空间以及如何通过余弦相似性度量文档之间的相似性。

原文链接

http://cloga.info/python/2014/01/28/Gensim_Similarity_Queries/

28 January 2014

如果你想要查看logging事件不要忘记设置。

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

相似性接口

在前面语料与向量空间的教程及主题和转换的教程中,我们涵盖了什么是在向量空间中创建一个语料库以及如何在不同的向量空间间转换。绕这样一个圈子的原因是我们想要判断一堆文档的相似性,或者特定文档与一组其他文档的相似性(比如用户查询 vs. 索引文档)。

为了展示gensim如何做到这一点,让我们看一下前面例子中语料(最初来自Deerwester等的“Indexing by Latent Semantic Analysis” seminal 1990 article):

from gensim import corpora, models, similarities
dictionary = corpora.Dictionary.load('/tmp/deerwester.dict')
corpus = corpora.MmCorpus('/tmp/deerwester.mm') # 来自一篇教程“从字符到向量”
print corpus

MmCorpus(9 documents, 12 features, 28 non-zero entries)

遵循Deerwester的例子,我们首先使用这个小样本语料定义一个二维的LSI空间:

lsi = models.LsiModel(corpus, id2word=dictionary, num_topics=2)

现在假设用户输入查询“Human computer interaction”。我们会想要以与查询相似度降序排列我们的9个语料。与现代搜索引擎不同,这里我们只关注可能相似的一个方面-文档(词)的表面抑郁相关。没有超链接,静态排名的随机游走,只有在布尔关键词匹配的语义扩展:

doc = "Human computer interaction"
vec_bow = dictionary.doc2bow(doc.lower().split())
vec_lsi = lsi[vec_bow] # convert the query to LSI space
print vec_lsi

[(0, -0.461821), (1, 0.070028)]

此外,我们将用余弦相似性来决定两个向量间的相似性。余弦相似性是向量空间模型中的标准度量,但是,当向量代表概率分布时,不同的相似性度量可能更适合。

初始化查询结构

要准备相似性查询,我们需要输入所有想要与随后的查询比较的所有文档。在这种情况下,还是用于训练LSI的9个文档被转化为二维空间。但是,这只是偶然,我们也可能索引不同的的语料。

index = similarities.MatrixSimilarity(lsi[corpus]) # 将语料转换为LSI,并索引

警告

similarities.MatrixSimilarity这个类只适用于所有语料可以放入内存的情况。例如,使用这个类,256维的LSI空间中的100万文档会需要2G的内存。

如果没有2G的可用内存,你需要使用similarities.Similarity类。这个类通过在硬盘的多个文件上分割索引,这些文件称为 shards,使用固定内存运行。它在内部使用similarities.MatrixSimilarity及similarities.SparseMatrixSimilarity,因此,仍然很快,尽管有点更加复杂。

索引的持久化通过标准的save()和load()函数处理:

index.save('/tmp/deerwester.index')
index = similarities.MatrixSimilarity.load('/tmp/deerwester.index')

所有的索引类都是这样的(similarities.Similarity, similarities.MatrixSimilarity和similarities.SparseMatrixSimilarity)。接下来这些也是,索引可以是这类中的任何一个对象。如果不确定,使用similarities.Similarity,因为这是扩展性最好的版本,并且它还支持后续为索引添加更多的文档。

进行查询

获得查询文档对9个索引文档的相似性:

sims = index[vec_lsi] # 进行语料的相似查询
print list(enumerate(sims)) # 打印(document_number, document_similarity) 2-tuples

[(0, 0.99809301), (1, 0.93748635), (2, 0.99844527), (3, 0.9865886), (4, 0.90755945),
(5, -0.12416792), (6, -0.1063926), (7, -0.098794639), (8, 0.05004178)]

余弦度量返回的的相似性在<-1,1>之前(越大越相似),因此,第一个文档的总分为0.99809301。

使用类似的标准Python魔法,我们可以将相似性降序排列,获得“Human computer interaction”查询的最终答案:

sims = sorted(enumerate(sims), key=lambda item: -item[1])
print sims # 打印排序的 (document number, similarity score) 2-tuples

[(2, 0.99844527), # The EPS user interface management system
(0, 0.99809301), # Human machine interface for lab abc computer applications
(3, 0.9865886), # System and human system engineering testing of EPS
(1, 0.93748635), # A survey of user opinion of computer system response time
(4, 0.90755945), # Relation of user perceived response time to error measurement
(8, 0.050041795), # Graph minors A survey
(7, -0.098794639), # Graph minors IV Widths of trees and well quasi ordering
(6, -0.1063926), # The intersection graph of paths in trees
(5, -0.12416792)] # The generation of random binary unordered trees

(为了更清晰,我在输出中用评论添加了原始文档的”字符形式”。)

这里注意的是第二号("The EPS user interface management system")及第四号("Relation of user perceived response time to error measurement")文档永远也不会返回一个标准的布尔全文搜索,因为它们与"Human computer interaction"没有相同的词。但是,应用LSI后,我们可以看到他们获得了很高的相似性分数(二号实际上是最相似!),更好的反映了我们的直觉,他们与查询都是关于“计算机-人类”这个话题。事实上,这句语言概括也是首先应用主题建模的原因。

接下来是什么?

祝贺你,你完成了教程-现在你知道了gensim如何工作:-)要研究更多细节,你需要看一下API文档,查看维基百科实验或者看一下gensim中分布计算

Gensim是相当成熟的包,被许多个人和公司成功应用,无论是快速原型还是在生产环境。 但是,这不意味这它是完美的:

  • 有许多部分应该更有效的实现(比如说用C),或者使用更好的并行机制(多核)

  • 新算法层出不穷;通过讨论帮助gensim保持更新并且贡献代码

  • 非常欢迎和感激你的反馈(不仅仅是代码!):贡献思想、报告bug或者考虑共享用户故事和一般问题

Gensim没有野心称为一个无所不包的框架,涉及所有NLP(甚至机器学习)的领域。它的使命是帮助NLP从业者轻松在大数据集上尝试流行主题建模算法,并且帮助研究者设计算法原型。


## 算法原理与程序使用 BM25算法原理参见我的博文:[【NLP】非监督文本匹配算法——BM25] 测试程序: ```python bm25 = BM25() result = bm25.cal_similarity("自然语言处理并不是一般地研究自然语言") for line, score in result: print(line, score) ``` 测试结果如下: ```python 自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。 1.012567843290477 它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。 2.0911221271793545 自然语言处理是一门融语言学、计算机科学、数学于一体的科学。 1.012567843290477 因此,这一领域的研究将涉及自然语言,即人们日常使用的语言, 2.2068046420905443 所以它与语言学的研究有着密切的联系,但又有重要的区别。 1.4616618736274032 自然语言处理并不是一般地研究自然语言, 3.2072055608059036 而在于研制能有效地实现自然语言通信的计算机系统, 1.201522188129132 特别是其中的软件系统。因而它是计算机科学的一部分。 0 在信息搜索中,我们做的第一步就是检索。 0 再延展一下,搜索这项功能在我们生活中也是太多太多。 0 大众一点就是搜索引擎,商品搜索等,在问题系统中可以匹配相似的问题,然后返回对应答案等。 0 文本匹配包括监督学习方法以及非监督学习方法。 0 或者分为传统方法和深度学习方法。 0 BM25 在 20 世纪 70 年代到 80 年代被提出,到目前为止已经过去二三十年了,但是这个算法依然在很多信息检索的任务中表现优异,是很多工程师首选的算法之一。 0 有时候全称是 Okapi BM25,这里的“BM”是“最佳匹配”(Best Match)的简称。 0 那么,当通过使用不同的语素分析方法,语素权重判定方法以及语素与文档的相关性判定方法,可以衍生很多不同的搜索相关性计算方法,灵活性也比较大。 0 ``` -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
您可以使用gensim库中的相似性排序函数来实现文档相似性排序。具体步骤如下: 1. 首先,您需要将所有文档转换为词袋模型,使用gensim库中的Dictionary和corpora模块来实现: ```python from gensim import corpora # 将所有文档转换为词袋模型 texts = [['human', 'interface', 'computer'], ['survey', 'user', 'computer', 'system', 'response', 'time'], ['eps', 'user', 'interface', 'system'], ['system', 'human', 'system', 'eps'], ['user', 'response', 'time'], ['trees'], ['graph', 'trees'], ['graph', 'minors', 'trees'], ['graph', 'minors', 'survey']] dictionary = corpora.Dictionary(texts) corpus = [dictionary.doc2bow(text) for text in texts] ``` 2. 接下来,您需要使用gensim库中的TF-IDF模型来计算每个文档的TF-IDF向量: ```python from gensim import models # 计算TF-IDF向量 tfidf = models.TfidfModel(corpus) corpus_tfidf = tfidf[corpus] ``` 3. 然后,您可以使用gensim库中的相似性排序函数来计算文档之间的相似性得分,例如使用余弦相似度: ```python from gensim import similarities # 计算余弦相似度 index = similarities.MatrixSimilarity(corpus_tfidf) sims = index[corpus_tfidf] ``` 4. 最后,您可以使用numpy库中的argsort函数来对相似性得分进行排序,得到每个文档的相似文档集合: ```python import numpy as np # 对相似性得分进行排序 sorted_sims = np.argsort(-sims, axis=1) # 打印每个文档的相似文档集合 for i, doc in enumerate(sorted_sims): print('Document', i, ':', doc) ``` 这样就可以得到每个文档的相似文档集合,其中相似度得分越高的文档排在前面。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值