Комментарии (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%+ — переобучение
Чеклист подбора коэффициентов
- Выбрать метод (Grid > Random > Bayesian > Optuna)
- Определить диапазоны (логика, а не случайность)
- Настроить cross-validation (5 или 10 folds)
- Запустить поиск с n_jobs=-1 (параллель)
- Проверить результаты на тесте
- При необходимости уточнить диапазон и повторить