我正在考虑使用任何编程语言(尽管我更喜欢 Python)来从事 NLP 项目。
我想获取两个文档并确定它们的相似程度。
最佳答案
常见的方法是将文档转换为 TF-IDF 向量,然后计算它们之间的余弦相似度。任何有关信息检索 (IR) 的教科书都涵盖了这一点。参见特别是。 Introduction to Information Retrieval ,免费且可在线获取。
计算成对相似度
TF-IDF(以及类似的文本转换)在 Python 包 Gensim 中实现和 scikit-learn 。在后一个包中,计算余弦相似度就像
from sklearn.feature_extraction.text import TfidfVectorizer
documents = [open(f).read() for f in text_files]
tfidf = TfidfVectorizer().fit_transform(documents)
# no need to normalize, since Vectorizer will return normalized tf-idf
pairwise_similarity = tfidf * tfidf.T
或者,如果文档是纯字符串,
>>> corpus = ["I'd like an apple",
... "An apple a day keeps the doctor away",
... "Never compare an apple to an orange",
... "I prefer scikit-learn to Orange",
... "The scikit-learn docs are Orange and Blue"]
>>> vect = TfidfVectorizer(min_df=1, stop_words="english")
>>> tfidf = vect.fit_transform(corpus)
>>> pairwise_similarity = tfidf * tfidf.T
尽管 Gensim 对于此类任务可能有更多选择。
另请参阅this question .
[免责声明:我参与了 scikit-learn TF-IDF 实现。]
解释结果
从上面来看,pairwise_similarity
是一个 Scipy sparse matrix其形状为正方形,行数和列数等于语料库中的文档数。
>>> pairwise_similarity
<5x5 sparse matrix of type '<class 'numpy.float64'>'
with 17 stored elements in Compressed Sparse Row format>
您可以通过 .toarray()
或 .A
将稀疏数组转换为 NumPy 数组:
>>> pairwise_similarity.toarray()
array([[1. , 0.17668795, 0.27056873, 0. , 0. ],
[0.17668795, 1. , 0.15439436, 0. , 0. ],
[0.27056873, 0.15439436, 1. , 0.19635649, 0.16815247],
[0. , 0. , 0.19635649, 1. , 0.54499756],
[0. , 0. , 0.16815247, 0.54499756, 1. ]])
假设我们想要找到与最终文档“The scikit-learn docs are Orange and Blue”最相似的文档。该文档在语料库
中的索引为4。您可以通过获取该行的 argmax 来找到最相似文档的索引,但首先您需要屏蔽 1,它表示每个文档与其自身的相似度。您可以通过 np.fill_diagonal()
执行后者,通过 np.nanargmax()
执行前者:
>>> import numpy as np
>>> arr = pairwise_similarity.toarray()
>>> np.fill_diagonal(arr, np.nan)
>>> input_doc = "The scikit-learn docs are Orange and Blue"
>>> input_idx = corpus.index(input_doc)
>>> input_idx
4
>>> result_idx = np.nanargmax(arr[input_idx])
>>> corpus[result_idx]
'I prefer scikit-learn to Orange'
注意:使用稀疏矩阵的目的是为大型语料库和词汇表节省(大量空间)。您可以执行以下操作,而不是转换为 NumPy 数组:
>>> n, _ = pairwise_similarity.shape
>>> pairwise_similarity[np.arange(n), np.arange(n)] = -1.0
>>> pairwise_similarity[input_idx].argmax()
3
关于python - 如何计算两个文本文档之间的相似度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8897593/