Ошибка памяти Numpy dot product для небольших матриц

#numpy #memory #scipy #sparse-matrix #matrix-multiplication

#numpy #память #scipy #разреженная матрица #умножение матрицы

Вопрос:

Я хотел реализовать разложение по сингулярным значениям (SVD) в качестве метода совместной фильтрации для рекомендательных систем. У меня есть это sparse_matrix , со строками, представляющими пользователей, и столбцами, представляющими элементы, и каждая запись матрицы в качестве рейтинга пользовательского элемента.

 >>> type(sparse_matrix)
scipy.sparse.csr.csr_matrix
 

Сначала я разложил эту матрицу на множители, используя SVD:

 from scipy.sparse.linalg import svds
u, s, vt = svds(sparse_matrix.asfptype(), k = 2)
s_diag = np.diag(s)
 

Затем я делаю прогноз, беря скалярное произведение u , s_diag , и vt :

 >>> tmp = np.dot(u, s_diag)
>>> pred = np.dot(tmp, vt)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
 

Я получил ошибку памяти. Тем не менее, я проверил размер и использование памяти tmp и vt :

 >>> tmp.shape
(686556, 2)
>>> tmp.nbytes
10984896
>>> vt.shape
(2, 85539)
>>> vt.nbytes
1368624
 

это означает, что tmp это около 11 МБ и vt составляет 1,4 МБ. Но на момент np.dot(tmp, vt) моей системы доступно более 50 ГБ свободной памяти, что кажется достаточным для этого вычисления. Итак, почему я получаю эту ошибку памяти? Что-то не так с моим кодом? Или это np.dot очень дорого с точки зрения использования памяти?

Комментарии:

1. s_diag является плотным. tmp также. Вы комбинируете tmp и vt в малом 2-м измерении. Таким pred образом, будет большой плотный массив (686556, 85539)

2. @hpaulj вы имеете в виду, что это pred будет 686556 * 85539 * 8 байт = 470 ГБ, что вызывает ошибку памяти?

3. да, что-то в этом роде!

Ответ №1:

Я думаю, вы получаете эту ошибку, потому что np.dot не может обрабатывать разреженные матрицы.

В качестве проверки, пожалуйста, попробуйте преобразовать матрицы в полные.

проверьте разреженную документацию (https://docs.scipy.org/doc/scipy/reference/sparse.html )

попробуйте:

 np.dot(u.toarray(), s_diag.toarray())
 

или используйте

 u.dot(s_diag)
 

Комментарии:

1. спасибо за ответ, но u , vt и s_diag имеют numpy.ndarray тип, который не имеет атрибута toarray