Время прочтения: 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).
Для выполнения этой задачи необходимо выполнить такие шаги как:
- создать набор RDD строк, представляющих содержимое электронных писем;
- выполнить один из алгоритмов извлечения признаков (feature extraction) в библиотеке MLlib, чтобы преобразовать текст в числовые признаки (пригодные для использования в алгоритмах обучения). В результате будет получен набор RDD векторов;
- вызвать алгоритм классификации (например, алгоритм логистической регрессии (logistic regression)) для обработки набора RDD векторов. В результате будет получена объектная модель, которую затем можно использовать для классификации новых точек;
- применить модель к тестовому набору данных с использованием одной из функций библиотеки 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.