【问题标题】:TD-IDF Find Cosine Similarity Between New Document and DatasetTF-IDF 查找新文档和数据集之间的余弦相似度
【发布时间】:2017-12-05 08:57:19
【问题描述】:

我有一个产品数据集的 TF-IDF 矩阵:

tfidf = TfidfVectorizer().fit_transform(words)

words 是描述列表。这会产生一个 69258x22024 矩阵。

现在我想在新产品和矩阵中的产品之间找到 余弦相似度,因为我需要找到最相似的 10 个产品。我使用上面相同的方法对其进行矢量化。

但是,我不能将矩阵相乘,因为它们的大小不同(新的应该是 6 个字,所以是 1x6 矩阵),所以我需要制作一个 TFIDFVectorizer,其列数与原始的一样。

我该怎么做?

【问题讨论】:

  • 你能澄清你的问题吗?我的回答够吗?

标签: python machine-learning scikit-learn tf-idf


【解决方案1】:

我已经找到了一种工作方式。您需要先将新文档拟合到语料库 TFIDF 矩阵,而不是使用 fit_transform,如下所示:

queryTFIDF = TfidfVectorizer().fit(words)

现在我们可以使用 transform 函数将此向量“转换”为该矩阵形状:

queryTFIDF = queryTFIDF.transform([query])

其中 query 是查询字符串。
然后我们可以找到余弦相似度并找到 10 个最相似/相关的文档:

cosine_similarities = cosine_similarity(queryTFIDF, datasetTFIDF).flatten()
related_product_indices = cosine_similarities.argsort()[:-11:-1]

【讨论】:

  • 好收获。我用一个大的语料库(1MM 词)进行了测试,查询时间不到 1.58s。
  • 传递给 tfidfvectorizer 的最终列表是否仅包含词形还原词?我们可以使用自定义的预处理函数,然后将词形还原的单词列表作为语料库并传递给 tfidfvectorizer,它会给我每个句子的向量吗?
【解决方案2】:

我认为words 变量是模棱两可的。我建议你将words 重命名为corpus

实际上,您首先将所有文档放入corpus 变量中,然后再计算您的余弦相似度。

这里是一个例子:

tf_idf.py:

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

corpus = [
     'This is the first document.',
     'This is the second second document.',
     'And the third one.',
     'Is this the first document?',
]

vectorizer = TfidfVectorizer()
tfidf = vectorizer.fit_transform(corpus)
words = vectorizer.get_feature_names()
similarity_matrix = cosine_similarity(tfidf)

在您的 ipython 控制台中执行该操作:

In [1]: run tf_idf.py

In [2]: words
Out[2]: ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

In [3]: tfidf.toarray()
Out[3]: 
array([[ 0.        ,  0.43877674,  0.54197657,  0.43877674,  0.        ,
         0.        ,  0.35872874,  0.        ,  0.43877674],
       [ 0.        ,  0.27230147,  0.        ,  0.27230147,  0.        ,
         0.85322574,  0.22262429,  0.        ,  0.27230147],
       [ 0.55280532,  0.        ,  0.        ,  0.        ,  0.55280532,
         0.        ,  0.28847675,  0.55280532,  0.        ],
       [ 0.        ,  0.43877674,  0.54197657,  0.43877674,  0.        ,
         0.        ,  0.35872874,  0.        ,  0.43877674]])

In [4]: similarity_matrix
Out[4]: 
array([[ 1.        ,  0.43830038,  0.1034849 ,  1.        ],
       [ 0.43830038,  1.        ,  0.06422193,  0.43830038],
       [ 0.1034849 ,  0.06422193,  1.        ,  0.1034849 ],
       [ 1.        ,  0.43830038,  0.1034849 ,  1.        ]])

注意:

  • tfidfscipy.sparse.csr.csr_matrixto_array 转换为 numpy.ndarray(但成本高,只是在这里轻松查看内容)。
  • similarity_matrix 是一个对称矩阵。

你可以这样做:

import numpy as np
print(np.triu(similarity_matrix, k=1))

给:

array([[ 0.        ,  0.43830038,  0.1034849 ,  1.        ],
       [ 0.        ,  0.        ,  0.06422193,  0.43830038],
       [ 0.        ,  0.        ,  0.        ,  0.1034849 ],
       [ 0.        ,  0.        ,  0.        ,  0.        ]]) 

只看到有趣的相似之处。

见:

http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_similarity.html
http://scikit-learn.org/stable/modules/feature_extraction.html#text-feature-extraction

【讨论】:

  • 谢谢,但我想在不向数据集中添加新查询/文档的情况下这样做。
  • 我想指出这种方法是不正确的,因为如果您将其应用于实际任务,这会给您训练/测试出血,因为您将 tf-idf 矢量化器安装在测试数据上.接受的答案是正确的,因为它只对测试数据调用转换。
猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 2012-11-20
  • 2019-09-04
  • 1970-01-01
  • 2017-02-03
  • 2013-07-06
  • 1970-01-01
  • 2019-04-12
相关资源
最近更新 更多