[Python, Программирование, Машинное обучение] Подбор гиперпараметров ML-модели с помощью HYPEROPT
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В машинном обучении гиперпараметрами называют параметры модели, значения которых устанавливаются перед запуском процесса её обучения. Ими могут быть, как параметры самого алгоритма, например, глубина дерева в random forest, число соседей в knn, веса нейронов в нейронный сетях, так и способы обработки признаков, пропусков и т.д. Они используются для управления процессом обучения, поэтому подбор оптимальных гиперпараметров – очень важный этап в построении ML-моделей, позволяющий повысить точность, а также бороться с переобучением. На сегодняшний день существуют несколько популярных подходов к решению задачи подбора, например:1. Поиск по решётке. В этом способе значения гиперпараметров задаются вручную, затем выполняется их полный перебор. Популярной реализацией этого метода является Grid Search из sklearn. Несмотря на свою простоту этот метод имеет и серьёзные недостатки:Очень медленный т.к. надо перебрать все комбинации всех параметров. Притом перебор будет продолжаться даже при заведомо неудачных комбинациях.Часто в целях экономии времени приходится укрупнять шаг перебора, что может привести к тому, что оптимальное значение параметра не будет найдено. Например, если задан диапазон значений от 100 до 1000 с шагом 100 (примером такого параметра может быть количество деревьев в случайном лесе, или градиентном бустинге), а оптимум находится около 550, то GridSearch его не найдёт.2. Случайный поиск. Здесь параметры берутся случайным образом из выборки с указанным распределением. В sklearn он этот метод реализован как Randomized Search. В большинстве случаев он быстрее GridSearch, к тому же значения параметров не ограничены сеткой. Однако, даже это не всегда позволяет найти оптимум и не защищает от перебора заведомо неудачных комбинаций.3. Байесовская оптимизация. Здесь значения гиперпараметров в текущей итерации выбираются с учётом результатов на предыдущем шаге. Основная идея алгоритма заключается в следующем – на каждой итерации подбора находится компромисс между исследованием регионов с самыми удачными из найденных комбинаций гиперпараметров и исследованием регионов с большой неопределённостью (где могут находиться ещё более удачные комбинации). Это позволяет во многих случаях найти лучшие значения параметров модели за меньшее количество времени.В этой статье приведён обзор hyperopt – популярной python-библиотеки для подбора гиперпарметров. В ней реализовано 3 алгоритма оптимизации: классический Random Search, метод байесовской оптимизации Tree of Parzen Estimators (TPE), и Simulated Annealing – ещё одна версия Random Search. Hyperopt может работать с разными типами гиперпараметров –непрерывными, дискретными, категориальными и т.д, что является важным преимуществом этой библиотеки.Установить hyperopt очень просто:
pip install hyperopt
Оценим работу этой библиотеки в реальной задаче – предсказать, зарабатывает ли человек больше $50 тыс. Это может быть полезно, например, в кредитном скоринге. Загрузим необходимые библиотеки, и подготовим данные на вход модели:
from functools import partial
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from hyperopt import hp, fmin, tpe, Trials, STATUS_OK
# загружаем данные
df = pd.read_csv('adult.data.csv')
# удаляем дубликаты
df.drop_duplicates(inplace=True, ignore_index=True)
# готовим признаки и целевую переменную
X = df.drop(labels=['salary', 'native-country'], axis=1).copy()
y = df['salary'].map({'<=50K':0,'>50K':1}).values
В данных есть признаки разных типов, которые, соответственно, требуют и разной обработки. Для этого воспользуемся методом ColumnTransformer из библиотеки sklearn, который позволяет задать свой способ обработки для каждой группы признаков. Для категориальных признаков (тип object) будем использовать методы SimpleImputer (заменяет пропуски, которые обозначены символом «?») и OneHotEncoder (выполняет dummy-кодирование). Числовые признаки (остальные типы) будем масштабировать с помощью StandardScaler. В качестве модели выберем логистическую регрессию.
# выбираем категориальные (тип object)
# и численные признаки (остальные типы)
num_columns = np.where(X.dtypes != 'object')[0]
cat_columns = np.where(X.dtypes == 'object')[0]
# пайплайн для категориальных признаков
cat_pipe = Pipeline([('imputer', SimpleImputer(missing_values='?',
strategy='most_frequent')),
('ohe', OneHotEncoder(sparse=False,
handle_unknown='ignore'))])
# пайплайн для численных признаков
num_pipe = Pipeline([('scaler', StandardScaler())])
# соединяем пайплайны вместе
transformer = ColumnTransformer(
transformers=[('cat', cat_pipe, cat_columns),
('num', num_pipe, num_columns)],
remainder='passthrough')
# итоговая модель
model = Pipeline([('transformer', transformer),
('lr', LogisticRegression(random_state=1, n_jobs=-1,
solver='liblinear'))])
Сформируем пространство поиска параметров для hyperopt:
search_space = {
'lr__penalty' : hp.choice(label='penalty',
options=['l1', 'l2']),
'lr__C' : hp.loguniform(label='C',
low=-4*np.log(10),
high=2*np.log(10))
}
Здесь параметр регуляризации C выбирается из лог-равномерного распределения [- 4ln10, 2ln10], и может принимать значения [10-4, 102], а тип регуляризации равновероятно выбирается из [l1, l2]. Можно выбрать и другие типы распределений, например, равномерное, или нормальное.Зададим функцию, которую будем оптимизировать. Она принимает на вход гиперпараметры, модель и данные, после чего возвращает точность на кросс-валидации:
def objective(params, pipeline, X_train, y_train):
"""
Кросс-валидация с текущими гиперпараметрами
:params: гиперпараметры
:pipeline: модель
:X_train: матрица признаков
:y_train: вектор меток объектов
:return: средняя точность на кросс-валидации
"""
# задаём модели требуемые параметры
pipeline.set_params(**params)
# задаём параметры кросс-валидации (стратифицированная 4-фолдовая с перемешиванием)
skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=1)
# проводим кросс-валидацию
score = cross_val_score(estimator=pipeline, X=X_train, y=y_train,
scoring='roc_auc', cv=skf, n_jobs=-1)
# возвращаем результаты, которые записываются в Trials()
return {'loss': score.mean(), 'params': params, 'status': STATUS_OK}
Укажем объект для сохранения истории поиска (Trials). Это очень удобно, т.к. можно сохранять, а также прерывать и затем продолжать процесс поиска гиперпараметров. И, наконец, запускаем сам процесс подбора с помощью функции fmin. Укажем в качестве алгоритма поиска tpe.suggest – байесовскую оптимизацию. Для Random Search нужно указать tpe.rand.suggest.
# запускаем hyperopt
trials = Trials()
best = fmin(
# функция для оптимизации
fn=partial(objective, pipeline=model, X_train=X, y_train=y),
# пространство поиска гиперпараметров
space=search_space,
# алгоритм поиска
algo=tpe.suggest,
# число итераций
# (можно ещё указать и время поиска)
max_evals=40,
# куда сохранять историю поиска
trials=trials,
# random state
rstate=np.random.RandomState(1),
# progressbar
show_progressbar=True
)
Выведем результаты в pandas DataFrame с помощью специальной функции и визуализируем:
def df_results(hp_results):
"""
Отображаем результаты hyperopt в формате DataFrame
:hp_results: результаты hyperop
:return: pandas DataFrame
"""
results = pd.DataFrame([{**x, **x['params']} for x in hp_results])
results.drop(labels=['status', 'params'], axis=1, inplace=True)
results.sort_values(by=['loss'], ascending=False, inplace=True)
return results
results = df_results(trials.results)
sns.set_context("talk")
plt.figure(figsize=(8, 8))
ax = sns.scatterplot(x='lr__C', y='loss', hue='lr__penalty',
data=results);
ax.set_xscale('log')
ax.set_xlim(1e-4, 2e2)
ax.grid()
На графике видно, что Hyperopt почти не исследовал районы, где получались низкие значения roc auc, а сосредоточился на районе с наибольшими значениями этой метрики.Таким образом, hyperopt – мощный инструмент для настройки модели, которым легко и удобно пользоваться. Дополнительные материалы можно найти врепозитории (для нескольких моделей), а также в 1, 2, 3, 4.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] 5 подходов к стилизации React-компонентов на примере одного приложения
- [Python, PostgreSQL, SQL, Data Mining, Data Engineering] Повторяем когортный анализ. Комплексный подход — Python, SQL, Power BI
- [Информационная безопасность, PHP, Программирование] Защита от уязвимости Dependency Confusion в PHP с помощью Composer (перевод)
- [Анализ и проектирование систем] Очень краткое введение в SysML или «а куда кобылу запрягать?»
- [Алгоритмы, Машинное обучение, Искусственный интеллект, DIY или Сделай сам] Приложение BrowZen отслеживает состояние пользователей по лицам при просмотре сайтов
- [Python, ERP-системы, Big Data] Выгрузка данных из SAP через RFC на Python
- [Python, Искусственный интеллект] Искусственные нейронные сети. Часть 2
- [JavaScript, Программирование, Учебный процесс в IT] Мои рассуждения на тему Как учиться программировать на JavaScript
- [Информационная безопасность] Security Week 07: конфуз с зависимостями в софте
- [Математика, Машинное обучение, Будущее здесь] Ученые создали машину для изобретения математики
Теги для поиска: #_python, #_programmirovanie (Программирование), #_mashinnoe_obuchenie (Машинное обучение), #_hyperopt, #_ml, #_mlmodel (ml-модель), #_grid_search, #_sklearn, #_python, #_programmirovanie (
Программирование
), #_mashinnoe_obuchenie (
Машинное обучение
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:37
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В машинном обучении гиперпараметрами называют параметры модели, значения которых устанавливаются перед запуском процесса её обучения. Ими могут быть, как параметры самого алгоритма, например, глубина дерева в random forest, число соседей в knn, веса нейронов в нейронный сетях, так и способы обработки признаков, пропусков и т.д. Они используются для управления процессом обучения, поэтому подбор оптимальных гиперпараметров – очень важный этап в построении ML-моделей, позволяющий повысить точность, а также бороться с переобучением. На сегодняшний день существуют несколько популярных подходов к решению задачи подбора, например:1. Поиск по решётке. В этом способе значения гиперпараметров задаются вручную, затем выполняется их полный перебор. Популярной реализацией этого метода является Grid Search из sklearn. Несмотря на свою простоту этот метод имеет и серьёзные недостатки:Очень медленный т.к. надо перебрать все комбинации всех параметров. Притом перебор будет продолжаться даже при заведомо неудачных комбинациях.Часто в целях экономии времени приходится укрупнять шаг перебора, что может привести к тому, что оптимальное значение параметра не будет найдено. Например, если задан диапазон значений от 100 до 1000 с шагом 100 (примером такого параметра может быть количество деревьев в случайном лесе, или градиентном бустинге), а оптимум находится около 550, то GridSearch его не найдёт.2. Случайный поиск. Здесь параметры берутся случайным образом из выборки с указанным распределением. В sklearn он этот метод реализован как Randomized Search. В большинстве случаев он быстрее GridSearch, к тому же значения параметров не ограничены сеткой. Однако, даже это не всегда позволяет найти оптимум и не защищает от перебора заведомо неудачных комбинаций.3. Байесовская оптимизация. Здесь значения гиперпараметров в текущей итерации выбираются с учётом результатов на предыдущем шаге. Основная идея алгоритма заключается в следующем – на каждой итерации подбора находится компромисс между исследованием регионов с самыми удачными из найденных комбинаций гиперпараметров и исследованием регионов с большой неопределённостью (где могут находиться ещё более удачные комбинации). Это позволяет во многих случаях найти лучшие значения параметров модели за меньшее количество времени.В этой статье приведён обзор hyperopt – популярной python-библиотеки для подбора гиперпарметров. В ней реализовано 3 алгоритма оптимизации: классический Random Search, метод байесовской оптимизации Tree of Parzen Estimators (TPE), и Simulated Annealing – ещё одна версия Random Search. Hyperopt может работать с разными типами гиперпараметров –непрерывными, дискретными, категориальными и т.д, что является важным преимуществом этой библиотеки.Установить hyperopt очень просто: pip install hyperopt
from functools import partial
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns from sklearn.model_selection import cross_val_score, StratifiedKFold from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.compose import ColumnTransformer from hyperopt import hp, fmin, tpe, Trials, STATUS_OK # загружаем данные df = pd.read_csv('adult.data.csv') # удаляем дубликаты df.drop_duplicates(inplace=True, ignore_index=True) # готовим признаки и целевую переменную X = df.drop(labels=['salary', 'native-country'], axis=1).copy() y = df['salary'].map({'<=50K':0,'>50K':1}).values # выбираем категориальные (тип object)
# и численные признаки (остальные типы) num_columns = np.where(X.dtypes != 'object')[0] cat_columns = np.where(X.dtypes == 'object')[0] # пайплайн для категориальных признаков cat_pipe = Pipeline([('imputer', SimpleImputer(missing_values='?', strategy='most_frequent')), ('ohe', OneHotEncoder(sparse=False, handle_unknown='ignore'))]) # пайплайн для численных признаков num_pipe = Pipeline([('scaler', StandardScaler())]) # соединяем пайплайны вместе transformer = ColumnTransformer( transformers=[('cat', cat_pipe, cat_columns), ('num', num_pipe, num_columns)], remainder='passthrough') # итоговая модель model = Pipeline([('transformer', transformer), ('lr', LogisticRegression(random_state=1, n_jobs=-1, solver='liblinear'))]) search_space = {
'lr__penalty' : hp.choice(label='penalty', options=['l1', 'l2']), 'lr__C' : hp.loguniform(label='C', low=-4*np.log(10), high=2*np.log(10)) } def objective(params, pipeline, X_train, y_train):
""" Кросс-валидация с текущими гиперпараметрами :params: гиперпараметры :pipeline: модель :X_train: матрица признаков :y_train: вектор меток объектов :return: средняя точность на кросс-валидации """ # задаём модели требуемые параметры pipeline.set_params(**params) # задаём параметры кросс-валидации (стратифицированная 4-фолдовая с перемешиванием) skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=1) # проводим кросс-валидацию score = cross_val_score(estimator=pipeline, X=X_train, y=y_train, scoring='roc_auc', cv=skf, n_jobs=-1) # возвращаем результаты, которые записываются в Trials() return {'loss': score.mean(), 'params': params, 'status': STATUS_OK} # запускаем hyperopt
trials = Trials() best = fmin( # функция для оптимизации fn=partial(objective, pipeline=model, X_train=X, y_train=y), # пространство поиска гиперпараметров space=search_space, # алгоритм поиска algo=tpe.suggest, # число итераций # (можно ещё указать и время поиска) max_evals=40, # куда сохранять историю поиска trials=trials, # random state rstate=np.random.RandomState(1), # progressbar show_progressbar=True ) def df_results(hp_results):
""" Отображаем результаты hyperopt в формате DataFrame :hp_results: результаты hyperop :return: pandas DataFrame """ results = pd.DataFrame([{**x, **x['params']} for x in hp_results]) results.drop(labels=['status', 'params'], axis=1, inplace=True) results.sort_values(by=['loss'], ascending=False, inplace=True) return results results = df_results(trials.results) sns.set_context("talk") plt.figure(figsize=(8, 8)) ax = sns.scatterplot(x='lr__C', y='loss', hue='lr__penalty', data=results); ax.set_xscale('log') ax.set_xlim(1e-4, 2e2) ax.grid() На графике видно, что Hyperopt почти не исследовал районы, где получались низкие значения roc auc, а сосредоточился на районе с наибольшими значениями этой метрики.Таким образом, hyperopt – мощный инструмент для настройки модели, которым легко и удобно пользоваться. Дополнительные материалы можно найти врепозитории (для нескольких моделей), а также в 1, 2, 3, 4. =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_mashinnoe_obuchenie ( Машинное обучение ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:37
Часовой пояс: UTC + 5