将函数(余弦相似度)映射到scipy.csr_matrix中每行的更好方法

时间:2015-10-12 09:23:50

标签: python scipy

假设我有一个稀疏的文档集合矩阵,其中每一行都是一个表示文档的向量(例如,由scikit-learn&#t; tfidf_transformer生成)。

tfidf_matrix = tfidf_transformer.fit_transform(posting)

现在我有一个查询,

query = transformer.transform(vectorizer.transform(['I am a sample query']))

所以我想使用scipy.spatial.distance.cosine(余弦相似度)将此查询与矩阵的每个文档(每行)进行比较。所以我按照以下方式制作地图

result = map(lambda document: cosine(document.toarray(), query[0].toarray()), tfidf_matrix)

也可以用循环来完成

result = []
for row in tfidf_matrix:
    result = result + [cosine(row.toarray(), query[0].toarray())]

然而,它很慢(我把gevent.threadpool.map扔到了同样结果的挫折中)。我很确定这不是正确的方法(将函数映射到稀疏矩阵的每一行),但我似乎无法找到正确的方法。

所以问题是,将函数映射到稀疏矩阵(scipy.csr_matrix)中每一行的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

我注意到的第一件事是,每次通过query[0].toarray()循环(或for调用的每次迭代)时,您都在运行map()。这个值是否会在行之间发生变化?因为如果不是,你可以通过在for循环之外只计算一个来节省一些时间:

result = []
query_array = query[0].toarray()
for row in tfidf_matrix:
    result = result + [cosine(row.toarray(), query_array)]

另外,不要result = result + [another_list_element];这比result.append(another_list_element)要慢得多。在这种情况下,您应该这样做:

result = []
query_array = query[0].toarray()
for row in tfidf_matrix:
    result.append(cosine(row.toarray(), query_array))

或者使用map,即:

query_array = query[0].toarray()
result = map(lambda document: cosine(document.toarray(), query_array), tfidf_matrix)

也可能有其他加速,但试试这个,看它是否有帮助。

编辑:另外,您看过Function application over numpy's matrix row/column了吗?看起来vectorize函数可能就是您想要的。我不能给你更多的细节,因为我自己并不熟悉numpy和scipy,但这看起来是你阅读的一个很好的起点。