Я делаю двоичный классификатор с несбалансированными классами (соотношение 1:10). Я попробовал KNN, RFs и XGB классификатор. Я получаю лучший компромисс между точностью и отзывом и оценкой F1 среди них от классификатора XGB (возможно, потому, что размер набора данных очень меньше - (1900,19)
)
Поэтому после проверки графиков ошибок для XGB я решил go для RandomizedSearchCV()
от sklearn для настройки параметров моего классификатора XGB. Основываясь на другом ответе на stackexchange, это мой код:
from xgboost import XGBClassifier
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold
score_arr = []
clf_xgb = XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': [50, 120, 180, 240, 400],
'learning_rate': [0.01, 0.03, 0.05],
'subsample': [0.5, 0.7],
'max_depth': [3, 4, 5],
'min_child_weight': [1, 2, 3],
'scale_pos_weight' : [9]
}
clf = RandomizedSearchCV(clf_xgb, param_distributions = param_dist, n_iter = 25, scoring = 'precision', error_score = 0, verbose = 3, n_jobs = -1)
print(clf)
numFolds = 6
folds = StratifiedKFold(n_splits = numFolds, shuffle = True)
estimators = []
results = np.zeros(len(X))
score = 0.0
for train_index, test_index in folds.split(X_train, y_train):
print(train_index)
print(test_index)
_X_train, _X_test = X.iloc[train_index,:], X.iloc[test_index,:]
_y_train, _y_test = y.iloc[train_index].values.ravel(), y.iloc[test_index].values.ravel()
clf.fit(_X_train, _y_train, eval_metric="error", verbose=True)
estimators.append(clf.best_estimator_)
results[test_index] = clf.predict(_X_test)
score_arr.append(f1_score(_y_test, results[test_index]))
score += f1_score(_y_test, results[test_index])
score /= numFolds
Итак, RandomizedSearchCV
фактически выбирает классификатор, а затем в kfolds он подгоняется и предсказывает результат на проверочном наборе. Обратите внимание, что я дал X_train
и y_train
в kfolds split, так что у меня есть отдельный набор данных test
для тестирования окончательного алгоритма.
Теперь проблема в том, что если вы на самом деле смотрите f1-score
в каждой итерации kfold, это выглядит так: score_arr = [0.5416666666666667, 0.4, 0.41379310344827586, 0.5, 0.44, 0.43478260869565216]
.
Но когда я проверяю clf.best_estimator_
в качестве моей модели, в моем test
наборе данных он дает f1-score
из 0.80
и с {'precision': 0.8688524590163934, 'recall': 0.7571428571428571}
точностью и отзывом.
Как получился мой результат, когда валидация низкая, и что теперь произошло на тестовом наборе? Моя модель верна или я что-то пропустил?
PS - Принимая параметры clf.best_estimator_
, я подгонял их отдельно по своим тренировочным данным, используя xgb.cv
, тогда также f1-score
был рядом 0.55
. Я думаю, что это может быть связано с различиями между тренировочными подходами RandomizedSearchCV
и xgb.cv
. Скажите, пожалуйста, нужны ли графики или дополнительная информация.
Обновление : я прилагаю графики ошибок поезда и проверяю aucpr
и classification accuracy
для сгенерированной модели. Сюжет создается при запуске model.fit()
только один раз (оправдывая значения score_arr
).