Практические руководства, Начало работы

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

Что, почему и как настраивать гиперпараметры

Настройка гиперпараметров - важная часть разработки модели машинного обучения.

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

Перво-наперво.

Что такое гиперпараметры? - Что

Параметр или гиперпараметр

  • Параметры оцениваются на основе набора данных. Они являются частью уравнения модели. Уравнение ниже представляет собой модель логистической регрессии. Тета - это вектор, содержащий параметры модели.

  • Гиперпараметры устанавливаются вручную, чтобы помочь в оценке параметров модели. Они не являются частью окончательного уравнения модели.

Примеры гиперпараметров в логистической регрессии

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

Нужно напомнить о градиентном спуске? Прочтите эту абсолютную вводную статью о линейной регрессии и градиентном спуске.



2. Параметр регуляризации (λ). Параметр регуляризации (λ) является константой в члене «штрафа», добавляемом к функции стоимости. Добавление этого штрафа к функции стоимости называется регуляризацией. Есть два типа регуляризации - L1 и L2. Они различаются уравнением для штрафа.

В линейной регрессии функция стоимости - это просто сумма квадратов ошибок. Добавляем член регуляризации L2, и он становится:

В логистической регрессии функция стоимости - это функция двоичной перекрестной энтропии или логарифмической потери. Добавляем член регуляризации L2, и он становится:

Что делает регуляризация?

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

Как вы относитесь к настройке гиперпараметров? - Как

Теперь, когда мы знаем, ЧТО настраивать, давайте поговорим о процессе их настройки.

Есть несколько стратегий настройки гиперпараметров. Два из них - это поиск по сетке и случайный поиск.

Поиск по сетке

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

Псевдокод будет выглядеть примерно так:

penalty = ['none, 'l1', 'l2']
lambda = [0.001, 0.1, 1, 5, 10]
alpha = [0.001, 0.01, 0.1]
hyperparameters = [penalty, lambda, alpha]
# grid_values is a list of all possible combinations of penalty, lambda, and alpha
grid_values = list(itertools.product(*hyperparameters))
scores = []
for combination in grid_values:
   # create a logistic regression classifier
   classifier = MyLogisticRegression(penalty=combination[0], ...)
   # train the model with training data
   classifier.fit(X_train, y_train)
   # score the model with test data
   score = classifier.score(X_test, y_test)
   scores.append([ combination, score])
# Use scores to determine which combination had the best score
print(scores)

(На самом деле, мы бы оценили несколько типов «баллов», таких как точность, балл F1 и т. Д., Я рассмотрю их в следующем разделе.)

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

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

Давайте займемся машинным обучением!

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

В этом посте мы продолжим тенденцию к прогнозированию вероятности выживания на основе характеристик пассажиров.



Действительно ли Джек умер бы на борту« Титаника ?
Как машинное обучение отвечает на вопрос todatascience.com»



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

  1. Отбросьте столбцы, которые могут оказаться бесполезными, например «Имя».
  2. Отбросьте строки (всего 2) с пропущенным значением для «Начать».
  3. Введите недостающие значения возраста (всего 177) с предположением. В этом случае предположение основывается на «Parch» - количестве родителей и детей на борту.
  4. Преобразуйте категориальные переменные с помощью быстрого кодирования.

Вы также можете найти код для этих шагов обработки данных вместе с более подробным объяснением в моем Jupyter Notebook.

После обработки данных это мой последний DataFrame.

Затем разделите данные на обучающий набор и набор тестов для обучения и оценки модели.

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

Почему важна настройка гиперпараметров? - Почему

Как вы вскоре увидите, настройка гиперпараметров влияет на точность модели и оценку F1. Не знаете, что означают эти показатели? См. Их определения в моей предыдущей статье о Титанике.

Эффект регуляризации

Я использовал классификатор LogisticRegression SciKit-Learn, чтобы сопоставить и протестировать мои данные. Есть много решателей на выбор, у каждого решателя есть свой алгоритм сходимости. В иллюстративных целях я выбрал решающую программу сага. Это единственный решатель, который поддерживает L1, L2 и не поддерживает регуляризацию.

Примечание: для LogisticRegression Scikit-Learn вместо параметра регуляризации λ классификатор принимает букву «C», которая является обратной величине силы регуляризации. Думайте об этом как об 1 / λ.

Я использовал SciKit-Learn GridSearchCV, чтобы получить оценку модели для каждой комбинации penalty = ["none", "l1", "l2"] и C = [0.05, 0.1, 0.5, 1, 5].

from sklearn.model_selection import GridSearchCV
clf = LogisticRegression(solver='saga', max_iter=5000, random_state=0)
param_grid = { 'penalty': ['none', 'l1', 'l2'], 'C': [0.05, 0.1, 0.5, 1, 5] }
grid_search = GridSearchCV(clf, param_grid=param_grid)
grid_search.fit(X, y)
result = grid_search.cv_results_

GridSearchCV выполняет внутреннюю 5-кратную перекрестную проверку. Среднее значение модели для каждой комбинации составляет:

L2-регуляризация с C, равным 0,1, показала наилучшие результаты!

Примечание №1: Я также реализовал алгоритм случайного поиска с помощью SciKit-Learn RandomizedSearchCV. Если вам интересно, вы можете найти пример в моем Блокноте Jupyter.

Дополнительное примечание №2: Я уверен, вы заметили, что ни одна регуляризация не работает лучше, чем L1, и во многих случаях нет разницы между отсутствием регуляризации и L2. Лучшее объяснение, которое у меня есть, это то, что LogisticRegression SciKit Learn уже может хорошо работать без регуляризации. Тем не менее, регуляризация принесла некоторые улучшения.

Позже мы увидим, что регуляризация действительно играет большую роль в SGDClassifier.

Затем я провел параллельное сравнение нескольких показателей производительности без регуляризации и с регуляризацией L2.

tuned = LogisticRegression(solver='saga', penalty='l2', C=0.1, max_iter=5000, random_state=2)
not_tuned = LogisticRegression(solver='saga', penalty='none', max_iter=5000, random_state=2)
tuned.fit(X_train, y_train)
not_tuned.fit(X_train, y_train)
y_pred_tuned = tuned.predict(X_test)
y_pred_not_tuned = not_tuned.predict(X_test)
data = {
    'accuracy': [accuracy_score(y_test, y_pred_tuned), accuracy_score(y_test, y_pred_not_tuned)],
    'precision': [precision_score(y_test, y_pred_tuned), precision_score(y_test, y_pred_not_tuned)],
    'recall': [recall_score(y_test, y_pred_tuned), recall_score(y_test, y_pred_not_tuned)],
    'f1 score': [f1_score(y_test, y_pred_tuned), f1_score(y_test, y_pred_not_tuned)]
}
pd.DataFrame.from_dict(data, orient='index', columns=['tuned', 'not tuned'])

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

Влияние скорости обучения (и регуляризации)

Чтобы увидеть, как разные скорости обучения могут повлиять на производительность модели, я использовал SGDClassifier SciKit Learn (классификатор стохастического градиентного спуска). Это позволяет мне настраивать скорость обучения, тогда как классификатор LogisticRegression - нет.

Есть три параметра SGDClassifier, которые мы можем настроить: alpha, learning_rate и eta0. Терминология немного сбивает с толку, так что терпите меня.

learning_rate - это тип скорости обучения («оптимальная» или «постоянная»).

eta0 - это скорость обучения алгоритма, когда learning_rate является «постоянным». Обычно я называю eta0 альфа.

alpha - это константа, которая умножает член регуляризации. Он также используется для расчета скорости обучения, когда learning_rate является «оптимальным». alpha служит цели, которую обычно называют лямбда.

Таким образом, есть несколько способов установить скорость обучения в SGDClassifier. Если вам нужна постоянная скорость обучения, установите learning_rate='constant' и eta0=the_learning_rate_you_want. Если вам нужна динамическая скорость обучения (которая зависит от того, на каком шаге вы находитесь), установите learning_rate='optimal'. В случае «оптимального» eta0 не используется, а alpha служит двойной цели: силы регуляризации и константы при вычислении скорости динамического обучения на каждом шаге.

Ниже приведен алгоритм поиска по сетке для поиска лучших гиперпараметров (для постоянной скорости обучения). Я использую «постоянную» скорость обучения и устанавливаю максимальное количество итераций на 50 000.

from sklearn.linear_model import SGDClassifier
import matplotlib.pyplot as plt
sgd = SGDClassifier(loss="log", penalty="l2", max_iter=50000, random_state=100)
param_grid = {
  'eta0': [0.00001, 0.0001, 0.001, 0.01, 0.1, 1],
  'learning_rate': ['constant'],
  'alpha': [0.00001, 0.0001, 0.001, 0.01, 0.1, 1]
}
grid_search = GridSearchCV(sgd, param_grid=param_grid)
grid_search.fit(X, y)
result = grid_search.cv_results_

Поисковик дал alpha (здесь это означает силу регуляризации) 0,1 и eta0 (скорость обучения) 0,0001 как лучшие параметры с оценкой 0,7176.

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

Точность довольно низкая для скорости обучения 0,00001. Вероятно, это происходит из-за слишком медленной сходимости алгоритма во время градиентного спуска; после 50000 итераций мы и близко не достигли минимума. Точность также низкая при высокой скорости обучения (0,1 и 1). Вероятно, это связано с перерегулированием. Ниже представлен более масштабный график со всеми альфами.

Сила регуляризации (альфа) также играет роль в точности. Для любой заданной скорости обучения (eta0) существует большое распределение точности в зависимости от значения альфа.

Скорость обучения и регуляризация - это всего лишь два гиперпараметра в моделях машинного обучения. У каждого алгоритма машинного обучения есть свой набор гиперпараметров. Вопросов? Комментарии? Ответьте ниже.