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

Как подбирать коэффициенты?

1.0 Junior🔥 171 комментариев
#Машинное обучение

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

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

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

Как подбирать коэффициенты в машинном обучении

Подбор коэффициентов (hyperparameter tuning) — это поиск оптимальных значений параметров модели. Это один из наиболее важных этапов, так как правильные коэффициенты могут улучшить качество на 10-20%.

Какие коэффициенты нужно подбирать

Для Ridge/Lasso регрессии:

  • alpha — сила регуляризации (0.001 до 1000)

Для деревьев (Decision Tree, Random Forest):

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

Для SVM:

  • C — сила штрафа за ошибки
  • kernel — тип ядра (linear, rbf, poly)
  • gamma — ширина гауссовского ядра

Для градиентного бустинга (XGBoost, LightGBM):

  • learning_rate (eta) — скорость обучения (0.01-0.5)
  • n_estimators — количество деревьев (100-1000)
  • max_depth — глубина деревьев (3-10)
  • subsample — доля примеров на каждое дерево
  • colsample_bytree — доля признаков на дерево

Метод 1: Grid Search (Сеточный поиск)

Перебираем все комбинации из заданного набора значений.

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# Определяем сетку коэффициентов
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, 15, None],
    'min_samples_leaf': [1, 2, 5, 10],
    'max_features': ['sqrt', 'log2']
}

model = RandomForestClassifier(random_state=42)

# Grid Search перебирает ВСЕ комбинации
grid_search = GridSearchCV(
    estimator=model,
    param_grid=param_grid,
    cv=5,  # 5-fold cross-validation
    scoring='accuracy',
    n_jobs=-1,  # Параллельно
    verbose=1
)

grid_search.fit(X_train, y_train)

# Лучшие коэффициенты
print(f"Best params: {grid_search.best_params_}")
print(f"Best CV score: {grid_search.best_score_:.4f}")

# Используем лучшую модель
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
print(f"Test accuracy: {accuracy_score(y_test, y_pred):.4f}")

# Матрица результатов
results_df = pd.DataFrame(grid_search.cv_results_)
print(results_df[['param_n_estimators', 'param_max_depth', 'mean_test_score']])

Плюсы:

  • Гарантирует найти лучшую комбинацию в заданной сетке
  • Просто реализовать

Минусы:

  • Экспоненциально медленно (3 x 4 x 4 x 2 = 96 моделей)
  • Дискретный поиск (может пропустить оптимум между значениями)

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

Случайно выбираем комбинации из распределения коэффициентов.

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

# Распределения вместо дискретных значений
param_dist = {
    'n_estimators': stats.randint(50, 500),
    'max_depth': [5, 10, 15, 20, None],
    'min_samples_leaf': stats.randint(1, 20),
    'max_features': ['sqrt', 'log2'],
    'learning_rate': stats.uniform(0.01, 0.1)
}

model = RandomForestClassifier(random_state=42)

random_search = RandomizedSearchCV(
    estimator=model,
    param_distributions=param_dist,
    n_iter=50,  # Проверим 50 случайных комбинаций
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    random_state=42
)

random_search.fit(X_train, y_train)

print(f"Best params: {random_search.best_params_}")
print(f"Best CV score: {random_search.best_score_:.4f}")

Плюсы:

  • Быстрее grid search
  • Может найти коэффициенты "между значениями"
  • Хорошо работает при большом количестве параметров

Минусы:

  • Случайность (разные запуски дают разные результаты)
  • Может пропустить оптимум

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

Эффективный метод, который строит модель зависимости score от коэффициентов.

from skopt import BayesSearchCV
from sklearn.ensemble import RandomForestClassifier

# Пространство поиска
search_space = {
    'n_estimators': (50, 500),
    'max_depth': (5, 50),
    'min_samples_leaf': (1, 20),
    'max_features': ['sqrt', 'log2']
}

model = RandomForestClassifier(random_state=42)

bayes_search = BayesSearchCV(
    estimator=model,
    search_spaces=search_space,
    n_iter=30,  # 30 итераций
    cv=5,
    n_jobs=-1,
    random_state=42
)

bayes_search.fit(X_train, y_train)

print(f"Best params: {bayes_search.best_params_}")
print(f"Best CV score: {bayes_search.best_score_:.4f}")

Плюсы:

  • Очень эффективен (нужно меньше итераций)
  • Адаптивно выбирает следующие точки для проверки
  • Работает с непрерывными параметрами

Минусы:

  • Сложнее в реализации
  • Требует scikit-optimize

Метод 4: Optuna (Modern Bayesian Optimization)

import optuna
from optuna.integration.sklearn import OptunaSearchCV
from sklearn.ensemble import RandomForestClassifier

def objective(trial):
    params = {
        'n_estimators': trial.suggest_int('n_estimators', 50, 500),
        'max_depth': trial.suggest_int('max_depth', 5, 50),
        'min_samples_leaf': trial.suggest_int('min_samples_leaf', 1, 20),
        'max_features': trial.suggest_categorical('max_features', ['sqrt', 'log2'])
    }
    
    model = RandomForestClassifier(**params, random_state=42)
    
    # Cross-validation
    scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')
    return scores.mean()

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)

print(f"Best params: {study.best_params}")
print(f"Best score: {study.best_value:.4f}")

Плюсы:

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

Практический пример: XGBoost

import xgboost as xgb
from sklearn.model_selection import GridSearchCV

# Подбираем в несколько этапов (итеративный подход)

# Этап 1: Найти хорошую скорость обучения
param_grid_1 = {
    'learning_rate': [0.01, 0.05, 0.1, 0.2],
    'n_estimators': [100]
}

model = xgb.XGBClassifier(random_state=42)
grid_1 = GridSearchCV(model, param_grid_1, cv=5, n_jobs=-1)
grid_1.fit(X_train, y_train)
print(f"Best learning_rate: {grid_1.best_params_['learning_rate']}")

# Этап 2: Глубина и количество деревьев
best_lr = grid_1.best_params_['learning_rate']
param_grid_2 = {
    'max_depth': [3, 5, 7, 9],
    'n_estimators': [200, 300, 400]
}

model = xgb.XGBClassifier(
    learning_rate=best_lr,
    random_state=42
)
grid_2 = GridSearchCV(model, param_grid_2, cv=5, n_jobs=-1)
grid_2.fit(X_train, y_train)
print(f"Best max_depth: {grid_2.best_params_['max_depth']}")
print(f"Best n_estimators: {grid_2.best_params_['n_estimators']}")

# Этап 3: Регуляризация
best_depth = grid_2.best_params_['max_depth']
best_n = grid_2.best_params_['n_estimators']

param_grid_3 = {
    'subsample': [0.6, 0.8, 1.0],
    'colsample_bytree': [0.6, 0.8, 1.0],
    'reg_alpha': [0, 0.1, 1],
    'reg_lambda': [0, 0.1, 1]
}

model = xgb.XGBClassifier(
    learning_rate=best_lr,
    max_depth=best_depth,
    n_estimators=best_n,
    random_state=42
)
grid_3 = GridSearchCV(model, param_grid_3, cv=5, n_jobs=-1)
grid_3.fit(X_train, y_train)

print(f"\nFinal best params:")
print(grid_3.best_params_)
print(f"Final CV score: {grid_3.best_score_:.4f}")

Важные принципы

1. Cross-validation обязателен

GridSearchCV(model, param_grid, cv=5)  # Всегда используем CV

2. Разумные диапазоны

# Плохо
param_grid = {'learning_rate': [0.00001, 1000]}

# Хорошо
param_grid = {'learning_rate': [0.01, 0.05, 0.1, 0.2]}

3. Остановитесь на 80-90% оптимума

# Обычно последние итерации дают минимальный прирост
# Тратить 1 неделю на +0.1% качества — неэффективно

4. Валидация на тесте обязательна

best_model = grid_search.best_estimator_
test_score = best_model.score(X_test, y_test)
print(f"Test score: {test_score:.4f}")
# Если CV score > test score на 5%+ — переобучение

Чеклист подбора коэффициентов

  1. Выбрать метод (Grid > Random > Bayesian > Optuna)
  2. Определить диапазоны (логика, а не случайность)
  3. Настроить cross-validation (5 или 10 folds)
  4. Запустить поиск с n_jobs=-1 (параллель)
  5. Проверить результаты на тесте
  6. При необходимости уточнить диапазон и повторить