Навчання на великих даних: Spark MLlib

Привіт, хабр!

image

минулий раз ми познайомилися з інструментом Apache Spark, який останнім часом стає чи не найпопулярнішим засобом для обробки великих даних і зокрема, Large Scale Machine Learning. Сьогодні ми розглянемо докладніше бібліотеку MlLib, а саме — покажемо, як вирішувати задачі машинного навчання — класифікації, регресии, кластеризації, а також колаборативної фільтрації. Крім цього покажемо, як можна дослідити ознаки з метою відбору і виділення нових (т. зв. Feature Engineering, про який ми говорили раніше, причому не один раз).

План
Насамперед подивимося, як зберігати об'єкти нашої навчальної вибірки, як вважати базові статистики ознак, після чого — алгоритми машинного навчання (класифікація, регресія, кластеризація) і, нарешті, розглянемо приклад побудови рекомендаційної системи — т. зв. методи колаборативної фільтрації, а якщо бути точніше — один з найпоширеніших алгоритмів ALS.

Вектора
Для простих «щільних» векторів є спеціальний клас Vectors.dense:

from pyspark.mllib.linalg import Vectors
my_vec = Vectors.dence([1.12, 4.10, 1.5, -2.7, 3.5, 10.7, 0.7])

Для «розріджених» векторів використовується клас Vectors.sparse:

from pyspark.mllib.linalg import Vectors
my_vec = Vectors.sparse(10, [0,2,4,9], [-1.2, 3.05, -4.08, 0.46])

Тут першим аргументом є кількість ознак (довжина вектора), далі йдуть списком — номери ненульових ознак, і після — самі значення ознак.

Розмічені вектора
Для розмічених точок в Spark'е є спеціальний клас LabeledPoint:

from pyspark.mllib.regression import LabeledPoint
my_point = LabeledPoint(1.0, my_vec)

Де в класі LabeledPoint ми маємо LabeledPoint.features — будь-який з описаних вище векторів, а LabeledPoint.label — це, відповідно, мітка, яка може приймати будь-яке дійсне значення у разі завдання регресії і значення [0.0,1.0,2.0,...] — для задач класифікації

Робота з ознаками
Не секрет, що часто, щоб побудувати хороший алгоритм машинного навчання, досить просто подивитися на ознаки, відібрати з найбільш релевантні або придумати нові. Для цієї мети в спарці клас Statistics, за допомогою якого можна робити всі ці речі, наприклад:

from pyspark.mllib.stat import Statistics
summary = Statistics.colStats(features)

# meas of features
summary.mean
# non zeros features
summary.numNonzeros
# variance
summary.variance
# correlations of features
Statistics.corr(features)

Крім цього, в Spark'е є величезна кількість додаткових можливостей начебто семплювання, генерації стандартних ознак (зразок TF-IDF для текстів), а також така важлива річ, як масштабування ознак (читачеві пропонується після прочитання цієї статті подивитися в документації). Для останнього є спеціальний клас Scaler:

from pyspark.mllib.feature import StandardScaler
scaler = StandardScaler(withMean=True, withStd=True).fit(features)
scaler.transform (features.map(lambda x:x.toArray()))

Єдине, що важливо пам'ятати — у разі розріджених векторів це не працює і стратегію масштабування треба продумувати під конкретну задачу. Тепер перейдемо безпосередньо до завдань машинного навчання.

Класифікація і регресія

Лінійні методи

Найпоширенішими методами <a href=«habrahabr.ru/post/248779/>завжди є лінійні класифікатори. Навчання лінійного класифікатора зводиться до задачі опуклої мінімізації функціонала від вектора ваг. Відмінність полягає у виборі функції втрат, функції регуляризації, кількості ітерацій і безлічі інших параметрів. Для прикладу, розглянемо нижче логістичну функцію втрат (і, відповідно, т. зв. метод логістичної регресії), 500 ітерацій і L2 — регуляризацию.

import pyspark.mllib.classification as cls
model = cls.LogisticRegressionWithSGD.train(train, iterations=500, regType="l2")

Аналогічно робиться і лінійна регресія:

import pyspark.mllib.regression as regr
model = regr.RidgeRegressionWithSGD.train(train)

Наївний Байєсівської

У цьому випадку, алгоритм навчання приймає на вхід всього 2 параметра — саму навчальну вибірку і параметр згладжування:

from pyspark.mllib.classification import NaiveBayes
model = NaiveBayes.train(train, 8.5)
model.predict(test.features)

Вирішальні дерева

У спарці, як і в багатьох інших пакетах, реалізовані дерева регресії та класифікації. Алгоритм навчання приймає на вхід безліч параметрів, такі, як безліч класів, максимальна глибина дерева. Також алгоритму необхідно вказати, які категорії мають категоріальні ознаки, а також безліч інших параметрів. Проте одним із найважливіших з них при навчанні дерев є так званий impurity — критерій обчислення так званої information gain, який може приймати наступні значення: entropy та gini — для задач класифікації, variance — для завдань регресії. Для прикладу розглянемо бінарну класифікацію з параметрами, визначеними нижче:

from pyspark.mllib.tree import DecisionTree
model = DecisionTree.trainClassifier(train, numClasses=2, impurity='gini', maxDepth=5)
model.predict(test.map(lambda x: x.features))

Random Forest

Випадкові ліси, як відомо, є одними з універсальних алгоритмів і слід було очікувати, що в цьому інструменті вони будуть реалізовані. Використовують вони дерева, описані вище. Тут точно також є методи trainClassifier та trainRegression — для навчання класифікатора та функції регресії відповідно. Одними з найважливіших параметрів є — кількість дерев у лісі, вже відомий нам impurity, а також featureSubsetStrategy — кількість ознак, які розглядаються при розбитті на черговому вузлі дерева (докладніше про значеннях — див. документацію). Відповідно, нижче приклад бінарної класифікації за допомогою 50 дерев:

from pyspark.mllib.tree import RandomForest
model = RandomForest.trainClassifier(train, numClasses=2, numTrees=50, featureSubsetStrategy="авто", impurity='gini', maxDepth=20, seed=12)
model.predict(test.map(lambda x:x.features))

Кластеризація
Як і скрізь, в спарці реалізовано всім відомий алгоритм KMeans, навчання якого приймає на вхід безпосередньо датасет, число кластерів, число ітерацій, а також стратегію вибору початкових центрів кластерів (параметр initializationMode, який за замовчуванням має значення k-means, а також може приймати значення random):

from pyspark.mllib.clustering import KMeans
clusters = KMeans.train(features, 3, maxIterations=100, runs=5, initializationMode="random")
clusters.predict(x.features))

Коллаборативная фільтрація
Враховуючи, що найвідоміший приклад застосування Великих Даних — це рекомендаційна система, було б дивним, якщо б найпростіші алгоритми не були реалізовані в багатьох пакетах. Це стосується і Spark'а. В ньому реалізований алгоритм ALS (Alternative Least Square) — мабуть, один з найбільш відомих алгоритмів колаборативної фільтрації. Опис самого алгоритму заслуговує окремої статті. Тут лише скажемо в двох словах, що алгоритм фактично займається розкладанням матриці відгуків (рядки якої — це користувачі, а стовпці — продукти) — на матриці продукт — топік та топік-користувач, де топіки — це деякі приховані змінні, значення яких найчастіше не зрозумілий (вся принадність алгоритму ALS як раз в тому, щоб самі топіки та знайти їх значення). Суть цих топіків в тому, що кожен користувач і кожен фільм тепер характеризуються набором ознак, а скалярний добуток цих векторів — це і є оцінка фільму конкретного користувача. Навчальна вибірка для цього алгоритму задається у вигляді таблиці userID -> productID -> rating. Після чого робиться навчання моделі з допомогою ALS (який, також як і інші алгоритми, приймає на вхід безліч параметрів, прочитати про яких пропонується читачеві самостійно):

from pyspark.mllib.recommendation import ALS
model = ALS.train (ratings, 20, 60)
predictions = model.predictAll(ratings.map (lambda x: (x[0],x[1])))

Висновок
Отже, ми коротко розглянули бібліотеку MlLib з фреймворку Apache Spark, який розроблявся для розподіленої обробки великих даних. Нагадаємо, що основною перевагою даного інструменту, як обговорювалося раніше, є те, що дані можна кешувати в оперативній пам'яті, що дозволяє істотно прискорювати обчислення у разі итеративных алгоритмів, якими і є більшість алгоритмів машинного навчання.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.