使用sklearn如何计算文档和查询之间的tf-idf余弦相似度?

时间:2019-04-14 16:06:20

标签: python scikit-learn tf-idf cosine-similarity

我的目标是输入3个查询,并找出哪个查询最类似于一组5个文档。

到目前为止,我已经计算出tf-idf个文档,它们执行以下操作:

from sklearn.feature_extraction.text import TfidfVectorizer

def get_term_frequency_inverse_data_frequency(documents):
    allDocs = []
    for document in documents:
        allDocs.append(nlp.clean_tf_idf_text(document))
    vectorizer = TfidfVectorizer()
    matrix = vectorizer.fit_transform(allDocs)
    return matrix

def get_tf_idf_query_similarity(documents, query):
    tfidf = get_term_frequency_inverse_data_frequency(documents)

我现在遇到的问题是我有tf-idf个文档,我对该查询执行哪些操作,以便可以找到与文档的余弦相似度?

4 个答案:

答案 0 :(得分:2)

这是我的建议:

  • 我们不必两次拟合模型。我们可以重复使用相同的矢量化器
  • 可以使用TfidfVectorizer属性将
  • 文本清除功能直接插入preprocessing中。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

vectorizer = TfidfVectorizer(preprocessor=nlp.clean_tf_idf_text)
docs_tfidf = vectorizer.fit_transform(allDocs)

def get_tf_idf_query_similarity(vectorizer, docs_tfidf, query):
    """
    vectorizer: TfIdfVectorizer model
    docs_tfidf: tfidf vectors for all docs
    query: query doc

    return: cosine similarity between query and all docs
    """
    query_tfidf = vectorizer.transform([query])
    cosineSimilarities = cosine_similarity(query_tfidf, docs_tfidf).flatten()
    return cosineSimilarities

答案 1 :(得分:1)

余弦相似度是代表文档的向量之间的夹角的余弦。

K(X, Y) = <X, Y> / (||X||*||Y||)

您的tf-idf矩阵将是维数为no的稀疏矩阵。文件*不同的单词。

要打印整个矩阵,可以使用todense()

print(tfidf.todense())

每一行代表与一个文档相对应的矢量表示。同样,每列对应于语料库中唯一词的tf-idf分数。

向量与任何其他向量之间的成对相似性可以根据您的tf-idf矩阵计算为:

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(reference_vector, tfidf_matrix) 

输出将是一个长度为no的数组。的文档,指示您的参考向量与每个文档对应的向量之间的相似性得分。当然,参考向量与其本身之间的相似度将为1。总的来说,它将是0到1之间的值。

要查找第一文档和第二文档之间的相似性,

print(cosine_similarity(tfidf_matrix[0], tfidf_matrix[1]))

array([[0.36651513]])

答案 2 :(得分:1)

您可以按照Nihal在其回应中所写的内容进行操作,也可以使用sklearn中最近的邻居算法。您必须选择适当的指标(余弦)

from sklearn.neighbors import NearestNeighbors
neigh = NearestNeighbors(n_neighbors=5, metric='cosine')

答案 3 :(得分:0)

其他答案非常有帮助,但并非完全符合我的要求,因为它们没有帮助我转换查询,因此可以将其与文档进行比较。

要转换查询,我首先将其适合文档矩阵:

queryTFIDF = TfidfVectorizer().fit(allDocs)

然后将其转换为矩阵形状:

queryTFIDF = queryTFIDF.transform([query])

然后只需使用sklearn.metrics.pairwise.cosine_similarity函数计算所有文档与我的查询之间的余弦相似度

cosineSimilarities = cosine_similarity(queryTFIDF, docTFIDF).flatten()

尽管我意识到使用Nihal的解决方案,我可以将查询作为文档之一输入,然后计算它与其他文档之间的相似度,但这对我来说最有效。

完整的代码最终看起来像:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

def get_tf_idf_query_similarity(documents, query):
    allDocs = []
    for document in documents:
        allDocs.append(nlp.clean_tf_idf_text(document))
    docTFIDF = TfidfVectorizer().fit_transform(allDocs)
    queryTFIDF = TfidfVectorizer().fit(allDocs)
    queryTFIDF = queryTFIDF.transform([query])

    cosineSimilarities = cosine_similarity(queryTFIDF, docTFIDF).flatten()
    return cosineSimilarities