Реализация поиска по декартовой и случайной сетке (гиперпараметры) в H2o.ai

Что нужно?

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

  • Случайный лес: no_of_trees, max_depth
  • Машины опорных векторов: gamma, rank_ratio
  • K-означает: k, max_iterations

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

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

Поиск по сетке - это метод оптимизации гиперпараметров, то есть метод, используемый для поиска наиболее оптимального набора гиперпараметров, который приводит к «лучшей» модели. Лучшее может означать разные вещи в зависимости от контекста модели: например, это может означать наиболее точную модель для задач классификации, тогда как для задачи регрессии лучшей может быть модель с наименьшим среднеквадратичным значением.

Поиск по сетке и его виды

поиск по сетке использует грубую силу для обучения модели каждой комбинации значений гиперпараметров. Например, если у вас есть три гиперпараметра H1, H2 и H3, и каждый из них может принимать 20, 30 и 15 значений соответственно, ваша сетка будет содержать в общей сложности 20 * 30 * 15 = 900 моделей.

В этой статье мы обсудим два основных вида поиска по сетке, которые поддерживает H2o: Поиск по декартовой сетке и Поиск по случайной сетке.

  • Поиск по декартовой сетке: метод поиска по сетке в H2o по умолчанию, исчерпывающий поиск по всем возможным комбинациям гиперпараметров. Если пространство для поиска мало, вам следует выбрать этот метод.
  • Поиск по случайной сетке: как следует из названия, случайная комбинация гиперпараметров (равномерно выбранная из набора всех возможных комбинаций значений гиперпараметров) тестируется вместо исчерпывающего тестирования всех возможных комбинаций. Кроме того, также устанавливается критерий остановки, чтобы указать, когда должен быть остановлен случайный поиск. Если у вас большое пространство для поиска, вам следует выбрать этот метод.

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

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

Давайте углубимся в данные

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

Данные уже очищены (я предпочитаю выполнять очистку в R и построение модели в Python) и готовы к использованию. Помимо переменной результата, т. Е. application_outcome, нас интересуют следующие предикторы:

  • age: возраст заявителя.
  • car_type: тип автомобиля, на который оформляется кредит.
  • Сумма кредита: сумма кредита, на которую подана заявка.
  • Депозит: залог, который заявитель готов заплатить
  • Площадь: на основе почтового индекса заявителя.

Поскольку мы будем настраивать гиперпараметры, разумно отделить кадры train, validate и test друг от друга, чтобы избежать случайного утечка данных. Мы используем три фрейма:

  • создать несколько конкурирующих моделей, используя набор train с различными комбинациями гиперпараметров.
  • выберите «лучшую» модель, протестировав фрейм проверки.
  • объективная оценка «лучшей» модели на невидимом тестовом кадре.

Приступим к кодированию

Настройка эталонной модели

Мы начинаем с создания простой модели логистической регрессии без какой-либо настройки гиперпараметров, чтобы мы могли сравнить ее результаты с окончательной моделью, в которой настройка гиперпараметров была достигнута с использованием методов поиска по сетке.

Оценив модель на тестовом наборе, мы получили AUC = 0,76.

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

Поиск по декартовой сетке

  1. Определение пространства поиска
param = { 'alpha': [x * 0.01 for x in range(0,11)]
}

Если вы заметили, мы не указали лямбда в параметрах сетки, потому что h2o имеет встроенную автоматическую настройку, чтобы найти лучшее значение лямбда. Таким образом, мы можем найти оптимальное значение лямбда автоматически, установив lambda_search = True. Поскольку мы хотим указать этот параметр модели не по умолчанию, который не является частью нашей сетки, мы передаем их в сетку с помощью метода H2OGridSearch.train () (см. Ниже)

2. Инициализация экземпляра поиска по сетке

# Import H2O Grid Search: 
from h2o.grid.grid_search import H2OGridSearch
h20_grid = H2OGridSearch(
model = H2OGeneralizedLinearEstimator(family = 'binomial'),
hyper_params = param, 
search_criteria = {'strategy': "Cartesian"},
grid_id = 'glm_grid1'
)

3. Тренировка сетки

h20_grid.train(
x = x,
y = y,
training_frame= train,
validation_frame=validate, 
lambda_search = True # model parameter than we want to prefix! 
)

4. Наконец-то мы получили лучшие гиперпараметры для нашей модели.

h20_grid.get_grid(sort_by='auc', decreasing=True)

Таким образом, у нас есть лучшая модель с AUC = 0,796 при альфа = 0,1, что является незначительным улучшением по сравнению с нашим предыдущим показателем AUC. Но помните, что эти результаты основаны на нашем наборе проверочных тестов. Проверка работоспособности с помощью набора тестов будет выполнена через несколько минут.

Случайный поиск по сетке

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

params = {
   'alpha': [x * 0.01 for x in range(0,99)]
}

Остальные шаги остаются такими же, как и раньше, за исключением небольшого изменения. При определении экземпляра поиска по сетке мы должны теперь явно указать стратегию как «RandomDiscrete». Кроме того, мы также упомянули критерии остановки, согласно которым максимальное количество моделей, которые будут сгенерированы в сетке, будет равно 30.

search_criteria = {'strategy': 'RandomDiscrete',
                  'max_models': 30 # max of 30 models assessed
                  }
# creating the grid of GLM 
h2o_grid2 = H2OGridSearch(
model = H2OGeneralizedLinearEstimator(family = 'binomial'),
hyper_params = params,
search_criteria = search_criteria,
grid_id = 'glm_grid2')

Обучение и оценка производительности этой сетки показывает, что лучшая модель дает AUC = 0,797 с альфа = 0,73.

P.S. На выходе будет 30 моделей. Мы представляем здесь только часть наших результатов.

Сравнение двух методов поиска по сетке

Сохраняем топовые модели из каждой сетки и оцениваем их с помощью протянутой тестовой рамки.

# Assessing the best model obtained from cartesian grid search best_cart_model.model_performance(test).auc()

Мы получили AUC = 0.8030682697458484

# Assessing the best model obtained from random grid search
best_random_model.model_performance(test).auc()

Мы получили AUC = 0.8034591194968553

Мы улучшили нашу первоначальную (не настроенную) модель, используя методы поиска по сетке, и увеличили AUC с 0,76 до 0,80.

Таким образом, нет никакой разницы между значениями AUC при декартовом и случайном поиске по сетке), однако мы получаем более высокое значение альфа при случайном поиске (альфа = 0,78) без потери значения AUC. Поскольку альфа представляет собой скорость обучения (или насколько быстро или медленно модель изучает проблему, т. Е. сходится модель), и мы знаем, что меньшая альфа может привести к более медленному обучению, было бы разумнее выбрать большее значение альфа. (поскольку высокие и низкие значения альфа сходятся в одном решении).

Бонусный раздел

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

Раньше мы просто использовали параметр max_models, чтобы остановить процесс случайного поиска, как только было сгенерировано 30 моделей. Мы также можем остановить поиск в сетке лучших значений гиперпараметров после того, как значение AUC модели не улучшится на 1e-3 (или 0,003) в течение трех раундов оценки.

search_criteria = {
'strategy': 'RandomDiscrete',     
'stopping_metric': 'AUC',     
'stopping_tolerance': 1e-3,     
'stopping_rounds': 3 
}

Ресурсы

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

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

Удачного обучения :)