Разреженные матрицы в Python с помощью Scipy

автор рубрика ,
Разреженные матрицы в Python с помощью Scipy

В предыдущей статье мы говорили о том, как можно представлять разреженные матрицы. Сегодня рассмотрим их создание с примерами кода на Python с помощью библиотеки Scipy. Читайте в этой статье: как можно создать разреженные матрицы в Python, как создаются матрицы формата списка координат (COOrdinate list), сжатого хранения столбцом (Compresed Sparse Row) и строкой (Compresed Sparse Column).

Способы создания разреженных матрицы Scipy

Самый простой формат представления разреженных матриц – это список координат (COOrdinate list, COO). Согласному этому представлению компьютер хранит массивы строк и столбцов ненулевых значений, а также сами ненулевые значения.

В Scipy разреженные матрицы создаются с помощью модуля sparse, который имеет соответствующие форматы. Их можно создать несколькими способами, передав в качестве аргументов:

  • плотную матрицу,
  • другую разреженную матрцу,
  • форму матрицы (вернется пустая матрица)
  • массивы с индексами строк и столбцов и сами значенния.

Разреженные матрицы Scipy имеют полезные методы для конвертации в плотные (todense или toarray), сжатые строкой (tocsr) и сжатые столбцом (tocsc).

Как создать список координат в Scipy

Создадим разреженную матрицу на основе плотной матрицы из предыдущей статьи. Пример кода на Python того, как создаются разреженные матрицы Scipy:

import numpy as np
import scipy.sparse as sparse

arr = np.array([
    [0, 1, 0, 0, 0, 0, 0],
    [0, 0, 2, 1, 0, 0, 1],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0, 3, 0],
])

print(sparse.coo_matrix(arr))

# Результат:
(0, 1)        1
(1, 2)        2
(1, 3)        1
(1, 6)        1
(3, 3)        1
(3, 5)        3

Как видите, результат тот же, что мы проделывали вручную. Первым элементом вернувшегося массива является индекс строки, вторым – индекс столбца, а справа – ненулевые значения, соответствующим этим индексам.

Мы могли бы также передать массивы индексов строк и столбцов с ненулевыми значениями. Вот так это выглядит в Python:

import numpy as np
import scipy.sparse as sparse

rows = [0, 1, 1, 1, 3 ,3]
cols = [1, 2, 3, 6, 3, 5]
data = [1, 2, 1, 1, 1, 3]

coo = sparse.coo_matrix((data, (rows, cols)))
# Результат тот же, что и выше

Преимущества списка координат:

  • обеспечивает быстрое преобразование между разреженными форматами, например, CSR и CSC;
  • разрешает повторяющиеся индексы, поэтому легко изменять форму.

Недостатки списка координат:

  • не поддерживает напрямую арифметические операции и извлечение подматриц (slicing).

Как создать с форматом сжатого хранения строкой (CSS) в Scipy

Сжатое хранение строкой (Compressed Sparse Row, CSR) подразумевает подсчет кумулятивной суммы количества элементов в строке вместо индексов строк.

В Python-библиотеке Scipy для создания разреженных матриц с сжатым хранением строкой используется функция csr_matrix:

# `arr' тот же, что и выше
csr = sparse.csr_matrix(arr)
print(csr)

# Результат:
(0, 1)        1
(1, 2)        2
(1, 3)        1
(1, 6)        1
(3, 3)        1
(3, 5)        3

Разреженные матрицы данного формата поддерживают арифметические операции: сложение, вычитание, умножение, деление и возведение в степень.

Преимущества сжатого хранения строкой:

  • эффективные операции с матрицами такого же формата (CSR + CSR, CSR * CSR и т.д.);
  • эффективное извлечение строк;
  • быстрое умножение матриц.

Недостатки сжатого хранения строкой:

  • медленное извлечение столбцов;
  • медленное преобразование в форматы список списков (LIL) и словарь ключей (DOK).

Как создать с форматом сжатого хранения столбцом (CSС) в Scipy

Сжатое хранение столбцом (Compressed Sparse Column, CSС) подразумевает подсчет кумулятивной суммы количества элементов в столбце. В машинном обучении (machine learning) CSС-матрицы наиболее распространены, так как часто приходится работать с набором признаков, которые как раз и составляют столбцы.

В Python-библиотеке Scipy для создания разреженных матриц с сжатым хранением столбцом используется функция csc_matrix:

csc = sparse.csc_matrix(arr)
print(csc)

# Результат:
(0, 1)        1
(1, 2)        2
(1, 3)        1
(3, 3)        1
(3, 5)        3
(1, 6)        1

Обратите внимание, что последними элементами идет 3, а затем 1, поскольку подсчет происходит по столбам, а столбец с со значением 3 встречается раньше значения 1.

Преимущества и недостатки такие же, как у CSR, но только вместо строк используются столбцы.

 

Больше подробностей о работе с разреженными матрицами в Python для решения задач Data Science вы узнаете на специализированном курсе по машинному обучению «PYML: Введение в машинное обучение на Python» в лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.

Источники
  1. https://docs.scipy.org/doc/scipy/reference/sparse.html
Комментировать