如何计算两个文本文档之间的相似度?

2024-04-23

我正在考虑使用任何编程语言(尽管我更喜欢 Python)来从事 NLP 项目。

我想获取两个文档并确定它们的相似程度。


常见的方法是将文档转换为 TF-IDF 向量,然后计算它们之间的余弦相似度。任何有关信息检索 (IR) 的教科书都涵盖了这一点。参见特别是。信息检索简介 http://www-nlp.stanford.edu/IR-book/,这是免费且在线提供的。

计算成对相似度

TF-IDF(以及类似的文本转换)在 Python 包中实现Gensim http://radimrehurek.com/gensim/ and scikit学习 http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfTransformer.html#sklearn.feature_extraction.text.TfidfTransformer。在后一个包中,计算余弦相似度就像

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 对于此类任务可能有更多选择。

也可以看看这个问题 https://stackoverflow.com/questions/2380394/simple-implementation-of-n-gram-tf-idf-and-cosine-similarity-in-python.

[免责声明:我参与了 scikit-learn TF-IDF 的实现。]

解释结果

从上面,pairwise_similarity是一个 Scipy稀疏矩阵 https://docs.scipy.org/doc/scipy/reference/sparse.html它是正方形的,行数和列数等于语料库中文档的数量。

>>> pairwise_similarity                                                                                                                                                                                                                                      
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 17 stored elements in Compressed Sparse Row format>

您可以通过以下方式将稀疏数组转换为 NumPy 数组.toarray() or .A:

>>> 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 位于corpus。您可以通过以下方式找到最相似文档的索引获取该行的 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何计算两个文本文档之间的相似度? 的相关文章

随机推荐