python - 与 numpy 的大型稀疏矩阵的余弦相似度

标签 python numpy memory matrix cosine-similarity

下面的代码导致我的系统在完成之前耗尽内存。

您能否建议一种更有效的方法来计算大型矩阵的余弦相似度,例如下面的方法?

我想计算原始矩阵 (mat) 中 65000 行中每一行相对于所有其他行的余弦相似度,以便结果是一个 65000 x 65000 矩阵,其中每个元素是原始矩阵中两行之间的余弦相似度。

import numpy as np
from scipy import sparse
from sklearn.metrics.pairwise import cosine_similarity

mat = np.random.rand(65000, 10)

sparse_mat = sparse.csr_matrix(mat)

similarities = cosine_similarity(sparse_mat)

运行完最后一行后,我总是内存不足,程序要么死机,要么因 MemoryError 而崩溃。无论我是在 8 GB 本地 RAM 上还是在 64 GB EC2 实例上运行,都会发生这种情况。

最佳答案

同样的问题。我有一个很大的非稀疏矩阵。它适合内存,但 cosine_similarity 因未知原因崩溃,可能是因为它们在某处复制矩阵一次太多。所以我让它比较“左边”的小批量行而不是整个矩阵:

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

def cosine_similarity_n_space(m1, m2, batch_size=100):
    assert m1.shape[1] == m2.shape[1]
    ret = np.ndarray((m1.shape[0], m2.shape[0]))
    for row_i in range(0, int(m1.shape[0] / batch_size) + 1):
        start = row_i * batch_size
        end = min([(row_i + 1) * batch_size, m1.shape[0]])
        if end <= start:
            break # cause I'm too lazy to elegantly handle edge cases
        rows = m1[start: end]
        sim = cosine_similarity(rows, m2) # rows is O(1) size
        ret[start: end] = sim
    return ret

我没有崩溃; YMMV。尝试不同的批量大小以使其更快。我过去一次只比较 1 行,在我的机器上花费了大约 30 倍的时间。

愚蠢但有效的完整性检查:

import random
while True:
    m = np.random.rand(random.randint(1, 100), random.randint(1, 100))
    n = np.random.rand(random.randint(1, 100), m.shape[1])
    assert np.allclose(cosine_similarity(m, n), cosine_similarity_n_space(m, n))

关于python - 与 numpy 的大型稀疏矩阵的余弦相似度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40900608/

相关文章:

python - 在 python 中使用另一个类的方法中的变量

python - Scrapy如何在爬取完所有页面后运行函数

python - 我创建了一个 Python egg;怎么办?

python - 优化python中的2D-1D操作

go - 如何改进实现的文件下载器

ios - 检查用户手机上是否有足够的可用空间来录制视频

python:使用 itsdangerous 生成 API token

python - 为什么我不能在 gdal 模块中等待 readasarray 方法?

python - 更改 numpy 数组的格式而不使用循环

c++ - 将读取的内存过程存储在缓冲区中,然后对其进行搜索