Локальный вектор и матрица: базовые структуры данных Spark MLlib

В Spark MLlib есть разные типы векторов и матриц. MLlib поддерживает локальные векторы и матрицы, хранящиеся на одной машине, а также распределенные матрицы, поддерживаемые одним или несколькими RDD. Сегодня познакомимся с локальными векторами и матрицами. Читайте в этой статье: как создаются плотные (dense) и разреженные (sparse) векторы, зачем нужны маркированные векторы и как представляются матрицы Spark MLlib с примерами кода на Scala и Python.

Локальные векторы: плотные и разреженные

Локальный вектор имеет целочисленные (int) или действительные (double) значения, хранящиеся на одной машине. Spark MLlib поддерживает два типа локальных векторов: плотные и разрезженные. Плотные векторы представляются обычными массивами, где каждый элемент значимый. Разреженные векторы представляются двумя параллельными массивами, где первый массив — это индексы ненулевых значений, а второй массив — сами ненулевые значения. Например, вектор (1.0, 0.0, 3.0) может быть представлен в виде:

  • полного вектора [1.0, 0.0, 3.0],
  • разреженного вектора (3, [0, 2], [1.0, 3.0]), где 3 — это размер вектора (нулевое значение не записывается).

Оба вида векторов наследуются от класса Vector и имеют соответственно реализации DenseVector и SparseVector [1]. Рекомендуется использовать класс Vectors, реализующий фабричный метод, и вызывать через него методы dense или sparse. В Scala полный и разреженный векторы Spark MLlib выглядят следующим образом:

import org.apache.spark.mllib.linalg.{Vector, Vectors}

// Представляем массив (1.0, 0.0, 3.0)
// в виде полного вектора:
val dv: Vector = Vectors.dense(1.0, 0.0, 3.0)
// в виде разреженного вектора:
val sv1: Vector = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0))

В Python полный и разреженный векторы Spark MLlib создаются аналогичным образом. Причем, полным вектором может выступать стандартные списки Python или массивы NumPy. Лучше отдавать предпочтение массивам NumPy, чем стандартным спискам, поскольку первые работают быстрее. В качестве разреженных: массивы csc_matrix от Scipy или SparseVector от MLlib.

Код на Python для создания полных и разреженных векторов выглядит так:

from pyspark.mllib.linalg import Vectors
import numpy as np
import scipy.sparse as sps

# Полные векторы
dv1 = Vectors.dense([1.0, 0.0, 3.0])
dv2 = np.array([1.0, 0.0, 3.0])

# Разреженные:
sv1 = Vectors.sparse(3, [0, 2], [1.0, 3.0])
sv2 = sps.csc_matrix((np.array([1.0, 3.0]),
                      np.array([0, 2]),
                      np.array([0, 2])), 
                     shape=(3, 1))

Маркированный вектор (Labeled point) в Spark MLlib

Маркированный вектор — это локальный полный или разреженный вектор, который ассоциирован с меткой. В Spark MLlib такие вектора необходимы в качестве данных для алгоритмов машинного обучения (machine learning). Метки имеют тип double, поэтому данные могут быть применяется как для задач регрессии, так и классификации. Для создания маркированного вектора используется класс LabeledPoint.

На Scala маркированные векторы Spark MLlib инициализируются следующим образом:

import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint

val pos = LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0))
val neg = LabeledPoint(0.0, Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)))

Код на Python для создания маркированных векторов Spark MLlib:

from pyspark.mllib.linalg import SparseVector
from pyspark.mllib.regression import LabeledPoint

pos = LabeledPoint(1.0, [1.0, 0.0, 3.0])
neg = LabeledPoint(0.0, SparseVector(3, [0, 2], [1.0, 3.0]))

Локальная матрица (Local matrix) в Spark MLlib

Локальная матрица — это двумерный вектор с действительными значениями, хранящимися на одной машине. Матрицу можно воспринимать как таблицу: обращение к значениям осуществляется через индексы строки и столбца. Локальная матрица может выражаться через плотный вектор, который записывается в порядке перечисления столбцов, или через разреженный вектор со значениями, которые хранятся в формате CSC (Compressed Sparse Column) и записываются также в порядке перечисления столбцов.

Локальная матрица реализуется через классы DenseMatrix и SparseMatrix. Для их создания рекомендуется использовать фабричный метод класса Matrices.

Код на Scala для создания матрицы с плотными и разреженными векторами Spark MLlib выглядит следующим образом:

import org.apache.spark.mllib.linalg.{Matrix, Matrices}

// Матрица:
// [(1.0, 0.0), 
    (0.0, 4.0), 
    (0.0, 6.0)]
// в плотных векторах выражается так:
val dm: Matrix = Matrices.dense(3, 2, Array(1.0, 0.0, 0.0, 0.0, 4.0, 6.0))

// в разреженных векторах так:
val sm: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 1, 2), Array(1, 4, 6))

Обратите внимание, что в плотном векторе сначала перечисляются значения столбцов. Такой порядок называется column-major order [2]. В разреженном векторе первый массив — это кумулятивная составляющая от индексов столбцов, второй — индексы строк, третий — значения. Разреженная матрица записывается по правилам CSC.

Пример кода на Python по созданию матриц с плотными и разреженными векторами выглядит так:

from pyspark.mllib.linalg import Matrices

dm2 = Matrices.dense(3, 2, [1, 0, 0, 0, 4, 6])
sm2 = Matrices.sparse(3, 2, [0, 1, 3], [0, 1, 2], [1, 4, 6])

 

В следующей статье рассмотрим распределенные матрицы. А о том, как применять векторы и матрицы для решения задач Machine Learning с реальными примерами Data Science, вы узнаете на специализированном курсе по машинному обучению «Машинное обучение в Apache Spark» в лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.

Записаться на курс

Смотреть раcписание

Источники
  1. docs/latest/api/python/reference/api/pyspark.mllib.linalg.Vectors.html
  2. en.wikipedia.org/wiki/Row-_and_column-major_order

Добавить комментарий

Поиск по сайту