Единичные значения, отсортированные в порядке убывания с использованием svd из scipy.sparse.linalg

Я применяю SVD к большой разреженной матрице в Python. Я использую svd из пакета scipy.sparse.linalg. Сингулярные значения сортируются по возрастанию, поэтому сингулярные векторы располагаются в соответствии с возрастанием сингулярных значений. Мне интересно, есть ли возможность выводить сингулярные значения в порядке убывания, чтобы сингулярные векторы также располагались в соответствии с нисходящими сингулярными значениями? Ниже приведен только пример кода:

from scipy.sparse.linalg import svds
from scipy import sparse
X = numpy.random.uniform(size = [40, 20])
X = scipy.sparse.csc_matrix(X)
u, s, vt = svds(X, 10, which = 'LM')

Я пробовал библиотеку Python sparsesvd. Время выполнения sparsesvd намного больше по сравнению с svd на образце матрицы. Поэтому я не рассматриваю возможность использования sparsesvd. Обычный пакет svd в scipy не работает для разреженной матрицы. Спасибо!


person user2498497    schedule 30.06.2014    source источник
comment
Вы пытаетесь вычислить наименьшие сингулярные значения, или вывести N больших сингулярных векторов в другом порядке? Если второе, то u = u[:,::-1]; s = s[::-1]; vt = vt[::-1,:] (или что-то подобное) должно быть достаточно.   -  person pv.    schedule 01.07.2014


Ответы (1)


Теперь вы ищете 10 самых больших сингулярных значений и получаете их в порядке возрастания вместе с левым и правым сингулярными векторами. Если вам нужны n наименьших значений, просто измените ключевое слово which на SM.

Однако я понимаю, что вы получаете правильные сингулярные значения, но в неправильном порядке. Для этого в функции нет переключателя, но векторы и значения можно переставить по следующему правилу: первые n столбцов u и первые n строк vt должны храниться в том же порядке, что и единственные значения.

Итак, обращая сингулярные значения:

n = len(s)
# reverse the n first columns of u
u[:,:n] = u[:, n-1::-1]
# reverse s
s = s[::-1]
# reverse the n first rows of vt
vt[:n, :] = vt[n-1::-1, :]

Это очень просто (как и указано pv в его комментарии), но хитрость заключается не в перестановке полных матриц, а только в соответствующих строках/столбцах. И, естественно, подойдет любая перестановка, поэтому в общем случае (perm — вектор перестановки):

u[:,:n] = u[:, perm]
s = s[perm]
vt[:n, :] = vt[perm, :]
person DrV    schedule 30.06.2014