Обратный сортировка и argsort в python
Я пытаюсь написать функцию в Python (все еще noob!), которая возвращает индексы и множество документов, упорядоченных внутренними продуктами их оценок tfidf. Процедура такова:
- Вычислить вектор внутренних продуктов между doc
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
является sparse matrix of type '<type 'numpy.float64'>'
.
Это кажется неэффективным, так как сортировка выполняется дважды (sort()
then argsort()
), и результаты должны быть затем отменены.
- Можно ли это сделать более эффективно?
- Можно ли это сделать без преобразования разреженной матрицы с помощью
toarray()
?
Ответы
Ответ 1
Я не думаю, что есть настоящая необходимость пропустить toarray
. Массив v
будет длиннее n_docs
, что затмевается размером матрицы n_docs
× n_terms
tf-idf в практических ситуациях. Кроме того, он будет довольно плотным, поскольку любой термин, разделяемый двумя документами, даст им ненулевое сходство. Редкие матричные представления только окупаются, когда матрица, которую вы храните, очень разрежена (я видел > 80% цифры для Matlab и предполагаю, что Scipy будет похож, хотя у меня нет точной цифры).
Двойную сортировку можно пропустить, выполнив
v = v.toarray()
vi = np.argsort(v, axis=0)[::-1]
vs = v[vi]
Btw., использование np.inner
в разреженных матрицах не будет работать с последними версиями NumPy; безопасный способ взять внутренний продукт из двух разреженных матриц -
v = (tfidf * tfidf[idx, :]).transpose()