Время прочтения: 4 мин.

MLlib – это библиотека функций для машинного обучения, входящий в состав Spark. Главным преимуществом MLlib от остальных библиотек машинного обучения является то, что она работает в кластерах Spark и может работать с распределёнными данными. При работе с MLlib можно использовать все языки программирования, которые поддерживает Spark: Scala, Python, Java.

Работая с машинным обучением, не хватает стандартных типов данных языка программирования. Например, вектора — нужны в качестве данных для алгоритмов машинного обучения, вот некоторые из них в MLlib:

  • Vector – последовательность признаков, реализованная в виде одномерного массива данных. Векторы бывают двух типов: плотные, хранящие все элементы, и разреженные, хранящие только ненулевые значения для экономии памяти, MLlib поддерживает оба типа. Векторы создаются с помощью класса mllib.linalg.Vector;
  • LabeledPoint — маркированная точка в пространстве данных для использования в алгоритмах обучения, таких как классификация и регрессия. Включает вектор признаков и маркер (являющийся вещественным числом). Определение находится в пакете mllib. regression package;
  • Rating — оценка продукта пользователем, используемая в пакете mllib. recommendation для определения рекомендаций;
  • семейство классов Model — все модели типа Model являются результатом работы алгоритма обучения и обычно имеют метод predict () для применения модели к новой точке или к набору RDD новых точек данных.

Для наборов этих элементов нужны данные, их конечно можно создать вручную или загрузить из файлов, но как я уже говорил основная идея MLlib и Spark в целом это работа с распределёнными данными. Для этого и служит SparkSQL, у которого с MLlib как и с другими его библиотеками есть тесная связь, они все используют наборы данных RDD (простая, неизменяемая, распределённая коллекция объектов во фреймворке Apache Spark).

Конечно же помимо типов данных в MLlib есть еще и алгоритмы, представленные в виде методов. Например, метод для создания вектора или выделения признаков для текста, для подготовки данных:

Term Frequency — lnverse Document Frequency (частота слова — обратная частота документа), или TF-IDF — это простой алгоритм создания векторов признаков для текстовых документов

Word2Vec 1 — это алгоритм выделения признаков для текста на основе нейронных сетей, который можно использовать для подготовки данных к обработке следующими за ним алгоритмами

Хватит теории, давайте приступать к практике. Передо мной стояла задача классификации электронных писем. Для этого мне понадобилось два алгоритма:

— HashingTF – создающий вектор частот встречаемости терминов (tern frequency) в тексте.

— Logistic Regression With SGD реализующий процедуру логистической регрессии (logistic regression) методом стохастического градиентного спуска (Stochastic Gradient Descent, SGD).

Для выполнения этой задачи необходимо выполнить такие шаги как:

  1. создать набор RDD строк, представляющих содержимое электронных писем;
  2. выполнить один из алгоритмов извлечения признаков (feature extraction) в библиотеке MLlib, чтобы преобразовать текст в числовые признаки (пригодные для использования в алгоритмах обучения). В результате будет получен набор RDD векторов;
  3. вызвать алгоритм классификации (например, алгоритм логистической регрессии (logistic regression)) для обработки набора RDD векторов. В результате будет получена объектная модель, которую затем можно использовать для классификации новых точек;
  4. применить модель к тестовому набору данных с использованием одной из функций библиотеки MLlib.

Теперь реализуем это в виде кода. Подключим все нужные модули и создадим SparkContext.

from pyspark import SparkContext
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.classification import LogisticRegressionWithSGD
from pyspark.mllib.feature import HashingTF
sc = SparkContext(appName="MlLibExample")

Нам понадобится файл spam.txt с электронными письмами со спамом и normal.txt – без спама, в которых каждая строка — это отдельное сообщение. Загрузим данные с файлов.

spam = sc.textFile("spam.txt") 
normal = sc.textFile("normal.txt")

Далее запишем каждое письмо в виде вектора признаков, для этого создадим объект HashingTF.

hash_tf = HashingTF(numFeatures = 10000)

Затем запишем каждую строку в вектор признаков.

spam_featr = spam.map(lambda x: hash_tf.transform(x.split(" ")))
normal_featr = normal.map(lambda x: hash_tf.transform(x.split(" ")))

Создадим два примера: с положительной реакцией (спам) и с отрицательной (обычные письма), для этого понадобился набор данных LabeledPoint.

positive_ex = spam_featr.map(lambda x: LabeledPoint(1, x))
negative_ex = normal_featr.map(lambda x: LabeledPoint(0, x))
educ_sample = positive_ex.union(negative_ex)
educ_sample.cache() 

Далее произведем обучение модели логической регрессии для разделения сообщений двух типов с помощью метода SGD.

model = LogisticRegressionWithSGD.train(educ_sample)

Почти все, модель обучена. Теперь, чтобы ее протестировать, надо подать ей тестовый вариант письма. Но подать ей строку нельзя, надо снова перед этим преобразовать строку в вектор признаков с помощью HashingTF.

pos_test = hash_tf.transform("O M G GET cheap stuff by sending money to ...".split(" "))
neg_test = hash_tf.transform("Hi Dad, I started studying Spark the other ...".split(" "))

Теперь мы можем пользоваться моделью для определения спама.

print "Прогнозирование для положительного примера текста: %g" % model.predict(pos_test)
    print " Прогнозирование для негативного примера текста: %g" % model.predict(neg_test)

Ну вот мы и познакомились с библиотекой MLlib Spark. Философия MLlib очень проста: библиотека позволяет выполнять разные алгоритмы на распределённых массивах данных используя наборы данных RDD, благодаря чему осуществляется тесная связь с остальными инструментами Spark, такими как: Spark SQL, Spark Streaming, Spark GraphX.