Кафедра ШІзики

Налаштування гіперпараметрів - Знаходимо ідеальні налаштування моделі

Кафедра ШІзики

Автор

32 хвилин

Час читання

12.01.2025

Дата публікації

Рівень:
Середній
Теги: #гіперпараметри #grid-search #random-search #крос-валідація #оптимізація

Налаштування гіперпараметрів: Знаходимо ідеальні налаштування моделі

Пастка “Достатньо добре”

Наприкінці Статті 9 Random Forest Марії працював чудово:

  • Training RMSE: 4.2 піци
  • Test RMSE: 9.1 піци
  • Точність на вихідних: 94%

Її племінник був готовий запускати модель у продакшн. Але Марія навчилась бути скептичною.

“Зачекай,” — сказала вона, дивлячись на код. “Чому ти використав 100 дерев? Чому max_depth=10? Чому min_samples_split=5?”

Племінник знизав плечима. “Це… звичайні значення за замовчуванням?”

“Тобто ти кажеш, що ми тижнями збирали дані, чистили їх, створювали ознаки, вивчали ансамблі… щоб просто вгадати фінальні налаштування?”

Він замислився. Вона мала рацію.

“А якщо є комбінація, яка дасть 95% точності? Або 97%? Як би ми взагалі її знайшли?”

Ласкаво просимо до налаштування гіперпараметрів — мистецтва пошуку оптимальних налаштувань моделі. Це різниця між “достатньо добре” та “найкраще можливе”.


🎯 Параметри vs Гіперпараметри

Перш ніж занурюватись у налаштування, давайте прояснимо критичну різницю, яка збиває з пантелику багатьох початківців.

Параметри: Що модель вивчає

Параметри — це значення, які модель вивчає з даних під час навчання:

МодельПараметри (вивчаються)
Лінійна регресіяКоефіцієнти (ваги) та зсув
Дерево рішеньПорогові значення розбиття та значення листків
Нейронна мережаВаги та зміщення

Ви не встановлюєте їх — алгоритм навчання визначає їх сам.

Гіперпараметри: Що встановлюєте ВИ

Гіперпараметри — це налаштування, які ви обираєте ДО навчання:

МодельГіперпараметри (ви обираєте)
Random Forestn_estimators, max_depth, min_samples_split
Gradient Boostinglearning_rate, n_estimators, max_depth
Нейронна мережаШвидкість навчання, розмір батчу, кількість шарів

Уявіть це як випікання:

  • Параметри = Наскільки підніметься тісто (відбувається під час випікання)
  • Гіперпараметри = Температура духовки та час випікання (ви встановлюєте заздалегідь)

Чому гіперпараметри важливі

Племінник Марії провів швидкий експеримент:

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
import numpy as np

# Ті самі дані, різні гіперпараметри
configs = [
    {"n_estimators": 10, "max_depth": 3},
    {"n_estimators": 100, "max_depth": 10},
    {"n_estimators": 100, "max_depth": None},
    {"n_estimators": 500, "max_depth": 15},
]

print("Конфігурація                | CV Score (RMSE)")
print("-" * 50)

for config in configs:
    rf = RandomForestRegressor(**config, random_state=42)
    scores = cross_val_score(rf, X_train, y_train,
                            cv=5, scoring='neg_root_mean_squared_error')
    rmse = -scores.mean()
    print(f"trees={config['n_estimators']:3}, depth={str(config['max_depth']):4} | {rmse:.2f} піц")

Результат:

Конфігурація                | CV Score (RMSE)
--------------------------------------------------
trees= 10, depth=3    | 12.4 піц
trees=100, depth=10   |  9.1 піц
trees=100, depth=None |  8.7 піц
trees=500, depth=15   |  8.2 піц

“Бачиш?” — Марія вказала на екран. “Просто змінивши налаштування, ми перейшли від 12.4 до 8.2 — покращення на 34%! І ми спробували лише 4 комбінації.”


🔍 Проблема простору пошуку

Ось виклик: скільки всього комбінацій?

Для Random Forest лише з цими гіперпараметрами:

  • n_estimators: [50, 100, 200, 500] → 4 варіанти
  • max_depth: [5, 10, 15, 20, None] → 5 варіантів
  • min_samples_split: [2, 5, 10, 20] → 4 варіанти
  • min_samples_leaf: [1, 2, 4] → 3 варіанти

Всього комбінацій: 4 × 5 × 4 × 3 = 240 можливостей

І це ПРОСТА модель! XGBoost має 15+ важливих гіперпараметрів. Нейронні мережі можуть мати сотні.

Це називається прокляттям розмірності у просторі гіперпараметрів.


🎲 Стратегія 1: Grid Search (Грубий перебір)

Найпростіший підхід: спробувати кожну комбінацію.

n_estimators:    [100, 200, 300]
max_depth:       [5, 10, 15]

Grid Search пробує ВСІ 9 комбінацій:
(100,5), (100,10), (100,15),
(200,5), (200,10), (200,15),
(300,5), (300,10), (300,15)

Реалізація

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestRegressor

# Визначаємо сітку параметрів
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [5, 10, 15, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# Створюємо модель
rf = RandomForestRegressor(random_state=42)

# Налаштовуємо Grid Search з 5-fold крос-валідацією
grid_search = GridSearchCV(
    estimator=rf,
    param_grid=param_grid,
    cv=5,                          # 5-fold крос-валідація
    scoring='neg_root_mean_squared_error',
    n_jobs=-1,                     # Використовувати всі ядра CPU
    verbose=2                      # Показувати прогрес
)

# Запускаємо пошук
grid_search.fit(X_train, y_train)

# Результати
print(f"Найкращі параметри: {grid_search.best_params_}")
print(f"Найкращий CV RMSE: {-grid_search.best_score_:.2f} піц")

Результат:

Fitting 5 folds for each of 144 candidates, totalling 720 fits
Найкращі параметри: {'max_depth': 15, 'min_samples_leaf': 2,
                      'min_samples_split': 5, 'n_estimators': 200}
Найкращий CV RMSE: 7.8 піц
ПлюсиМінуси
✅ Вичерпний — не пропустить найкращу комбінацію❌ Обчислювально дорогий
✅ Легко зрозуміти та реалізувати❌ Погано масштабується з більшою кількістю параметрів
✅ Відтворювані результати❌ Витрачає час на погані регіони
✅ Добре працює з малими сітками❌ Не може досліджувати неперервні діапазони

Коли Grid Search має сенс

  • У вас мало гіперпараметрів (2-3)
  • Кожен параметр має мало варіантів (3-5)
  • У вас достатньо обчислювального часу
  • Ви хочете гарантоване покриття

Марія підрахувала: “144 комбінації × 5 фолдів × ~10 секунд кожна = 2 години. Непогано для одноразової оптимізації.”


🎰 Стратегія 2: Random Search (Розумний гравець)

А що, якщо замість перебору всіх комбінацій випадково обирати з простору пошуку?

Несподівана правда

У 2012 році дослідники Бергстра та Бенджіо довели щось контрінтуїтивне:

Random search знаходить хороші гіперпараметри швидше за grid search — особливо коли одні гіперпараметри важливіші за інші.

Чому Random Search працює краще

Уявіть, що ви налаштовуєте два параметри, але важливий лише один:

Grid Search (9 точок):         Random Search (9 точок):
●───●───●                      ●     ●   ●
│   │   │                        ●       ●
●───●───●                      ●   ●
│   │   │                            ●   ●
●───●───●                        ●

Grid: 3 унікальних значення    Random: 9 унікальних значень
для важливого параметра        для важливого параметра!

Grid search витрачає обчислення, тестуючи ті самі значення повторно. Random search досліджує більше простору.

Реалізація

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform

# Визначаємо розподіли параметрів (не просто списки!)
param_distributions = {
    'n_estimators': randint(50, 500),        # Випадкове ціле 50-500
    'max_depth': randint(3, 30),             # Випадкове ціле 3-30
    'min_samples_split': randint(2, 20),     # Випадкове ціле 2-20
    'min_samples_leaf': randint(1, 10),      # Випадкове ціле 1-10
    'max_features': uniform(0.1, 0.9),       # Випадкове дробове 0.1-1.0
}

rf = RandomForestRegressor(random_state=42)

# Random Search зі 100 ітераціями
random_search = RandomizedSearchCV(
    estimator=rf,
    param_distributions=param_distributions,
    n_iter=100,                    # Спробувати 100 випадкових комбінацій
    cv=5,
    scoring='neg_root_mean_squared_error',
    n_jobs=-1,
    random_state=42,
    verbose=1
)

random_search.fit(X_train, y_train)

print(f"Найкращі параметри: {random_search.best_params_}")
print(f"Найкращий CV RMSE: {-random_search.best_score_:.2f} піц")

Результат:

Fitting 5 folds for each of 100 candidates, totalling 500 fits
Найкращі параметри: {'max_depth': 18, 'max_features': 0.42,
                      'min_samples_leaf': 3, 'min_samples_split': 8,
                      'n_estimators': 287}
Найкращий CV RMSE: 7.5 піц

Порівняння Grid vs Random

Марія запустила обидва на своїх даних піцерії:

# Grid Search: 144 комбінації
# Random Search: 100 випадкових вибірок

print(f"{'Метод':<15} {'Комбінацій':>12} {'Час':>10} {'Найкращий RMSE':>15}")
print("-" * 55)
print(f"{'Grid Search':<15} {144:>12} {'2.1 год':>10} {7.8:>13.2f}")
print(f"{'Random Search':<15} {100:>12} {'1.4 год':>10} {7.5:>13.2f}")

“Random search був швидший І знайшов кращі параметри!” — вигукнув племінник.

“Бо він досліджував значення, які ми б ніколи не спробували,” — пояснила Марія. “287 дерев? max_features=0.42? Grid search не може їх знайти.”


🧠 Стратегія 3: Байєсівська оптимізація (Розумний пошук)

А що, якщо замість випадкового вгадування використовувати ПОПЕРЕДНІ результати для керування НАСТУПНОЮ спробою?

Інтуїція

Уявіть, що ви шукаєте найкращий рецепт піци:

Random Search: “Спробуємо 200°C… тепер 120°C… тепер 250°C…”

Байєсівський: “200°C було добре. 180°C було гірше. Оптимум, мабуть, десь 200-210°C. Спробуємо 205°C.”

Байєсівська оптимізація будує модель цільової функції і використовує її для вирішення, де шукати далі.

Як це працює

  1. Почати з кількох випадкових точок
  2. Побудувати модель (зазвичай Гаусівський процес) результатів
  3. Передбачити, який недосліджений регіон найперспективніший
  4. Оцінити цю точку
  5. Оновити модель і повторити

Реалізація з Optuna

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

def objective(trial):
    """Optuna викликатиме цю функцію багато разів з різними параметрами"""

    # Пропонуємо гіперпараметри
    params = {
        'n_estimators': trial.suggest_int('n_estimators', 50, 500),
        'max_depth': trial.suggest_int('max_depth', 3, 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_float('max_features', 0.1, 1.0),
    }

    # Навчаємо та оцінюємо
    rf = RandomForestRegressor(**params, random_state=42, n_jobs=-1)
    scores = cross_val_score(rf, X_train, y_train,
                            cv=5, scoring='neg_root_mean_squared_error')

    return -scores.mean()  # Optuna мінімізує, тому повертаємо додатний RMSE

# Створюємо дослідження та оптимізуємо
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=50, show_progress_bar=True)

print(f"Найкращі параметри: {study.best_params}")
print(f"Найкращий CV RMSE: {study.best_value:.2f} піц")

Результат:

[I 2025-01-12 10:30:00] Trial 0 finished with value: 9.2
[I 2025-01-12 10:30:15] Trial 1 finished with value: 8.8
...
[I 2025-01-12 10:45:00] Trial 49 finished with value: 7.1

Найкращі параметри: {'n_estimators': 312, 'max_depth': 21,
                      'min_samples_split': 6, 'min_samples_leaf': 2,
                      'max_features': 0.58}
Найкращий CV RMSE: 7.1 піц

Порівняння: Всі три методи

results = {
    'Grid Search':        {'trials': 144, 'time': '2.1 год', 'rmse': 7.8},
    'Random Search':      {'trials': 100, 'time': '1.4 год', 'rmse': 7.5},
    'Bayesian (Optuna)':  {'trials': 50,  'time': '0.8 год', 'rmse': 7.1},
}

print(f"{'Метод':<20} {'Спроб':>8} {'Час':>10} {'Найкращий RMSE':>15}")
print("-" * 55)
for method, data in results.items():
    print(f"{method:<20} {data['trials']:>8} {data['time']:>10} {data['rmse']:>13.1f}")

Результат:

Метод                  Спроб        Час   Найкращий RMSE
-------------------------------------------------------
Grid Search              144    2.1 год            7.8
Random Search            100    1.4 год            7.5
Bayesian (Optuna)         50    0.8 год            7.1

“Вдвічі менше спроб, найкращі результати,” — схвально кивнула Марія. “Алгоритм вчився на своїх помилках.”


⚠️ Прихована небезпека: Перенавчання на валідації

Ось пастка, яка ловить навіть досвідчених практиків.

Проблема

Ви запускаєте 500 комбінацій гіперпараметрів. Кожна оцінюється на валідаційних даних. Зрештою ви знаходите налаштування, які добре працюють на валідації… випадково.

Це називається перенавчання на валідаційній вибірці.

Відкриття Марії

# Після інтенсивного налаштування...
best_model = grid_search.best_estimator_

# Валідаційний скор (використовувався під час налаштування)
val_rmse = -grid_search.best_score_
print(f"Validation RMSE: {val_rmse:.2f}")  # 7.1 піц

# СПРАВЖНІЙ тестовий скор (повністю відкладений)
test_pred = best_model.predict(X_test)
test_rmse = np.sqrt(mean_squared_error(y_test, test_pred))
print(f"Test RMSE: {test_rmse:.2f}")       # 8.3 піц 😬

“Зачекай, тестова помилка вища за валідаційну?”

“Ми спробували так багато комбінацій, що деякі виявились вдалими на валідації випадково,” — зрозумів племінник.

Рішення: Вкладена крос-валідація

Золотий стандарт для чесної оцінки:

Зовнішній цикл: Оцінка справжньої продуктивності
├── Fold 1: Навчання на 80%, Тест на 20%
│   └── Внутрішній цикл: Пошук найкращих гіперпараметрів на 80%
│       ├── Inner Fold 1: Навчання на 64%, Валідація на 16%
│       ├── Inner Fold 2: ...
│       └── Вибір найкращих параметрів → Оцінка на зовнішніх 20%
├── Fold 2: Інший поділ 80/20
│   └── Внутрішній цикл: Знову пошук найкращих параметрів
...

Простіша альтернатива: Відкладена тестова вибірка

Якщо вкладена CV занадто повільна:

# Розбиваємо дані на ТРИ частини
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5)

# Використовуємо X_train + X_val для налаштування
# X_test НІКОЛИ не чіпаємо до фінальної оцінки

# Налаштовуємо на train+val
grid_search.fit(X_train, y_train)  # CV використовує X_train внутрішньо

# Фінальна чесна оцінка
final_score = grid_search.best_estimator_.score(X_test, y_test)

🛠️ Практичний робочий процес налаштування

Ось робочий процес, який розробив племінник Марії:

Крок 1: Почніть зі значень за замовчуванням

# Завжди спочатку встановіть базову лінію
baseline = RandomForestRegressor(random_state=42)
baseline_scores = cross_val_score(baseline, X_train, y_train, cv=5,
                                  scoring='neg_root_mean_squared_error')
print(f"Baseline RMSE: {-baseline_scores.mean():.2f}")
# Спочатку закидаємо широку сітку
coarse_params = {
    'n_estimators': randint(50, 500),
    'max_depth': randint(3, 50),
    'min_samples_split': randint(2, 30),
}

coarse_search = RandomizedSearchCV(rf, coarse_params, n_iter=30, cv=3)
coarse_search.fit(X_train, y_train)

# Визначаємо перспективні регіони
print(f"Поки що найкраще: {coarse_search.best_params_}")
# Збільшуємо масштаб на перспективних регіонах
fine_params = {
    'n_estimators': [250, 300, 350],      # Біля найкращого з грубого
    'max_depth': [15, 18, 21, 24],         # Біля найкращого з грубого
    'min_samples_split': [4, 6, 8, 10],    # Біля найкращого з грубого
}

fine_search = GridSearchCV(rf, fine_params, cv=5)
fine_search.fit(X_train, y_train)

Крок 4: Фінальна оцінка

# Чесна оцінка на тестовій вибірці
final_model = fine_search.best_estimator_
test_predictions = final_model.predict(X_test)
test_rmse = np.sqrt(mean_squared_error(y_test, test_predictions))

print(f"Фінальний Test RMSE: {test_rmse:.2f} піц")

📊 Поширені гіперпараметри за алгоритмами

Decision Trees / Random Forests

ГіперпараметрТиповий діапазонЕфект
max_depth3-30 або NoneГлибше = складніше, ризик перенавчання
min_samples_split2-20Вище = більше регуляризації
min_samples_leaf1-10Вище = плавніші передбачення
n_estimators50-500Більше дерев = краще, але повільніше
max_features’sqrt’, ‘log2’, 0.1-1.0Нижче = більше різноманітності

Gradient Boosting (XGBoost/LightGBM)

ГіперпараметрТиповий діапазонЕфект
learning_rate0.01-0.3Нижче = потрібно більше дерев
n_estimators100-1000Більше з нижчим learning rate
max_depth3-10Зазвичай менше ніж у RF
subsample0.5-1.0Частка зразків на дерево
colsample_bytree0.5-1.0Частка ознак на дерево
reg_alpha (L1)0-10Регуляризація розрідженості
reg_lambda (L2)0-10Ridge регуляризація

Нейронні мережі

ГіперпараметрТиповий діапазонЕфект
learning_rate1e-5 до 1e-1Критичний — занадто високий розбігається, занадто низький застряє
batch_size16-256Більший = швидше, але менш стабільно
hidden_layers1-5Більше = більше ємності
neurons_per_layer32-512Ширше = більше ємності
dropout0.1-0.5Регуляризація

🎯 Налаштування XGBoost: Повний приклад

Налаштуймо XGBoost для передбачень піци Марії:

import xgboost as xgb
import optuna

def objective(trial):
    params = {
        'n_estimators': trial.suggest_int('n_estimators', 100, 1000),
        'max_depth': trial.suggest_int('max_depth', 3, 10),
        'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True),
        'subsample': trial.suggest_float('subsample', 0.5, 1.0),
        'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0),
        'reg_alpha': trial.suggest_float('reg_alpha', 1e-8, 10, log=True),
        'reg_lambda': trial.suggest_float('reg_lambda', 1e-8, 10, log=True),
    }

    model = xgb.XGBRegressor(**params, random_state=42, n_jobs=-1)

    scores = cross_val_score(model, X_train, y_train,
                            cv=5, scoring='neg_root_mean_squared_error')

    return -scores.mean()

# Запускаємо оптимізацію
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=100, show_progress_bar=True)

# Навчаємо фінальну модель
best_xgb = xgb.XGBRegressor(**study.best_params, random_state=42)
best_xgb.fit(X_train, y_train)

# Оцінюємо
test_pred = best_xgb.predict(X_test)
print(f"Tuned XGBoost Test RMSE: {np.sqrt(mean_squared_error(y_test, test_pred)):.2f}")

💡 Професійні поради з практики

1. Почніть просто, налаштовуйте потім

# Неправильний підхід:
# "Давайте налаштуємо 20 гіперпараметрів протягом 3 годин"

# Правильний підхід:
# 1. Отримайте базову лінію зі значеннями за замовчуванням
# 2. Перевірте, чи тип моделі підходить
# 3. ПОТІМ налаштовуйте важливі гіперпараметри

2. Використовуйте Early Stopping з Boosting

# Замість налаштування n_estimators...
model = xgb.XGBRegressor(
    n_estimators=10000,  # Встановіть високо
    early_stopping_rounds=50,
    eval_metric='rmse'
)

model.fit(X_train, y_train,
         eval_set=[(X_val, y_val)],
         verbose=False)

print(f"Оптимальна кількість дерев: {model.best_iteration}")

3. Learning Rate та кількість дерев пов’язані

# Ці комбінації часто дають схожі результати:
# - learning_rate=0.3, n_estimators=100
# - learning_rate=0.1, n_estimators=300
# - learning_rate=0.03, n_estimators=1000

# Нижчий learning rate + більше дерев = зазвичай краще, але повільніше

4. Зберігайте результати пошуку

import pandas as pd

# Збережіть результати grid search для аналізу
results_df = pd.DataFrame(grid_search.cv_results_)
results_df.to_csv('hyperparameter_search_results.csv', index=False)

# Ви можете проаналізувати, які параметри важливіші

5. Не налаштовуйте все

Зосередьтесь на параметрах, які найбільше впливають:

АлгоритмНайважливішіМенш важливі
Random Forestn_estimators, max_depthmin_samples_leaf
XGBoostlearning_rate, max_depth, n_estimatorsreg_alpha, reg_lambda
Нейронні мережіlearning_rate, архітектураmomentum, epsilon

🎬 Результати: Налаштована модель Марії

Після систематичного налаштування племінник Марії представив фінальне порівняння:

print("=" * 60)
print("МОДЕЛЬ ПРОГНОЗУВАННЯ ПІЦИ - ФІНАЛЬНЕ ПОРІВНЯННЯ")
print("=" * 60)

models = {
    'Базова (за замовчуванням)': 9.8,
    'Після feature engineering': 8.5,
    'Random Forest (вручну)': 7.8,
    'Random Forest (grid search)': 7.5,
    'XGBoost (Optuna tuned)': 6.4,
}

print(f"\n{'Модель':<35} {'Test RMSE':>15}")
print("-" * 52)
for model, rmse in models.items():
    print(f"{model:<35} {rmse:>12.1f} піц")

print("\n" + "=" * 60)
improvement = (9.8 - 6.4) / 9.8 * 100
print(f"Загальне покращення: {improvement:.0f}% зменшення помилки передбачення")
print(f"Від ±9.8 піц до ±6.4 піц")
print("=" * 60)

Результат:

============================================================
МОДЕЛЬ ПРОГНОЗУВАННЯ ПІЦИ - ФІНАЛЬНЕ ПОРІВНЯННЯ
============================================================

Модель                                    Test RMSE
----------------------------------------------------
Базова (за замовчуванням)                     9.8 піц
Після feature engineering                     8.5 піц
Random Forest (вручну)                        7.8 піц
Random Forest (grid search)                   7.5 піц
XGBoost (Optuna tuned)                        6.4 піц

============================================================
Загальне покращення: 35% зменшення помилки передбачення
Від ±9.8 піц до ±6.4 піц
============================================================

Марія посміхнулась. “±6.4 піци. Це менше однієї великої піци похибки. А на вихідних…”

“Похибка на вихідних знизилась до ±4.2 піц,” — додав племінник. “Ми перейшли від втрат 340упоганіпонеділкидопередбаченьвмежах340 у погані понеділки до передбачень в межах 50 від реальності.”


🏁 Підсумок: Ваш інструментарій налаштування

Швидка довідка

МетодНайкраще дляПотрібно спробПлюсиМінуси
Grid SearchМало параметрів, малі діапазониВсі комбінаціїВичерпнийПовільний, пропускає значення
Random SearchБагато параметрів, невідомі діапазони50-200Швидкий, гнучкийМоже пропустити оптимум
BayesianПродакшн налаштування, дорогі моделі30-100Ефективний, розумнийСкладніше налаштування

Чек-лист налаштування

  • Встановіть базову лінію з параметрами за замовчуванням
  • Визначте, які гіперпараметри найважливіші для вашого алгоритму
  • Почніть з грубого random search для пошуку перспективних регіонів
  • Використовуйте точний grid search або Байєсівську оптимізацію для уточнення
  • Використовуйте крос-валідацію під час налаштування
  • Тримайте відкладену тестову вибірку для фінальної оцінки
  • Збережіть результати пошуку для аналізу
  • Не налаштовуйте більше, ніж потрібно

Ключові висновки

  1. Параметри вивчаються моделлю; гіперпараметри встановлюєте ви
  2. Random search зазвичай перемагає grid search за той самий час
  3. Байєсівська оптимізація найефективніша, коли кожна спроба дорога
  4. Вкладена CV запобігає перенавчанню на валідаційній вибірці
  5. Почніть просто — налаштовуйте лише після робочої базової лінії

🚀 Що далі?

Вітаємо! Ви тепер завершили фазу покращення моделей:

  • ✅ Стаття 8: Діагностували та виправили перенавчання/недонавчання
  • ✅ Стаття 9: Комбінували моделі з ансамблями
  • ✅ Стаття 10: Оптимізували гіперпараметри

Модель піци Марії тепер:

  • Точна: ±6.4 піци похибка передбачення
  • Надійна: Працює і в будні, і на вихідних
  • Оптимізована: Найкращі можливі гіперпараметри знайдені систематично

Але залишається одне питання: “Як нам насправді ВИКОРИСТОВУВАТИ цю модель у ресторані?”

У Статті 11: Розгортання ML моделей ви дізнаєтесь:

  • Як зберігати та завантажувати навчені моделі
  • Створення prediction API з Flask/FastAPI
  • Docker контейнери для ML
  • Моніторинг моделей у продакшні

Подорож від Jupyter notebook до реального впливу починається!


Маєте питання про налаштування гіперпараметрів? Експериментуйте з різними стратегіями пошуку на своїх даних — найкраще навчання приходить через практику!