Искусственный интеллект стало проще с H2O.ai

Полное руководство по моделированию с H2O.ai и AutoML в Python

Авторы: Ишаан Дей и Элиз Ли

Если вы чем-то похожи на моего отца, вы проработали в ИТ десятилетиями, но лишь косвенно коснулись науки о данных. Теперь ваш новый C-something-O хочет, чтобы вы создали команду по анализу данных и работали с новым набором модных словечек, о которых вы только смутно слышали на конференциях. Или, возможно, вы - разработчик в быстро развивающемся стартапе и потратили недели на доработку алгоритма, но столкнулись с проблемами, связанными с развертыванием модели в вашем веб-приложении для использования в реальном времени. В обоих случаях H2O.ai определенно является решением, на которое стоит обратить внимание.

Почему именно H2O.ai?

H2O.ai позиционирует себя как программный пакет, который оптимизирует процесс машинного обучения с помощью пакета с открытым исходным кодом H2O и AutoML. В то время как такие продукты, как H2O Driverless AI, позволяют конечным пользователям полностью автоматизировать процесс без единой строчки кода, большинство пользователей (например, я) хотят иметь хотя бы некоторую степень настраиваемости при разработке своей модели.

H2O.ai здесь сияет по нескольким причинам:

  • Он упрощает процесс разработки до интуитивно понятного рабочего процесса,
  • Поезда моделируют быстрее, чем популярные пакеты, такие как sci-kit learn и
  • Упрощает перенос модели в производство с помощью объектов Java.

Короче говоря, H2O, безусловно, предоставляет быструю и доступную платформу машинного обучения для больших наборов данных, которая оснащена удобными и высокопроизводительными инструментами.

Обзор

  • Начиная
  • Построение автономной модели
  • Поиск лучшей модели с помощью AutoML
  • Развертывание модели

Хорошая новость заключается в том, что большая часть H2O в Python похожа на то, что вы, возможно, знакомы с использованием функций обучения sci-kit. Структуры данных H2O в значительной степени аналогичны Pandas, и рабочий процесс для определения, подбора и оценки моделей аналогичен. Используя набор данных финансового кредита из репозитория UCI, мы будем использовать H2O.ai для прогнозирования вероятности того, что человек не выполнит свой следующий платеж.

Примечание. Если вас интересует только часть AutoML, пропустите "Создание Hello, World!" Раздел «Модель», в котором подробно рассказывается о разработке отдельной модели. Вы можете вернуться туда и использовать его в качестве справочного руководства, а также ссылки на документацию по H2O.

Вы можете следить за ними, используя фрагменты кода в публикации или интерактивную записную книжку Python, указанную ниже.

GitHub: https://github.com/elyselee/H2O-Walkthrough/blob/master/H2O%20Walkthrough.ipynb

Начало работы с H2O Python

Настройка зависимостей

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

Для начала перейдите по ссылке H2O stable здесь и загрузите zip-файл, содержащий самую последнюю версию. Следуйте приведенным ниже командам, чтобы завершить установку пакета.

cd ~/Downloads
unzip h2o-3.25.0.4698.zip
cd h2o-3.25.0.4698
java -jar h2o.jar

На момент написания этой статьи (июнь 2019 г.) H2O поддерживает только среду выполнения Java SE версий 8–11. Вы можете проверить свою версию с помощью команды java -version. Если у вас есть Java SDK 12, вам придется удалить Java SDK 11 и перейти на более раннюю версию, чтобы поддерживать совместимость с H2O. Для этого выполните следующую команду: /usr/libexec/java_home -V в терминале. Скопируйте возвращаемый путь и используйте следующую команду для удаления: sudo rm -rf pathname. Перейдите на сайт загрузки Oracle JDK 11, создайте учетную запись и следуйте инструкциям по установке.

Теперь, когда у вас установлены необходимые пакеты, откройте свой скрипт Python и выполните приведенный ниже код. Параметр nthreads просто контролирует количество ядер, на которых будут выполняться операции, а -1 выделяет максимальное количество ядер, доступных для H2O.

import h2o
h2o.init(nthreads = -1, max_mem_size = 8)
h2o.connect()

Предварительная обработка данных

Если вы занимаетесь наукой о данных на Python, используйте Pandas DataFrames. Если вы пишете алгоритмы с нуля и используете массивы NumPy, прекрасно. Но если вы на мгновение подумаете, что H2OFrames - это то, чему стоит научиться, я сэкономлю вам много времени и проблем: это не так.

Честно говоря, одна из причин, почему H2O работает намного быстрее, чем модели научного обучения, - это более эффективные структуры данных, которые H2O предоставляет по сравнению с Pandas. Однако для разработки функций мы рекомендуем использовать обычные DataFrames, а затем преобразовывать их в H2OFrame, как только вы будете готовы к импорту. Поскольку это, в конце концов, руководство по H2O, наши методы обработки будут выполняться с использованием H2OFrames. У H2O также есть отличное справочное руководство по манипулированию данными.

Для начала импортируем набор данных кредитной карты UCI с помощью функции h2o.import_file() .

df = h2o.import_file(‘uci_creditheader.csv’)

Многие функции для H2OFrames аналогичны функциям Pandas DataFrame. Например, мы можем исследовать столбцы с помощью атрибута .columns, который возвращает список имен функций (а не массив NumPy). Мы можем удалить ненужные функции с помощью функции drop() (спецификация оси не требуется).

df = df.drop(‘ID’)
df.columns

В приведенном ниже коде мы создадим список имен столбцов функций x и имен целевых переменных y. Такое форматирование позволяет нам передавать меньше структур данных в функции обучения и прогнозирования (sklearn запрашивает X_train и y_train), что значительно улучшает время выполнения.

y = ‘default payment next month’
x = list(df.columns).remove(y)

Пока мы обсуждаем эту тему, важно отметить, что H2O автоматически принимает регрессионную или классификационную модель в зависимости от типа данных переменной y. Быстрая проверка с использованием атрибута df[y].type показывает нам, что наши значения являются целыми числами (1 для дефолта по кредиту, 0 в противном случае). Затем мы можем преобразовать этот столбец в факторный тип с помощью функции as_factor().

df[y] = df[y].as_factor()

Чтобы создать наборы для обучения и тестирования, мы будем использовать функцию H2O split_frame() вместо функции sklearn train_test_split(). Для этого нам нужно передать список дробей для размеров обучающего и проверочного набора (размер набора для тестирования вычисляется неявно). Функция возвращает список, в котором первый элемент относится к обучающему набору, второй соответствует набору проверки, а третий элемент является набором тестов.

splits = df.split_frame(ratios=[0.7, 0.15], seed=1)
train = splits[0]
valid = splits[1]
test = splits[2]

Мы также можем проверить размер каждого набора с помощью атрибута .nrow. Обратите внимание, что каждый из этих наборов содержит как функции переменной X, так и цель y, которая отличается от нашего процесса, если бы мы делали это в sklearn.

print(train.nrow)
print(valid.nrow)
print(test.nrow)

Создание модели "Hello, World!"

Конструкция модели

Мы классифицируем нашу модель, используя случайную оценку лесов, и вы снова заметите сходство с научным набором знаний. Используя функцию H2ORandomForestEstimator(), мы создаем экземпляр модели, который будем использовать для классификации (или регрессии, если у нас была целочисленная или плавающая переменная ответа).

from h2o.estimators.random_forest import H2ORandomForestEstimator
rf = H2ORandomForestEstimator(seed=1)
  • seed: этот параметр, как и random_state в других модулях, просто контролирует случайные числа, используемые при создании модели. Это важно для воспроизводимости во время проверки модели с внешними наборами данных.
  • Можно указать некоторые другие параметры, специфичные для каждой модели, например ntrees или min_split_improvement. Чтобы узнать, что это за алгоритм модели по вашему выбору, ознакомьтесь с документацией по H2O.

Подгонка и прогнозирование результатов

Чтобы подогнать нашу модель к данным, нам нужно передать как минимум три параметра: training_frame, y столбец и x столбцы. Однако, если параметр x оставить пустым, h2o при подгонке предполагает использовать все столбцы, кроме столбца y. Ниже приведены некоторые другие параметры, которые вы можете использовать в данных, не включенных в приведенный ниже фрагмент. Опять же, полный список можно найти в документации здесь.

rf.train(x=x, y=y, training_frame=train)
  • nfolds: количество складок, используемых для перекрестной проверки. Для получения дополнительной информации ознакомьтесь с объяснением H2O перекрестной проверки.
  • balance_classes: Когда у нас есть дисбаланс классов в нашей целевой функции, мы можем захотеть пересчитать наши данные либо путем передискретизации класса меньшинства, либо заниженной выборки класса большинства при создании нового распределения. Если мы установим для этого параметра значение True, мы также можем указать параметр class_sampling_factors и передать список соотношений для определения результирующего распределения.
  • ignored_columns: Если у нас есть столбцы, которые мы не хотим включать при подгонке, но которые могут быть полезны для сравнения прогнозируемых значений, таких как идентификатор наблюдения, мы можем указать это с помощью этого параметра.
  • categorical_encoding: В то время как в sklearn мы обрабатывали категориальные переменные с отдельными функциями на этапе предварительной обработки, H2O может обрабатывать каждый столбец с помощью таких методов, как одно горячее кодирование или кодирование меток. Небольшое примечание: чтобы пометить столбцы, которые необходимо обрабатывать как категориальные, заранее используйте функцию .as_factor(), чтобы изменить тип данных в наборах для обучения и тестирования. Полный список опций для categorical_encoding можно найти здесь.

Прогнозы

Возврат прогнозируемых вероятностей для каждого класса довольно тривиален и может быть выполнен с помощью функции predict().

y_hat = rf.predict(test_data=test)

При дальнейшем изучении y_hat мы видим, что predict() возвратил три столбца для каждого наблюдения: p0, вероятность принадлежности наблюдения к классу 0; p1, вероятность принадлежности наблюдения к классу 1; и predict, прогнозируемая классификационная метка. Здесь граница принятия решения (порог) для классификационной метки была принята равной 0,5, поэтому любое значение p1 выше 0,5 будет соответствовать метке predict, равной 1.

Оценка эффективности

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

Чтобы получить отчет о том, насколько хорошо работает наша модель, мы можем использовать функцию model_performance() и вывести результат на консоль.

rf_performance = rf.model_performance(test)
print(rf_performance)

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

ModelMetricsBinomial: drf
** Reported on train data. **
MSE: 0.14036700152537882
RMSE: 0.3746558441094691
LogLoss: 0.45587629761245807
Mean Per-Class Error: 0.30286812164834764
AUC: 0.7576361236577988
pr_auc: 0.5240926163909475
Gini: 0.5152722473155975

Мы также получаем матрицу путаницы с фактическими метками по вертикальной оси и прогнозируемыми метками по горизонтали. Примечание. Значения матрицы неточностей сообщаются на пороге (пороге вероятности), который максимизирует оценку F1, в отличие от 0,5. Наши выходные данные здесь идентифицируют это как 0,312.

Что замечательно в выводе H2O, так это то, что он автоматически вычисляет каждую метрику для каждого порогового значения, а затем сообщает о максимальной метрике value, а также threshold, при которой она была достигнута. Опять же, если используемый здесь словарь ничего не значит для вас, я бы очень рекомендовал прочитать эту статью, объясняющую показатели оценки.

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

Кроме того, мы можем возвращать определенные метрики, вызывая метрическую функцию для объекта H2OModelMetrics. Чтобы увидеть полный список метрик, которые можно вызвать, нажмите tab после ввода имени объекта H2OModelMetrics и выберите вариант из раскрывающегося списка (а затем добавьте (), чтобы вернуть интересующую метрику).

rf_performance.auc()
rf_performance.confusion_matrix()

Справочные ссылки:

Руководство по показателям: https://towardsdatascience.com/hackcvilleds-4636c6c1ba53

Краткие шпаргалки для других типов моделей:

Глубокое обучение (DL): искусственная нейронная сеть, состоящая из многоуровневых нейронов, каждый последующий слой модели улучшается по сравнению с предыдущим за счет агрегирования. Чтобы узнать больше о том, как это работает, ознакомьтесь с нашей статьей о глубоком обучении.

  • epochs: количество потоков для передачи набора данных.
  • L1: Добавляет регуляризацию L1 для улучшения обобщения и стабильности, устанавливая многие значения веса равными 0
  • L2: Добавляет регуляризацию L2 для улучшения обобщения и стабильности за счет снижения многих значений веса.
  • adaptive_rate: ручная настройка скорости обучения включена по умолчанию
  • loss: укажите функцию потерь с параметрами: Automatic (по умолчанию), Absolute, Quadratic, Huber и CrossEntropy

Распределенный случайный лес (DRF): DRF создает лес регрессионных или классификационных деревьев с набором данных.

  • ntrees: количество деревьев
  • max_depth: Максимальная глубина дерева
  • sample_rate: частота выборки строки от 0 до 1 (по умолчанию 1)
  • col_sample_rate_per_tree: Частота дискретизации столбца на дерево от 0 до 1

Обобщенная линейная модель (GLM): линейная регрессия с гибким обобщением для обработки нелинейности.

  • Solver: используемый алгоритм решателя: auto, l_bfgs, irlsm, coordinate_descent, coordinate_descent_naive, gradient_descent_lh или gradient_descent_sqerr.
  • Lambda: Сила регуляризации
  • Alpha: Распределение регуляризации между L1 и L2

Gradient Boosting Machine (GBM): использует ансамбль (набор моделей) слабых деревьев решений путем последовательного уточнения.

  • ntrees: Количество деревьев в ансамбле.
  • learn_rate: Скорость обучения в диапазоне от 0 до 1
  • sample_rate: частота выборки строки от 0 до 1 (по умолчанию 1)
  • col_sample_rate: частота выборки столбца в диапазоне от 0 до 1.

Наивный байесовский классификатор: алгоритм классификации с сильными предположениями о независимости признаков, основанный на применении теоремы Байеса.

  • max_hit_ratio_k: Максимальное число прогнозов для вычисления коэффициента попадания
  • min_prob: минимальная вероятность, которая будет использоваться для наблюдений.
  • eps_prob: порог ниже вероятности быть замененным на min_prob

Справочные ссылки:

Документация по оценке модели: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science.html#supervised

Документация по параметрам: http://h2o-release.s3.amazonaws.com/h2o-dev/rel-shackleford/5/docs-website/h2o-py/docs/h2o.html

AutoML: простая оптимизация

Как вы, наверное, уже заметили, выбор наилучшей модели прогнозирования может оказаться сложной задачей и потребовать много времени. Вам нужно будет выбрать не только лучшую модель, но и лучшие параметры, которые максимизируют производительность этой модели. Традиционно мы делали это с помощью Grid Search для настройки гиперпараметров, но H2O также автоматизирует весь процесс для нескольких моделей.

Автоматическое машинное обучение (AutoML) автоматизирует процесс выбора лучшей модели путем обучения широкого набора моделей, позволяя тем, у кого нет опыта в данной области, создавать высокопроизводительные модели, а также традиционные методы. Подумайте о конвейерах научного обучения, просто больше и лучше.

В настоящее время AutoML в H2O версии 3.16 поддерживает следующие модели: случайный лес, чрезвычайно рандомизированный лес, случайную сетку глубоких нейронных сетей, случайную сетку машин с градиентным усилением (GBM), фиксированную сетку обобщенной линейной модели (GLM). ), а затем обучает составной ансамбль моделей.

Создание оценщика AutoML

Мы начинаем с импорта функции H2O AutoML и подгонки ее к обучающему набору, передавая столбцы x и y так же, как мы делали с предыдущими моделями.

from h2o.automl import H2OAutoML
aml = H2OAutoML(max_models=5, max_runtime_secs=300, seed=1)
aml.train(x=x, y=y, training_frame=train)
  • max_models: этот параметр определяет максимальное количество моделей для построения, не включая составные ансамблевые модели.
  • max_runtime_secs: это максимальное время выполнения AutoML в секундах перед обучением моделей.

Оценка эффективности

Мы можем увидеть лучшие модели и их производительность по различным показателям, вызвав атрибут leaderboard и сохранив результат в H2OFrame lb, который затем можно просмотреть с помощью функции head().

lb = aml.leaderboard
lb.head(rows=lb.nrows)

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

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

y_hat = aml.leader.predict(test) 
aml.leader.auc()
aml.leader.confusion_matrix()

Документация AutoML: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/automl.html#

Переход в производство

Одним из самых больших преимуществ H2O является то, что все полностью обученные модели могут храниться в виде объектов, которые можно легко развернуть в других средах Java для оценки в реальном времени.

Для этого H2O может преобразовать модели в M odel O b j ect O ptimized (MOJO). MOJO не имеют ограничений по размеру, в отличие от обычных старых объектов Java (POJO), и быстрее и меньше занимают дисковое пространство, чем POJO. В качестве выходных данных создается файл H2O-genmodel.jar, который представляет собой библиотеку для поддержки скоринга, содержащую необходимые считыватели и интерпретаторы. Этот файл также необходим при развертывании моделей MOJO в производстве.

Приведенный ниже код загружает mojo и файл h20-genmodel.jar по указанному пользователем пути.

model.download_mojo(path='pathname', get_genmodel_jar=True)

Для получения дополнительной информации о том, как получить доступ к модели в производстве, см. Документацию по H2O ниже.

Производственная документация: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/productionizing.html#

Мысли на прощание

К настоящему времени вы знакомы с основами API H2O в python и, получив немного дополнительной помощи от StackOverflow и документации, должны иметь возможность запускать H2O на Python, создавать и обучать модели, оценивать его производительность, и, возможно, даже изучить развертывание.

В ходе этого процесса я обнаружил, что ресурсы документации H2O были доступны по сравнению с другими источниками. Не сбрасывайте со счетов StackOverflow, но и не ожидайте найти там ответы на все свои вопросы.

Сообщите нам, если у вас возникнут какие-либо вопросы, и мы будем рады предоставить дополнительные ресурсы, когда вы начнете работать с AutoML и H2O.ai.