gensim教程翻译学习记录(四)

相似性查询(Similarity Queries)

展示一个语料库中相似文档的查询。

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

首先,我们需要创建一个能够工作的语料库。这一步和前面的教程是一样的;如果您已经完成了,请直接跳到下一节。

from collections import defaultdict
from gensim import corpora

documents = [
    "Human machine interface for lab abc computer applications",
    "A survey of user opinion of computer system response time",
    "The EPS user interface management system",
    "System and human system engineering testing of EPS",
    "Relation of user perceived response time to error measurement",
    "The generation of random binary unordered trees",
    "The intersection graph of paths in trees",
    "Graph minors IV Widths of trees and well quasi ordering",
    "Graph minors A survey",
]

# remove common words and tokenize
stoplist = set('for a of the and to in'.split())
texts = [
    [word for word in document.lower().split() if word not in stoplist]
    for document in documents
]

# remove words that appear only once
frequency = defaultdict(int)
for text in texts:
    for token in text:
        frequency[token] += 1

texts = [
    [token for token in text if frequency[token] > 1]
    for text in texts
]

dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]

相似性接口(Similarity interface)

在先前的教程( Corpora and Vector Spaces和Topics and Transformations)中,我们已经了解了如何在向量空间模型中创建一个语料库以及如何在不同向量空间中对其进行变换。这个做法的常见原因是,我们希望确定文档对的相似性,或者一个特定文档和文档集间的相似性(如用户查询和检索文档)。

为了展示如何在gensim中完成上述过程,让我们考虑在前面例子中的相同语料库(这确实最初来自Deerwester等人的开创性文章“Indexing by Latent Semantic Analysis”)。为了跟随Deerwester的例子,我们首先使用这个微型语料库来定义一个2维的LSI空间:

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

出于教程的目的,这里您仅需要了解LSI的两个参数。首先,它是另一个变换:它把向量从一个空间变换到另一个空间。第二,LSI的好处在于它能够识别类型和项(在我们的例子中是文档中的单词)以及主题间的关系。我们的LSI空间是二维的(num_topics = 2),因此这是有2个主题,但这都是主观设置的。如果您感兴趣,更多关于LSI的信息请参阅Latent Semantic Indexing:

现在,假设一个用户输入问题“Human computer interaction”。我们将对语料库中的9个文档按照其到问题的相关度按降序排列。与现代搜索引擎不同,这里我们仅关注可能的相似性这一点——关于其文本(单词)的明显语义相关性。没有超链接(hyperlinks),没有随机行走静态排序(random-walk static ranks), 只是布尔关键字匹配的语义扩展:

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.46182100453271535), (1, 0.07002766527900044)]

此外,我们考虑cosine相似性(cosine similarity)来确定两个向量间的相似度。Cosine相似性是向量空间建模的标准测量方法,但只要向量表示概率分布,不同相似性测量(different similarity measures)可能更合适。

初始化问询结构(Initializing query structures)

为了准备相似性查询,我们需要输入我们想要与后续查询进行比较的所有文档。在我们的情况下,这里有同样的9个文档用于训练LSI,被变换到2维的LSA空间。但这只是偶然的,我们可能也会将索引不同的语料库。

from gensim import similarities
index = similarities.MatrixSimilarity(lsi[corpus]) # transform corpus to LSI space and index it

提醒:similarities.MatrixSimilarity类仅适用于当整个向量集输入内存中。例如,在256维LSI空间上,一个包含一百万条文档的语料库在使用该类时会需要2GB的RAM。没有2GB的空闲RAM,你可能需要使用similarities.Similarity类。通过将索引拆分到磁盘上的多个文件(称为碎片)中,此类在固定内存中运行。它在内部使用similarities.MatrixSimilarity和similarities.SparseMatrixSimilarity,因此,虽然它有点复杂,但是运行仍然很快。

索引(index)的持久性通过标准函数save()和load()进行处理:

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

这对所有相似性索引类(similarities.Similarity, similarities.MatrixSimilarity以及similarities.SparseMatrixSimilarity)都适用。此外,在以下几个方面,索引可以是其中任何一个对象。有疑问时,使用similarities.Similarity,因为它是最可扩展的版本,它也支持以后在索引中添加更多的文档。

执行问询(Performing queries)

为了获得我们的问询文档和9个被索引文档的相似度:

sim = index[vec_lsi] # perform a similarity query against the corpus
print(list(enumerate(sims))) # print (document_number, document_similarity) 2-tuples

结果为:

[(0, 0.998093), (1, 0.93748635), (2, 0.9984453), (3, 0.9865886), (4, 0.90755945), (5, -0.12416792), (6, -0.10639259), (7, -0.09879464), (8, 0.050041765)]

Cosine测量返回在范围间的相似度(值越大,越相似),因此第一个文档的得分为0.998093。

使用一些标准的Python魔法,我们把相似度按降序排列,以及获得最后问询“Human computer interaction”的回答:

sim = sorted(enumerate(sims), key=lambda item: -item[1])
for doc_position, doc_score in sims:
    print(doc_score, documents[doc_position])

结果为:

0.9984453 The EPS user interface management system
0.998093 Human machine interface for lab abc computer applications
0.9865886 System and human system engineering testing of EPS
0.93748635 A survey of user opinion of computer system response time
0.90755945 Relation of user perceived response time to error measurement
0.050041765 Graph minors A survey
-0.09879464 Graph minors IV Widths of trees and well quasi ordering
-0.10639259 The intersection graph of paths in trees
-0.12416792 The generation of random binary unordered trees

值得注意的是,2号文档(“The EPS user interface management system”)和4号文档(“Relation of user perceived response time to error measurement”)不可能作为一个标准布尔全文本搜索的返回结果,因为它们不共享“Human computer interaction”中的任何通用单词。然而,在应用LSI后,我们能够观察到这两者都返回了非常高的相似性得分(2号文档实际上是最相似的!)。从它们和问询共享“computer-human”相关话题这一点上出发,这样的结果也更符合我们的直觉。事实上,这种语义概括是我们首先应用转换和做主题建模的原因。

在一步在哪(Where next?)

恭喜您,您已经完成了教程——现在你知道gensim是如何工作的:-)要深入了解更多详细信息,您可以浏览API Reference,查看Experiments on the English Wikipedia,或者查看Gensim中的Distributed Computing。

Gensim是一个相当成熟的包装,已被许多个人和公司成功用于快速原型制作和生产。但这并不意味着它是完美的, 虽然:

有些部件可以更有效地实现(例如在C中),或者更好地利用并行性(多机芯)

新的算法一直发布;通过讨论它们和贡献代码来帮助 gensim不断更新

您的反馈非常受欢迎和赞赏(不仅仅是代码!):bug reports或user stories and general questions。

Gensim没有雄心壮志成为一个跨越所有NLP(甚至机器学习)子领域包罗万象的框架。其使命是帮助NLP从业者轻松尝试大型数据集上的流行主题建模算法,并为研究人员提供新算法的原型设置。

你可能感兴趣的:(gensim教程翻译学习记录(四))