В чем разница между numpy.linalg.lstsq и scipy.linalg.lstsq?
lstsq
пытается решить Ax=b
минимизацию |b - Ax|
. Оба scipy и numpy предоставляют функцию linalg.lstsq
с очень похожим интерфейсом. В документации не упоминается, какой тип алгоритма используется, ни для scipy.linalg.lstsq, ни для numpy.linalg.lstsq, но, похоже, это почти то же самое.
Реализация, по-видимому, отличается от scipy.linalg.lstsq и numpy.linalg.lstsq. Оба, кажется, используют LAPACK, оба алгоритма, похоже, используют SVD.
Где разница? Какой из них я должен использовать?
Примечание. не путайте linalg.lstsq
с scipy.optimize.leastsq
, который также может решить проблемы нелинейной оптимизации.
Ответы
Ответ 1
Если я правильно прочитал исходный код (Numpy 1.8.2, Scipy 0.14.1
), numpy.linalg.lstsq()
использует процедуру LAPACK xGELSD
и scipy.linalg.lstsq()
использует xGELSS
.
LAPACK Manual Sec. 2.4 утверждает
Подпрограмма xGELSD значительно быстрее, чем ее старший аналог xGELSS, особенно для больших проблем, но может потребовать несколько больше рабочего пространства в зависимости от размеров матрицы.
Это означает, что Numpy работает быстрее, но использует больше памяти.
Обновление августа 2017 года:
Scipy теперь использует xGELSD по умолчанию https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lstsq.html
Ответ 2
Numpy 1.13 - Июнь 2017
Начиная с Numpy 1.13 и Scipy 0.19, и scipy.linalg.lstsq() и numpy.linalg.lstsq() вызывает по умолчанию тот же самый код LAPACK DSGELD (см. LAPACK).
Однако текущее важное различие между двумя функциями заключается в принятом стандартном параметре RCOND LAPACK по умолчанию (называемом rcond
от Numpy и cond
от Scipy), который определяет порог для сингулярных значений.
Scipy использует хороший и надежный порог по умолчанию RCOND=eps*max(A.shape)*S[0]
, где S[0]
является наибольшим сингулярным значением A
, а Numpy использует пороговое значение по умолчанию RCOND=-1
, что соответствует установке в LAPACK порога, равного точность машины, независимо от значений A
.
По умолчанию подход по принципу "Numpy" практически бесполезен в реалистичных приложениях и, как правило, приводит к очень вырожденному решению, когда A
почти не имеет ранга, теряя точность разложения сингулярных значений SVD, используемого DSGELD. Это означает, что в Numpy необязательный параметр rcond
должен быть всегда.
Обновление: Numpy 1.14 - Январь 2018
Я сообщил о некорректном по умолчанию rcond
(см. выше раздел) в numpy.linalg.lstsq(), и теперь функция a FutureWarning
в Numpy 1.14 (см. Будущие изменения).
Будущее поведение будет идентичным как в scipy.linalg.lstsq(), так и в numpy.linalg.lstsq(). Другими словами, Scipy и Numpy будут использовать не только один и тот же код LAPACK, но также использовать те же значения по умолчанию.
Чтобы начать использовать правильное (то есть будущее) значение по умолчанию в Numpy 1.14, следует вызвать numpy.linalg.lstsq() с явным rcond=None
.