Машинное обучение, способность учиться на данных, было одним из самых успешных и разрушительных вариантов использования больших данных. В сфере данных и аналитики у каждого есть доступ к бесчисленному набору инструментов для решения задач машинного обучения различной природы и сложности.

Однако, когда кто-то работает с данными в масштабе, обычно традиционные библиотеки машинного обучения на таких языках, как R и Python (например, pandas, scikit-learn), не работают, поскольку они изначально работают на одной машине, где данные для анализа должен умещаться в памяти (хотя существуют подходы, такие как внеплановое обучение, которые позволяют обойти это, но у него есть свой собственный набор предостережений). Таким образом, для масштабного масштабного машинного обучения решающее значение приобретают распределенные конвейеры обучения и вывода. Само по себе это нетривиальная задача, но наличие фреймворков и библиотек значительно облегчает этот процесс. Такие библиотеки, как Mahout (работающая на старом-добром MapReduce) и SparkMLLIB (библиотека машинного обучения Spark на основе RDD) были среди первых игроков в этой категории, и с тех пор мы стали свидетелями появления многих других подобных. Эта тенденция изменилась по нескольким направлениям:

1. Зрелость библиотеки машинного обучения Spark (SparkML), которая теперь поддерживает универсальный API Dataframe / Dataset и обеспечивает покрытие для ряда алгоритмов и преобразований функций.
2. Доступность библиотек, которые без проблем работают со Spark, например Sparkling Water, DeepLearning4J, XgBoost4J, Stanford Core NLP Wrapper для Spark с учетом беспрецедентного роста Spark как ведущей среды распределенных вычислений
3. Интеграция и совместимость библиотек глубокого обучения, таких как TensorFlow, с другими средами распределенных вычислений, такими как Apache Beam (например, TensorFlow Transform и хорошо поддерживается в Google Cloud Platform)
4. Доступность встроенных в облако фреймворков и библиотек машинного обучения, например SageMaker от AWS

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

Использование kmeans в SparkML и SageMaker

Недавно у меня появилась возможность использовать как SparkML, так и AWS SageMaker в постановке задач машинного обучения без учителя, где основной целью был анализ огромных объемов данных для выполнения кластеризации. Учитывая характер проблемы машинного обучения, подходящим было сочтено kmeans (один из широко используемых алгоритмов кластеризации на основе секционирования).

И SparkML, и SageMaker предоставляют алгоритм kmeans, и опыт использования обоих был совершенно разным, с рядом оговорок, поэтому этот пост посвящен именно этому. Если вы намереваетесь использовать алгоритм kmeans (или, возможно, любой другой алгоритм), и вам нужно принять дизайнерское решение между SparkML и AWS SageMaker, этот пост потенциально поможет вам и в этом контексте.

Расстояние от центроидов Метрика:

Учитывая, что кластеризация - это, в основном, неконтролируемое машинное обучение, когда истинные метки обучающих экземпляров заранее недоступны, основной вывод, который можно извлечь из применения алгоритмов кластеризации, - это связь меток кластера с обучающими экземплярами, то есть обучающие экземпляры сгруппированы. в кластеры, где эвристика заключается в том, что экземпляры в кластере похожи друг на друга, чем экземпляры, находящиеся в разных кластерах. И SparkML, и SageMaker kmeans предоставляют метки кластера при запуске алгоритма kmeans. Однако одно поразительное различие - это расстояние от центроида, то есть насколько далеко конкретный экземпляр находится от центра кластера. Это понимание может быть весьма полезным для выявления сплоченности, а также потенциальных выбросов.
SageMaker в этом контексте удобно предоставляет расстояние от центроида для каждого обучающего экземпляра в дополнение к метке кластера.

Это сокращает количество этапов предварительной обработки, чтобы значительно связать выходы с входами.
Однако в случае SparkML он не предоставляется в качестве выходных данных для каждого обучающего экземпляра. Скорее, он предоставляется как атрибут модели. Например, для данных радужной оболочки глаза, если вы выполнили кластеризацию с использованием 4 функций и для k = 3, тогда центры кластеров (или центроиды), доступные как атрибут обученной модели, будут массивом размера 3 (эквивалентно количеству кластеров), где каждый element будет массивом из 4-х чисел с плавающей запятой (соответствующих 4-м координатам в 4-мерном пространстве признаков).

Затем это требует дополнительных шагов предварительной обработки, чтобы связать выходы с входами.

Определение оптимального количества кластеров:

kmeans требует, чтобы количество кластеров (заданное как k) было предоставлено до запуска алгоритма. Хотя знание предметной области для рассматриваемой проблемы обычно помогает определить, каким должно быть количество кластеров, мы, специалисты по данным, применяем подходы, основанные на данных, для определения правильного значения k. В этом контексте используются такие методы, как изгиб локтя и силуэт. Мы использовали метод кривой изгиба для определения оптимального числа k, который включает многократное выполнение алгоритма kmeans для набора данных с разными значениями k и определение степени соответствия на основе оценочной метрики. Spark ML использует внутри установленную сумму квадратов ошибок (WSSSE). Для каждого значения k используется этот показатель, который затем наносится на график. Исходя из этого, точка, в которой происходит изгиб на кривой (статистически говоря, где градиент становится меньше), обычно является правильным значением k. Интуитивно это означает, что дальнейшее увеличение значения k не приводит к значительному уменьшению показателя.

Использовать метод кривой изгиба в SparkML довольно просто, так как нужно указать диапазон и просто обучить модель этим значениям. Тот же кластер, на котором работает Spark, используется для выполнения нескольких запусков kmeans для разных значений k, и никаких дополнительных накладных расходов не требуется. Мы протестировали это с одним экземпляром r5.12xlarge и примерно 350 тысячами экземпляров и с различным количеством функций (от 4 до 100), и каждый запуск занимал у нас минуту или около того.

from pyspark.ml.clustering import KMeans
import numpy as np
cost = np.zeros(50)
for k in range(3,50):
   kmeans = KMeans().setK(k).setSeed(1).setFeaturesCol("scaled_features")
   model = kmeans.fit(spark_dataframe)
   cost[k] = model.computeCost(spark_dataframe)

а затем его можно построить с помощью matplotlib, если используется Python.

Однако выполнение того же самого в SageMaker связано со своим набором предостережений. Конвейер машинного обучения в SageMaker можно визуально проиллюстрировать следующим образом:

В случае SageMaker экземпляры запускаются для каждого задания обучения или вывода, т.е. если вы хотите запустить модель, например k означает, что с определенным набором гиперпараметров, например k = 10, вам нужно будет запустить задание обучения для того, что запустит экземпляр (или экземпляры, если вы укажете несколько из них). Этот обучающий экземпляр сгенерирует артефакт, называемый «моделью», который будет сохранен в области корзины S3 (настраиваемой). Вы не получите выводов, например, метку кластера, просто выполнив обучающие задания. Скорее результат учебной работы - это модельный артефакт.

Чтобы получить фактические выводы через SageMaker, необходимо запустить задания вывода, которые могут быть в двух формах:
Развертывание конечной точки - выводы получаются путем отправки тестовых данных (или обучающих данных в в случае неконтролируемых алгоритмов) до конечной точки в виде вызова API. SageMaker SDK значительно абстрагирует это. Кроме того, ту же конечную точку можно использовать для получения выводов из экосистемы SageMaker, что особенно полезно, если есть последующие приложения, которые хотят получать выводы в режиме, близком к реальному времени.

Задание пакетного преобразования - если нет такого требования, чтобы конечная точка была подготовлена ​​для облегчения генерации аналитических данных, как описано выше, то можно использовать функцию заданий пакетного преобразования, которая запускает экземпляр, загружает обнаруженные данные обучения на S3 (здесь может быть два режима, то есть File или Pipe. Когда используется режим File, данные загружаются в обучающие экземпляры, тогда как они «передаются в потоке», когда используется режим Pipe, при условии, что алгоритм поддерживает это), выводы генерируются и затем сохраняются обратно на S3 (форматы могут отличаться от CSV, JSON или recordIO в зависимости от используемого алгоритма).

Таким образом, вкратце, использование такого метода, как кривая локтя, потребует обучающих экземпляров, эквивалентных диапазону «k», который вам нужен. Поскольку стоимость связана с запуском каждого экземпляра, поэтому следует быть осторожным. Кроме того, каждый тип экземпляра имеет время запуска (которое может варьироваться от 1 до 7 минут или даже больше), поэтому простое выполнение кривой изгиба также потребует значительного времени в этом аспекте.

Значения по умолчанию для параметров Kmeans:

Значения kmeans по умолчанию в SparkML и SageMaker сильно различаются. Хотя хорошая привычка - тщательно изучить значения по умолчанию и установить их в соответствии с требованиями, но я видел, как люди просто полагаются на значения по умолчанию и запускают алгоритмы. В частности, в случае SparkML kmeans значениями по умолчанию являются:

метрика расстояния: евклидова
метод инициализации: kmeans || (это kmeans ++ - расширенная форма kmeans, которая касается способа инициализации начальных центроидов)
Шаги инициализации: 2

тогда как в SageMaker:
метрика расстояния: msd (среднеквадратичное расстояние)
метод инициализации: случайные
эпохи (эквивалентно шагам инициализации в SparkML): 1

Среди этих различий параметр метода инициализации особенно важен, поскольку использование kmeans ++ дает лучшие результаты по сравнению со случайным подходом.

Кроме того, согласно нашему анализу, состав кластеров, полученных при запуске kmeans через SparkML или SageMaker, был совершенно другим. Так что это следует учитывать, если вы используете эти технологические стеки в своем конвейере.

Короче говоря, оба являются мощными вариантами, если кто-то хочет ускорить масштабное распределенное машинное обучение. SageMaker - это полная экосистема, которая предоставляет ряд других функций, таких как записные книжки, реестр моделей и т. Д., Которые значительно упрощают сквозной процесс; что-то, что потребует индивидуальной реализации, если используется SparkML. Также интересно видеть, как такие производители, как Databricks, запускают платформу MLFlow, которая предоставляет аналогичные возможности, что является еще одним показателем сильной ориентации сообщества на эту нишу.

Если вы заинтересованы в повышении квалификации в этом наборе технологий, обязательно ознакомьтесь с моим самым продаваемым курсом по Spark и моей книгой Программирование на Scala для аналитики больших данных.