RandomizedSearchCV(n_iter=10) не останавливается после обучения 10 моделей.

Вопрос или проблема

Я использую RandomizedSearchCV для оптимизации гиперпараметров. Когда я запускаю модель, она показывает оценки для каждой тренировки модели. Проблема в том, что она обучает гораздо больше 10 моделей, в то время как я ожидаю, что будет обучено всего 10 моделей, указав n_iters равным 10. Почему это происходит? Что мне сделать, чтобы ограничить общее количество запусков до 10?

Вот мой код

from catboost import CatBoostRegressor
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint

params = {
    'iterations': randint(100, 1000),
    'depth': randint(3, 10),
    'learning_rate': [0.01, 0.02, 0.03, 0.04, 0.05],
    'l2_leaf_reg': randint(1, 10),
    'border_count': randint(32, 255),
    'bagging_temperature': [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
}

model = CatBoostRegressor(loss_function='RMSE', od_type="Iter", cat_features=[0, 1, 2, 3, 4], task_type="GPU")
search = RandomizedSearchCV(model, param_distributions=params, n_iter=10, scoring='neg_root_mean_squared_error')

# Обучаем модель
search.fit(X_train, y_train, eval_set=(X_val, y_val), plot=True)

Вы просто упускаете из виду часть “CV”? По умолчанию выполняется 5-кратная перекрестная проверка для оценки производительности каждой комбинации гиперпараметров, поэтому $5\cdot10=50$ моделей будет обучено ($+1$ для окончательной модели повторной подгонки).

Параметр n_iter в RandomizedSearchCV указывает количество итераций, которые нужно выполнить для оптимизации гиперпараметров. Однако он не обязательно ограничивает общее количество моделей, которые будут обучены.

Причина этого в том, что RandomizedSearchCV выполняет случайный поиск по пространству гиперпараметров. Это означает, что он случайным образом выбирает параметры из распределений для каждой итерации. Поэтому возможно, что некоторые комбинации гиперпараметров будут повторяться в нескольких итерациях, что приведет к обучению более чем 10 моделей.

Чтобы ограничить общее количество обученных моделей до 10, вы можете установить параметр max_evals в CatBoostRegressor. Этот параметр ограничивает максимальное количество итераций для оптимизации гиперпараметров. Вы можете установить его равным 10, чтобы гарантировать, что будет обучено только 10 моделей:

     model = CatBoostRegressor(loss_function='RMSE', od_type="Iter",
            cat_features=[0, 1, 2, 3, 4],
            task_type="GPU", max_evals=10)

     search = RandomizedSearchCV(model, param_distributions=params, 
              n_iter=10,scoring='neg_root_mean_squared_error')
        
     search.fit(X_train, y_train, eval_set=(X_val, y_val), plot=True)

#Вот еще один способ:

[Если вы хотите ограничить общее количество подгонок модели до 10, вы можете установить параметр n_estimators в CatBoostRegressor равным 1 и установить параметр cv в RandomizedSearchCV на 10 (или любое другое число, которое меньше или равно 10). Это гарантирует, что будет подогнана только одна модель для каждой комбинации гиперпараметров, и что всего будет подогнано 10 моделей.]

model = CatBoostRegressor(
    n_estimators=1, # Подгоняем только одну модель для каждой комбинации гиперпараметров
    loss_function='RMSE', od_type="Iter",
    cat_features=[0, 1, 2, 3, 4], task_type="GPU"
)

search = RandomizedSearchCV(
    model, param_distributions=params, n_iter=10,
    scoring='neg_root_mean_squared_error', cv=10 # Ограничить до 10 фолдов
)

# Обучаем модель
search.fit(X_train, y_train, eval_set=(X_val, y_val), plot=True)

Ответ или решение

Проблема, с которой вы столкнулись, заключается в том, что параметр n_iter в RandomizedSearchCV определяет количество итераций для поиска гиперпараметров, но не ограничивает общее число моделей, которые будут обучены.

По умолчанию при выполнении RandomizedSearchCV используется кросс-валидация, обычно с 5 складками (folds). Это означает, что для каждой комбинации гиперпараметров будет обучено 5 моделей, что приводит к общему количеству обученных моделей, равному (5 \cdot n_iter + 1) (одна модель для финальной подгонки на полных данных).

Если вы установили n_iter=10, то с 5-кратной кросс-валидацией будет обучено 50 моделей (10 комбинаций гиперпараметров по 5 фолдам, плюс одна модель для финальной подгонки).

Чтобы ограничить общее количество обученных моделей до 10, вы можете использовать один из следующих подходов:

Подход 1: Установка max_evals

В CatBoostRegressor нет параметра max_evals, но вы можете сбалансировать сложность модели и количество итераций. Однако наиболее подходящий способ будет заключаться в ограничении количества фолдов в кросс-валидации.

Подход 2: Установка n_estimators и cv

Один из способов снизить количество итераций – это задать n_estimators=1 в CatBoostRegressor, что гарантирует обучение одной модели для каждой комбинации гиперпараметров. При этом вы также можете ограничить количество фолдов, чтобы контролировать общее количество вариантов. Установив cv=1, вы сможете достичь пределы в 10 моделей, если используете n_iter=10.

Вот пример кода:

from catboost import CatBoostRegressor
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint

params = {
    'iterations': randint(100, 1000),
    'depth': randint(3, 10),
    'learning_rate': [0.01, 0.02, 0.03, 0.04, 0.05],
    'l2_leaf_reg': randint(1, 10),
    'border_count': randint(32, 255),
    'bagging_temperature': [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
}

model = CatBoostRegressor(
    n_estimators=1,  # Обучаем только одну модель на каждую комбинацию гиперпараметров
    loss_function='RMSE',
    od_type="Iter",
    cat_features=[0, 1, 2, 3, 4],
    task_type="GPU"
)

search = RandomizedSearchCV(
    model,
    param_distributions=params,
    n_iter=10,  # Количество различных комбинаций гиперпараметров
    scoring='neg_root_mean_squared_error',
    cv=1  # Устанавливаем кросс-валидацию на 1, чтобы избежать большого количества моделей
)

# Обучаем модель
search.fit(X_train, y_train, eval_set=(X_val, y_val), plot=True)

Таким образом, использование n_estimators=1 и cv=1 позволит вам контролировать количество моделей, обучаемых в процессе оптимизации, и избежать излишних вычислений.

Оцените материал
Добавить комментарий

Капча загружается...