В 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 в Москве.



