Вопрос или проблема
Я использую 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
позволит вам контролировать количество моделей, обучаемых в процессе оптимизации, и избежать излишних вычислений.