Python: эквивалентно svds (A, k) Matlab для больших массивов? - PullRequest
5 голосов
/ 12 февраля 2011

Я пытаюсь перенести некоторый код из Matlab в Python, и я столкнулся с проблемой. Я не могу найти эквивалент svds.

Я пытался использовать numpy.corrcoef, а затем numpy.linalg.eig, но numpy.corrcoef не работает для больших массивов (скажем, 500 x 20000).

Вот код в Matlab, на случай, если он что-то изменит:

s = size(data, 2)
mean = sum(data, 2)/s
m_data = ( data - repmat(mean, 1, s) ) / sqrt(s - 1)
[res_u,res_s] = svds(m_data, s)
eigenvals = diag(res_s).^2
eigenvecs = res_u

Ответы [ 2 ]

3 голосов
/ 12 февраля 2011

Итак, то, что вы ищете, будет примерно таким в python и numpy (я взял на себя смелость не "напрямую переводить" matlab -код в python и numpy, вместо этогоЯ немного изменил рефакторинг, чтобы «почувствовать» больше pythonic [of'course, довольно похожий рефакторинг можно применить и к matlab -коду]]:

import numpy as np

def _cas(D):
    """Center at mean and standardize."""
    return (D- D.mean(1)[:, None])/ (D.shape[1]- 1)** .5

def example(D):
    """Eigenvalues and -vectors, based on SVD."""
    u, s, v= np.linalg.svd(D, full_matrices= False);
    return np.diag(s)** 2, u

if __name__ == '__main__':
    data= np.random.rand(5, 20)
    data= _cas(data) # preprocess data according to your requirements
    eigenvals, eigenvecs= example(data)
    print eigenvals
    print eigenvecs

Но у вас есть производительностьпроблема с этим?

Можете ли вы теперь более точно указать текущую производительность, и насколько вы действительно можете ожидать ее повышения?В моем скромном компьютере случайная (500, 20000) матрица потратит на выполнение example(.) около 20 секунд.

Я могу тривиально (благодаря базовой линейной алгебре) сократить время выполнения до уровня, равного 2,5 с (почти 10-кратное улучшение)!Теперь, если вы ищете гораздо лучшую производительность, чем эта, то, пожалуйста, уточните более детально о «природе» вашего data!

Откуда поступают ваши данные?В каком конкретном случае вы используете вычисленные собственные значения и -векторы?т. е. какова ваша главная цель?

2 голосов
/ 12 февраля 2011

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

Если ваша матрица плотная, то 500 на 20000 велики, но в наше время на настольных компьютерах трудно решить проблему. Вы звоните numpy.linalg.svd с full_matrices=False, верно?

Для чего вы используете numpy.corrcoef? Ничего подобного не появляется в опубликованном вами фрагменте кода MATLAB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...