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