Оптимизация значений гиперпараметров XGBoost Ошибка: Метка должна состоять из целых меток вида 0, 1, 2, …, [num_class — 1]

#python #xgboost #random-seed #hyperparameters

Вопрос:

Я выполняю некоторую базовую оптимизацию гиперпараметров для модели xgboost и столкнулся со следующей проблемой. Во-первых, мой код:

 from sklearn.preprocessing import LabelEncoder, OrdinalEncoder from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix, accuracy_score import xgboost as xgb from functools import partial from skopt import space, gp_minimize  lt;Some preprocessing...gt;   x = Oe.fit_transform(x) y = Ly.fit_transform(y)   def optimize(params, param_names, x, y):  params = dict(zip(params, param_names))  X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2)  nc = len(set(y_train))  xgb_model = xgb.XGBClassifier(use_label_encoder=False, num_class=nc 1, objective="multi:softprob", **params)  xgb_model.fit(X_train, y_train)  preds = xgb_model.predict(X_test)  acc = accuracy_score(y_test, preds)  return -1.0 * acc   param_space = [  space.Integer(3, 10, name="max_depth"),  space.Real(0.01, 0.3, prior="uniform", name="learning_rate"), ]  param_names = [  "max_depth",  "learning_rate" ]  optimization_function = partial(  optimize,  param_names,  x=x,  y=y )  result = gp_minimize(  optimization_function,  dimensions=param_space,  n_calls=30,  n_random_starts=6,  verbose=True )  print(dict(zip(param_names, result.x)))  

После того, как я сам провел поиск, я понял, что если я не использую a random_state в своем тестовом расколе на поезде, чтобы получить детерминированный результат, то я рискую получить a y_train , который не содержит меток в форме 0,1,2 … таким образом, получается следующая ошибка ValueError: The label must consist of integer labels of form 0, 1, 2, ..., [num_class - 1].

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

И действительно, после запуска моего кода, random_state=0 например, после 3 итераций gp_minimize, я в конечном итоге получаю один и тот же оптимум, независимо от того, какую комбинацию гиперпараметров он создает.

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

Комментарии:

1. Каково распределение ваших занятий y ? Наверное, достаточно установить stratify=y в сплиттер? Я задаюсь вопросом, является ли хорошей идеей разрешить гауссовскому процессу использовать разные разбиения для каждого набора гиперпараметров…не рискует ли это повысить/понизить значение гиперпараметра только из-за удачного/неудачного раскола?

2. @BenReiniger Я только начал изучать науку о данных, поэтому, если я скажу что-то, что не имеет смысла, пожалуйста, потерпите меня. Видите ли, проблема в том, что мой набор данных настолько мал (14×16), что я даже не думаю, что смогу сделать хорошее предположение, когда речь заходит о распределении переменной y. Что касается вашего второго пункта, то, если вы читали мой последний абзац, я размышлял о том, имеет ли это смысл или нет. Но опять же, как я уже сказал, после 3 итераций с одним и тем же разбиением я получаю точность 100%, так что это заставило меня подумать, что моя модель может быть переоснащена, и заставило меня попробовать использовать разные разбиения.

3. @BenReiniger также не могли бы вы объяснить, почему стратификация не используется в большинстве случаев при разделении поезда/теста? По крайней мере, до сих пор я не видел его в какой-либо реализации

4. Я не могу представить, чтобы xgboost очень хорошо справлялся всего с 14 строками, особенно с более чем одним классом. Я почти всегда видел stratify , как используется; с большими наборами данных это не имеет большого значения, потому что случайность, скорее всего, в любом случае приведет к примерно равномерному распределению, но для небольших наборов данных может быть полезно приложить больше усилий для обеспечения одинакового распределения классов.

5. @BenReiniger большое спасибо за объяснение. Да, мне совершенно ясно, что xgboost не будет хорошо работать с 14 строками. Я попробую стратифицировать и посмотрю, решит ли это мою проблему.