给定一个稀疏矩阵列表,计算矩阵中每一列(或行)之间的余弦相似度的最佳方法是什么?我不想重复n- iterate 2次。
假设输入矩阵是:
A=
[0 1 0 0 1
0 0 1 1 1
1 1 0 1 0]
稀疏表示为:
A =
0, 1
0, 4
1, 2
1, 3
1, 4
2, 0
2, 1
2, 3
在Python中,使用矩阵输入格式很简单:
import numpy as np
from sklearn.metrics import pairwise_distances
from scipy.spatial.distance import cosine
A = np.array(
[[0, 1, 0, 0, 1],
[0, 0, 1, 1, 1],
[1, 1, 0, 1, 0]])
dist_out = 1-pairwise_distances(A, metric="cosine")
dist_out
提供:
array([[ 1. , 0.40824829, 0.40824829],
[ 0.40824829, 1. , 0.33333333],
[ 0.40824829, 0.33333333, 1. ]])
这对于全矩阵输入来说很好,但是我真的想从稀疏表示开始(由于我的矩阵的大小和稀疏性)。关于如何最好地实现这一点,您有什么想法吗?提前谢谢。
发布于 2016-08-23 22:45:16
您可以直接使用sklearn计算稀疏矩阵的行上的成对余弦相似度。从0.17版本开始,它还支持稀疏输出:
from sklearn.metrics.pairwise import cosine_similarity
from scipy import sparse
A = np.array([[0, 1, 0, 0, 1], [0, 0, 1, 1, 1],[1, 1, 0, 1, 0]])
A_sparse = sparse.csr_matrix(A)
similarities = cosine_similarity(A_sparse)
print('pairwise dense output:\n {}\n'.format(similarities))
#also can output sparse matrices
similarities_sparse = cosine_similarity(A_sparse,dense_output=False)
print('pairwise sparse output:\n {}\n'.format(similarities_sparse))
结果:
pairwise dense output:
[[ 1. 0.40824829 0.40824829]
[ 0.40824829 1. 0.33333333]
[ 0.40824829 0.33333333 1. ]]
pairwise sparse output:
(0, 1) 0.408248290464
(0, 2) 0.408248290464
(0, 0) 1.0
(1, 0) 0.408248290464
(1, 2) 0.333333333333
(1, 1) 1.0
(2, 1) 0.333333333333
(2, 0) 0.408248290464
(2, 2) 1.0
如果你想要列余弦相似性,只需事先转置你的输入矩阵:
A_sparse.transpose()
发布于 2013-12-20 01:26:54
下面的方法大约比scipy.spatial.distance.pdist
快30倍。它在大型矩阵上的运行速度非常快(假设您有足够的RAM)
有关如何优化稀疏性的讨论,请参阅下面的内容。
# base similarity matrix (all dot products)
# replace this with A.dot(A.T).toarray() for sparse representation
similarity = numpy.dot(A, A.T)
# squared magnitude of preference vectors (number of occurrences)
square_mag = numpy.diag(similarity)
# inverse squared magnitude
inv_square_mag = 1 / square_mag
# if it doesn't occur, set it's inverse magnitude to zero (instead of inf)
inv_square_mag[numpy.isinf(inv_square_mag)] = 0
# inverse of the magnitude
inv_mag = numpy.sqrt(inv_square_mag)
# cosine similarity (elementwise multiply by inverse magnitudes)
cosine = similarity * inv_mag
cosine = cosine.T * inv_mag
如果你的问题是典型的大规模二元偏好问题,那么你在一个维度上的条目要比另一个维度多得多。此外,短维度是您要计算其条目之间的相似性的维度。让我们将这个维度称为“item”维度。
如果是这样的话,在行中列出您的“项目”,并使用scipy.sparse
创建A
。然后按照指示替换第一行。
如果你的问题是非典型的,你需要更多的修改。这些应该是用它们的scipy.sparse
等价物非常直接地替换基本的numpy
操作。
发布于 2017-09-30 17:31:19
我已经尝试了上面的一些方法。然而,@zbinsd的实验有其局限性。实验中使用的矩阵稀疏度极低,而实际稀疏度通常在90%以上。在我的条件下,稀疏的形状是(7000,25000),稀疏度是97%。方法4非常慢,我不能容忍得到结果。我使用方法6,它在10秒内完成。令人惊讶的是,我尝试了下面的方法,它只用了0.247秒就完成了。
import sklearn.preprocessing as pp
def cosine_similarities(mat):
col_normed_mat = pp.normalize(mat.tocsc(), axis=0)
return col_normed_mat.T * col_normed_mat
这种高效的方法是通过enter link description here链接的
https://stackoverflow.com/questions/17627219
复制相似问题