вычисление усеченного SVD, одно единственное значение / вектор за один раз

11

Существует ли усеченный алгоритм SVD, который вычисляет сингулярные значения по одному?

Моя проблема: я хотел бы вычислить первые k сингулярных значений (и сингулярных векторов) большой плотной матрицы M , но я не знаю, каково было бы подходящее значение k . M велико, поэтому из соображений эффективности я бы предпочел не оценивать полный SVD только для того, чтобы впоследствии урезать самые маленькие SV.

В идеале был бы способ вычислить сингулярные значения последовательно, от наибольшего ( σ 1 ) до наименьшего ( σ n ). Таким образом, я мог бы просто остановить вычисления после вычисления K - го особого значения , если σ к / σ 1 падает ниже некоторого порога.σ1,σ2,σ1σnkσk/σ1

Существует ли такой алгоритм (желательно с реализацией Python)? В моем поиске я обнаружил только усеченные SVD-функции, которые принимают k в качестве параметра, заставляя вас угадывать его априори.

SuperElectric
источник
Ваш М квадрат или прямоугольник? Если прямоугольный, вы хотите длинные или короткие единичные векторы? То есть, если M равен (mxn) с m> n, вы хотите (mxk) или (kxn)?
Макс Хатчинсон
М является прямоугольным, с гораздо большим количеством строк, чем столбцы. Я хочу короткие особые векторы (то есть V, в M = U S V ^ T).
SuperElectric

Ответы:

6

Есть несколько вариантов, если вы хотите приблизительные факторизации ранга k.

  1. Сильно выявляющие QR-факторизации
  2. Интерполативная декомпозиция (ID) и другие рандомизированные методы.

AMNTfactor×σk+1(A):=ϵ

Приблизительная факторизация вышеуказанной формы может быть преобразована в стандартное разложение, такое как QR или SVD, с использованием стандартных методов. Хороший обзор доступен в статье Халко, Мартинссона и Троппа «Нахождение структуры со случайностью: вероятностные алгоритмы для построения приближенных матричных разложений»

С точки зрения программного обеспечения интерфейс для алгоритмов идентификации доступен в scipy (scipy.linalg.interpolative) http://docs.scipy.org/doc/scipy-dev/reference/linalg.interpolative.html, который позволяет пользователю указать .ϵ

user2457602
источник
2

(Отредактировано, потому что я сначала неправильно прочитал вопрос; вы уже знаете, что существуют процедуры для вычисления первых единичных значений.)k

Если исключить подход вычисления целого SVD, алгоритмы частичного SVD сводятся к использованию итерационных методов для решения связанной эрмитовой задачи на собственные значения. Итак, одна из стратегий, которую вы могли бы выбрать, - это самостоятельно написать код такого рода и продолжать искать наибольшее оставшееся нерешенное единичное значение до тех пор, пока вы не захотите остановиться, используя что-то вроде стратегии сдвига и инвертирования. Могут быть элегантные способы сделать это в сложных пакетах, таких как SLEPc .

Другая стратегия будет следующей:

  • Вычислите наибольшее единственное значение .s1
  • Установите абсолютный допуск для разреженной процедуры SVD равным , где - ваш порог, а - это некоторый коэффициент безопасности, чтобы определить, сколько возможных сингулярных значений вы хотите вычислять.τs1fτ0<f1
  • Назовите редкую процедуру SVD.

Если разреженная процедура SVD вычисляет тонкий SVD (и я не могу понять, почему это не так), то эта стратегия дает вам все необходимые значения единственного числа (плюс, возможно, некоторые дополнительные), потому что значения ниже абсолютного допуска будут трактоваться как ноль. В этом случае вы можете использовать scipy.sparse.linalg.svds , отметив, что является необязательным параметром и вам не нужно указывать его априори .k

Джефф Оксберри
источник
Если вы не укажете «k» в scipy.sparse.linalg.svds, то по умолчанию будет установлено значение k = 6 независимо от параметра «tol». Непонятно, является ли это ошибкой или «tol» относится к точности вычисленных единичных значений (а не к их размеру)
Ник Алджер,