← Назад к вопросам

Как выбрать гиперпараметры модели?

2.0 Middle🔥 241 комментариев
#Python#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как выбрать гиперпараметры модели?

Выбор гиперпараметров (hyperparameter tuning) — это одна из самых критических задач в machine learning. Неправильный выбор может привести к переобучению, недообучению или просто к субоптимальному качеству модели. Давайте разберём все методы и лучшие практики.

Основные типы гиперпараметров

Для модели линейной регрессии с регуляризацией:

  • Коэффициент регуляризации (alpha, lambda): контролирует силу штрафа
  • Тип регуляризации: L1 (Lasso), L2 (Ridge), ElasticNet

Для Random Forest:

  • n_estimators: количество деревьев
  • max_depth: максимальная глубина дерева
  • min_samples_split: минимум samples для разделения узла
  • min_samples_leaf: минимум samples в листе

Для нейронных сетей:

  • learning_rate: скорость обучения
  • batch_size: размер батча
  • number of layers: количество слоёв
  • units per layer: количество нейронов в слое

Метод 1: Grid Search (Сетка параметров)

Grid Search — это исчерпывающий поиск по предопределённой сетке значений.

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# Загрузка данных
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Определяем сетку параметров
param_grid = {
    'n_estimators': [10, 50, 100, 200],
    'max_depth': [None, 5, 10, 15],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# GridSearchCV
grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,  # 5-fold cross-validation
    n_jobs=-1,  # используй все ядра
    verbose=1
)

grid_search.fit(X_train, y_train)

print(f"Лучшие параметры: {grid_search.best_params_}")
print(f"Лучшая точность (CV): {grid_search.best_score_:.4f}")
print(f"Точность на тестовом наборе: {grid_search.score(X_test, y_test):.4f}")

# Доступ к результатам
results_df = pd.DataFrame(grid_search.cv_results_)
print(results_df[['param_n_estimators', 'param_max_depth', 'mean_test_score']].head(10))

Преимущества:

  • Гарантированно найдёт лучшие параметры из сетки
  • Легко использовать
  • Хорошо распараллеливается

Недостатки:

  • Экспоненциальный рост вычислений с количеством параметров
  • Неэффективен для непрерывных параметров
  • С 4 параметрами по 5 значений = 625 моделей!

Метод 2: Random Search (Случайный поиск)

Random Search — случайная выборка из параметров.

from sklearn.model_selection import RandomizedSearchCV
import scipy.stats as stats

# Распределения для параметров
param_distributions = {
    'n_estimators': stats.randint(10, 200),
    'max_depth': [None, 5, 10, 15, 20, 30],
    'min_samples_split': stats.randint(2, 20),
    'min_samples_leaf': stats.randint(1, 10),
    'max_features': ['sqrt', 'log2']
}

# RandomizedSearchCV
random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_distributions,
    n_iter=50,  # только 50 комбинаций вместо 625
    cv=5,
    n_jobs=-1,
    random_state=42
)

random_search.fit(X_train, y_train)

print(f"Лучшие параметры: {random_search.best_params_}")
print(f"Лучшая точность (CV): {random_search.best_score_:.4f}")

Преимущества:

  • Много быстрее GridSearch
  • Хорошо исследует пространство параметров
  • Может быть столь же эффективен при правильном количестве итераций

Недостатки:

  • Не гарантирует нахождение оптимума
  • Требует больше итераций для гарантии качества

Метод 3: Bayesian Optimization (Оптимизация Байеса)

Bayesian Optimization — использует вероятностную модель для умного выбора параметров.

from skopt import BayesSearchCV
from skopt.space import Integer, Categorical
from sklearn.ensemble import RandomForestClassifier

# Определяем пространство поиска
search_spaces = {
    'n_estimators': Integer(10, 200),
    'max_depth': Integer(5, 30),
    'min_samples_split': Integer(2, 20),
    'min_samples_leaf': Integer(1, 10),
    'max_features': Categorical(['sqrt', 'log2', None])
}

# BayesSearchCV
bayes_search = BayesSearchCV(
    RandomForestClassifier(random_state=42),
    search_spaces,
    n_iter=20,  # намного меньше итераций нужно
    cv=5,
    n_jobs=-1,
    random_state=42,
    verbose=1
)

bayes_search.fit(X_train, y_train)

print(f"Лучшие параметры: {bayes_search.best_params_}")
print(f"Лучшая точность: {bayes_search.best_score_:.4f}")

Преимущества:

  • Очень эффективен: требует намного меньше итераций
  • Использует информацию из предыдущих итераций
  • Может работать с непрерывными параметрами

Недостатки:

  • Сложнее в использовании
  • Требует установки дополнительных библиотек (scikit-optimize)

Метод 4: Optuna (Современный подход)

Optuna — фреймворк для гиперпараметрической оптимизации с поддержкой pruning.

import optuna
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

def objective(trial):
    # Определяем параметры
    n_estimators = trial.suggest_int('n_estimators', 10, 200)
    max_depth = trial.suggest_int('max_depth', 5, 30)
    min_samples_split = trial.suggest_int('min_samples_split', 2, 20)
    min_samples_leaf = trial.suggest_int('min_samples_leaf', 1, 10)
    max_features = trial.suggest_categorical('max_features', ['sqrt', 'log2'])
    
    # Создаём модель
    clf = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        min_samples_split=min_samples_split,
        min_samples_leaf=min_samples_leaf,
        max_features=max_features,
        random_state=42
    )
    
    # Вычисляем кросс-валидацию
    scores = cross_val_score(clf, X_train, y_train, cv=5, scoring='accuracy')
    
    return scores.mean()

# Создаём study
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)

print(f"Лучшие параметры: {study.best_params}")
print(f"Лучшая точность: {study.best_value:.4f}")

# Визуализация
optuna.visualization.plot_optimization_history(study).show()

Преимущества:

  • Очень гибкий и мощный
  • Поддерживает pruning (отсекает плохие ветки)
  • Хорошо документирован
  • Простой API

Лучшие практики выбора гиперпараметров

1. Стратегия поиска

# Стратегия 1: Грубый поиск -> Тонкий поиск
# Сначала GridSearch с широким диапазоном
coarse_params = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 15, 30]
}

# Потом RandomSearch в узком диапазоне
fine_params = {
    'n_estimators': stats.randint(80, 150),
    'max_depth': stats.randint(10, 20)
}

2. Кросс-валидация

# Используй StratifiedKFold для несбалансированных классов
from sklearn.model_selection import StratifiedKFold

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# Или TimeSeriesSplit для временных рядов
from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5)

3. Масштабирование параметров

# Логарифмическое масштабирование для некоторых параметров
from sklearn.model_selection import GridSearchCV
import numpy as np

param_grid = {
    'C': np.logspace(-4, 4, 20),  # от 10^-4 до 10^4
    'gamma': np.logspace(-3, 3, 20)
}

4. Ранняя остановка для итеративных моделей

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import learning_curve

# Gradient Boosting с validation_fraction и n_iter_no_change
gb = GradientBoostingClassifier(
    n_estimators=500,
    learning_rate=0.1,
    validation_fraction=0.2,
    n_iter_no_change=10,  # ранняя остановка
    tol=1e-4,
    random_state=42
)

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

МетодСкоростьКачествоСложность
Grid SearchМедленноХорошоНизкая
Random SearchБыстроХорошоНизкая
Bayesian OptimizationОчень быстроОтличноСредняя
OptunaОчень быстроОтличноСредняя
Halving Grid SearchБыстроОтличноСредняя

Итоговая рекомендация

  1. Для быстрого прототипирования: Random Search (50-100 итераций)
  2. Для production моделей: Optuna или Bayesian Optimization (20-50 итераций)
  3. Для маленьких пространств параметров: Grid Search
  4. Для больших моделей (LightGBM, XGBoost): Optuna с pruning
# Практический шаблон
from optuna import create_study
from optuna.pruners import MedianPruner
from optuna.samplers import TPESampler

study = create_study(
    direction='maximize',
    sampler=TPESampler(seed=42),
    pruner=MedianPruner()
)

study.optimize(objective, n_trials=50, n_jobs=-1)
best_model = train_final_model(study.best_params)

Вывод: выбор метода зависит от размера пространства параметров и доступных вычислительных ресурсов. Для большинства случаев рекомендуется Optuna или Bayesian Optimization как оптимальный баланс скорости и качества.