如何从 TfidfVectorizer 计算余弦相似度?

Posted

技术标签:

【中文标题】如何从 TfidfVectorizer 计算余弦相似度?【英文标题】:How do I calculate cosine similarity from TfidfVectorizer? 【发布时间】:2017-01-18 19:56:33 【问题描述】:

我有两个 CSV 文件 - 训练和测试,每个文件有 18000 条评论。我需要使用训练文件进行特征提取并计算训练文件中的每条评论与测试文件中的每条评论之间的相似度度量。

我根据训练集和测试集中的单词生成了一个词汇表 - 我删除了停用词,但没有删除错别字和词干。

我面临的问题是 - 我不知道如何使用 TfIdfVectorizer 的输出来生成训练数据和测试数据之间的余弦相似度。

这是适合我的火车数据到vocabulary的代码sn-p:

vect = TfidfVectorizer(sublinear_tf=True, min_df=0.5,      vocabulary=vocabulary)
X = vect.fit_transform(train_list)
vocab = vect.get_feature_names()
# train_matrix = X.todense()
train_idf = vect.idf_
print vocab
print X.todense()

我从 X.todense() 得到的输出是

[[ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 ..., 
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]]

如果我只是打印 X,它看起来像这样:

(0, 28137)  0.114440020953
(0, 27547)  0.238913278498
(0, 26519)  0.14777362826
(0, 26297)  0.247716207254
(0, 26118)  0.178776605168
(0, 26032)  0.15139993147
(0, 25771)  0.10334152493
(0, 25559)  0.157584788446
(0, 25542)  0.0909693864147
(0, 25538)  0.179738937276
(0, 21762)  0.112899547719
(0, 21471)  0.159940534946
(0, 21001)  0.0931693893501
(0, 13960)  0.134069984961
(0, 12535)  0.198190713402
(0, 11918)  0.142570540903
:   :
(18505, 18173)  0.237810781785
(18505, 17418)  0.233931974117
(18505, 17412)  0.129587180209
(18505, 17017)  0.130917070234
(18505, 17014)  0.137794139419
(18505, 15943)  0.130040669343
(18505, 15837)  0.0790013472346
(18505, 11865)  0.158061557865
(18505, 10896)  0.0708161593204
(18505, 10698)  0.0846731116968
(18505, 10516)  0.116681527108
(18505, 8668)   0.122364898181
(18505, 7956)   0.174450779875
(18505, 1111)   0.191477939381
(18505, 73) 0.257945257626

我不知道如何读取 X.todense() 的输出或打印 X,我不确定如何找到测试集和训练集之间的余弦距离(可能使用成对相似性?-http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_distances.html ?)

编辑:

我对测试数据重复了相同的步骤。 现在我有两个 scipy.sparse.csr.csr_matrix 类型的稀疏矩阵 X 和 Y - 但由于它们都是稀疏矩阵和 (doc, term) tf-idf 类型,我无法通过直接乘法直接得到 X 和 Y 之间的余弦相似度。

使用 todense() 转换 X 和 Y 会出现 MemoryError - 这意味着它效率低下。

接下来我该怎么做?

我需要得到某种尺寸为 18000 * 18000 的成对余弦相似度的矩阵或稀疏矩阵,但我不知道该怎么做。

这是家庭作业,在这个阶段阅读 sklearn 文档对我没有任何帮助。

【问题讨论】:

【参考方案1】:

你快到了。使用vect.fit_transform 返回document-term matrix. 的稀疏表示,它是训练集的文档项矩阵表示。然后,您需要使用相同的模型转换测试集。提示:在test_list 上使用transform 方法。你很幸运,因为sklearn.metrics.pairwise.pairwise_distances(X, Y) 在传递metric='euclidean' 时为XY 采用稀疏矩阵(即你想要的度量)。从这里开始你需要做的事情应该很简单。

【讨论】:

感谢您的提示。我想我差不多完成了 - 除了 pairwise_distances 需要繁重的处理并且我的系统无法处理它。 pairwise_distances(X,Y) 给了我一个 MemoryError。 File "/home/bt/amzreview/local/lib/python2.7/site-packages/scipy/sparse/base.py", line 1009, in _process_toarray_args return np.zeros(self.shape, dtype=self.dtype, order=order) 【参考方案2】:

我认为你可以使用pariwise_distances

这是我正在使用的示例:

tf = TfidfVectorizer(tokenizer=normalize, decode_error = 'ignore',max_features=10000)

tfidf_matrix = tf.fit_transform(aux['enlarged_description'])

#cosine_similarities = linear_kernel(tfidf_matrix, tfidf_matrix)
X = pairwise_distances(tfidf_matrix, metric = metrics,n_jobs = -2 )

【讨论】:

以上是关于如何从 TfidfVectorizer 计算余弦相似度?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用已计算的 TFIDF 分数计算余弦相似度

R语言使用lsa包计算余弦相似度(Cosine Similarity)实战:两个向量的余弦相似度矩阵的余弦相度

在 TfidfVectorizer 中如何计算词频?

如何在 Python 中快速计算大量向量的余弦相似度?

从 tf-idf 计算余弦相似度

我们如何计算由它们的评分表示的两个项目的调整余弦相似度?