Что такое Bayesian optimization для подбора гиперпараметров?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Bayesian Optimization для подбора гиперпараметров
Bayesian Optimization — это метод оптимизации, который использует вероятностную модель для умного выбора гиперпараметров модели машинного обучения. Это значительно эффективнее, чем простая сетка перебора (Grid Search) или случайный поиск (Random Search).
Почему нужна Bayesian Optimization
Традиционные подходы к поиску гиперпараметров:
# Grid Search - полный перебор
from sklearn.model_selection import GridSearchCV
param_grid = {
'C': [0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1],
'kernel': ['rbf', 'poly']
}
# Всего 4 * 3 * 2 = 24 комбинации
# Каждая требует полного обучения модели
Проблемы:
- Экспоненциальный рост комбинаций ("проклятие размерности")
- Дорого в вычислительном отношении
- Не использует информацию из предыдущих попыток
- Неэффективен для высокой размерности
Принцип работы Bayesian Optimization
Bayesian Optimization работает в 4 шага:
- Построить модель (surrogate model): вероятностная модель, которая предсказывает качество метрики для произвольного набора гиперпараметров
- Найти лучший кандидат: использовать acquisition function для выбора следующего набора для тестирования
- Оценить кандидата: обучить реальную модель и получить её качество
- Обновить модель: добавить новую точку данных в модель и повторить
Компоненты Bayesian Optimization
1. Surrogate Model (Суррогатная модель)
Обычно используется Gaussian Process (GP) — вероятностная модель, которая предсказывает не только значение, но и неопределённость:
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import Matern, ConstantKernel
# Гауссов процесс с ядром Матерна
kernel = ConstantKernel(1.0) * Matern(nu=2.5)
gp = GaussianProcessRegressor(
kernel=kernel,
alpha=1e-6,
normalize_y=True,
n_restarts_optimizer=10
)
# После обучения GP может предсказать как среднее, так и стандартное отклонение
mean, std = gp.predict(new_params, return_std=True)
2. Acquisition Function (Функция приобретения)
Это стратегия выбора следующего набора для тестирования:
Expected Improvement (EI) — популярный выбор:
import numpy as np
from scipy.stats import norm
def expected_improvement(mean, std, current_best):
"""
mean: предсказанное среднее значение GP
std: предсказанное стандартное отклонение
current_best: лучшее значение, найденное до сих пор
"""
improvement = mean - current_best
Z = improvement / std
ei = improvement * norm.cdf(Z) + std * norm.pdf(Z)
return ei
Другие acquisition функции:
- Upper Confidence Bound (UCB): mean + alpha * std (балансирует исследование и эксплуатацию)
- Probability of Improvement (PI): P(mean > current_best)
- Thompson Sampling: случайная выборка из апостериорного распределения
Практический пример с scikit-optimize
from skopt import gp_minimize
from skopt.space import Real, Integer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
# Определяем пространство поиска
space = [
Integer(10, 200, name='n_estimators'),
Integer(1, 30, name='max_depth'),
Real(0.0, 1.0, name='min_samples_split'),
Real(0.0, 1.0, name='min_samples_leaf')
]
# Функция для минимизации (берём -score, т.к. gp_minimize ищет минимум)
def objective(params):
n_estimators, max_depth, min_samples_split, min_samples_leaf = params
model = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
min_samples_split=min_samples_split,
min_samples_leaf=min_samples_leaf,
random_state=42
)
score = cross_val_score(
model, X_train, y_train,
cv=5,
scoring='accuracy'
).mean()
return -score # Минимизируем минус-скор
# Запускаем Bayesian Optimization
result = gp_minimize(
objective,
space,
n_calls=30, # Кол-во итераций
n_initial_points=5, # Кол-во случайных начальных точек
acq_func='EI', # Acquisition function
random_state=42,
verbose=1
)
print(f"Лучшие параметры: {result.x}")
print(f"Лучший скор: {-result.fun:.4f}")
# Получить лучшие параметры
best_params = {
'n_estimators': result.x[0],
'max_depth': result.x[1],
'min_samples_split': result.x[2],
'min_samples_leaf': result.x[3]
}
model_final = RandomForestClassifier(**best_params)
model_final.fit(X_train, y_train)
Практический пример с Optuna (современный вариант)
import optuna
from optuna.samplers import TPESampler
def objective(trial):
# Trial предлагает гиперпараметры
n_estimators = trial.suggest_int('n_estimators', 10, 200)
max_depth = trial.suggest_int('max_depth', 1, 30)
min_samples_split = trial.suggest_float('min_samples_split', 0, 1)
min_samples_leaf = trial.suggest_float('min_samples_leaf', 0, 1)
model = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
min_samples_split=min_samples_split,
min_samples_leaf=min_samples_leaf,
random_state=42
)
score = cross_val_score(
model, X_train, y_train, cv=5, scoring='accuracy'
).mean()
return score
# Создаём исследование с TPE sampler (Tree-structured Parzen Estimator)
sampler = TPESampler(seed=42)
study = optuna.create_study(
sampler=sampler,
direction='maximize'
)
# Оптимизируем
study.optimize(objective, n_trials=30, show_progress_bar=True)
# Лучший trial
print(f"Лучший скор: {study.best_value:.4f}")
print(f"Лучшие параметры: {study.best_params}")
# Получить историю
df = study.trials_dataframe()
print(df[['number', 'value', 'params_n_estimators', 'params_max_depth']])
Сравнение методов поиска
| Метод | Скорость | Качество | Сложность | Когда использовать |
|---|---|---|---|---|
| Grid Search | Медленно | Хорошее | Простая | Мало параметров, известный диапазон |
| Random Search | Быстро | Среднее | Простая | Когда-то при недостатке вычисловых ресурсов |
| Bayesian Opt | Быстро | Отличное | Средняя | Стандартный выбор для ML |
| Evolutionary Algorithms | Медленно | Отличное | Сложная | Многообъектная оптимизация |
Рекомендации по использованию
-
Используй Bayesian Optimization для:
- Важных моделей, где каждая итерация дорога
- Большого пространства гиперпараметров
- Когда нужно быстро найти хорошие параметры
-
Типичное количество вызовов:
- Простые модели: 20-30 итераций
- Сложные модели: 50-100 итераций
- Очень важные модели: 100-200 итераций
-
Настройка acquisition function:
- EI (Expected Improvement): универсальный выбор
- UCB: когда нужен баланс исследования и эксплуатации
- PI: консервативнее, меньше рисков
-
Определение пространства:
- Используй log-scale для параметров (например, learning_rate)
- Ограничивай диапазон с использованием доменной экспертизы
- Не добавляй ненужные параметры в поиск
Выводы
Bayesian Optimization — это мощный и эффективный метод, который революционизировал подбор гиперпараметров в ML. Это должен быть стандартный выбор для любого серьёзного ML проекта.