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

标签 python nlp

我正在考虑使用任何编程语言(尽管我更喜欢 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/

相关文章:

Python类变量或一般的类变量

python - 多变量线性回归与 scipy linregress

python-3.x - 需要构建自定义 NER 的方法,以便从任何格式的工资单中提取以下关键字

java - java API中的-sentenceDelimiter换行符

python - 使用 gensim 库进行内存高效 LDA 训练

algorithm - NLP语法: fixing a to an?

python - 在 ubuntu 上安装 devstack kilo 时如何解决这个错误

python - 查找大型数据集中两个日期之间是否有假期?

python - Pandas Drop Duplicates Series 散列错误

python - NLTK panlex_lite 给我错误