Python中的反向排序和索引排序

16 投票
1 回答
36385 浏览
提问于 2025-04-17 08:02

我正在尝试用Python写一个函数(我还是个新手!),这个函数的作用是根据文档的tfidf分数的内积,返回文档的索引和分数,并按顺序排列。具体步骤是:

  • 计算文档idx与所有其他文档之间的内积向量
  • 按降序排列
  • 返回从第二个开始到最后的“分数”和索引(也就是说,不包括自己)

我现在的代码是:

import h5py
import numpy as np

def get_related(tfidf, idx) :
    ''' return the top documents '''

    # calculate inner product   
    v = np.inner(tfidf, tfidf[idx].transpose())

    # sort
    vs = np.sort(v.toarray(), axis=0)[::-1]
    scores = vs[1:,]

    # sort indices
    vi = np.argsort(v.toarray(), axis=0)[::-1]
    idxs = vi[1:,] 

    return (scores, idxs)

其中tfidf是一个类型为''的稀疏矩阵。

这似乎效率不高,因为排序操作执行了两次(先是sort(),然后是argsort()),而且结果还得反转。

  • 有没有更高效的方法?
  • 有没有办法不使用toarray()来转换稀疏矩阵?

1 个回答

11

我觉得没有必要跳过 toarray 这个步骤。因为 v 数组的长度只有 n_docs,在实际情况中,这个长度比 n_docs × n_terms 的 tf-idf 矩阵要小得多。而且,这个数组会非常密集,因为任何两个文档之间共享的词都会让它们的相似度不为零。稀疏矩阵的表示方式只有在你存储的矩阵非常稀疏时才有意义(我见过 Matlab 的稀疏度超过 80%,我想 Scipy 也差不多,虽然我没有确切的数字)。

双重排序可以通过以下方式跳过:

v = v.toarray()
vi = np.argsort(v, axis=0)[::-1]
vs = v[vi]

顺便说一下,你在稀疏矩阵上使用 np.inner 在最新版本的 NumPy 中是行不通的;安全的方式来计算两个稀疏矩阵的内积是:

v = (tfidf * tfidf[idx, :]).transpose()

撰写回答