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



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

tfidf_matrix = tfidf_transformer.fit_transform(posting)

现在我有了一个查询,

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

所以我想用scipy. space .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)的每一行?

我注意到的第一件事是,每次通过for循环(或每次迭代map()调用)时,您都在运行query[0].toarray()。这个值会在行与行之间改变吗?因为如果不是,您可以通过在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)

可能还有其他的加速方法,但是试试这个,看看是否有帮助。

EDIT:另外,您是否见过numpy's矩阵行/列上的函数应用程序?看起来vectorize函数可能是您想要的。我不能给你更多的细节,因为我自己不太熟悉numpy和scipy,但这看起来是一个很好的阅读起点。

最新更新