#python #validation #scikit-learn #grid-search #scoring
#python #проверка #scikit-learn #поиск по сетке #оценка
Вопрос:
Я использую sklearn GridSearch для поиска наилучших параметров для классификации случайного леса с использованием предопределенного набора проверки. Оценки от наилучшего оценщика, возвращаемые GridSearch, не соответствуют оценкам, полученным при обучении отдельного классификатора с теми же параметрами.
Определение разделения данных
X = pd.concat([X_train, X_devel])
y = pd.concat([y_train, y_devel])
test_fold = -X.index.str.contains('train').astype(int)
ps = PredefinedSplit(test_fold)
Определение GridSearch
n_estimators = [10]
max_depth = [4]
grid = {'n_estimators': n_estimators, 'max_depth': max_depth}
rf = RandomForestClassifier(random_state=0)
rf_grid = GridSearchCV(estimator = rf, param_grid = grid, cv = ps, scoring='recall_macro')
rf_grid.fit(X, y)
Определение классификатора
clf = RandomForestClassifier(n_estimators=10, max_depth=4, random_state=0)
clf.fit(X_train, y_train)
Отзыв был вычислен явно с использованием sklearn.metrics.recall_score
y_pred_train = clf.predict(X_train)
y_pred_devel = clf.predict(X_devel)
uar_train = recall_score(y_train, y_pred_train, average='macro')
uar_devel = recall_score(y_devel, y_pred_devel, average='macro')
Поиск по сетке
uar train: 0.32189884516029466
uar devel: 0.3328299259976279
Случайный лес:
uar train: 0.483040291148839
uar devel: 0.40706644557392435
В чем причина такого несоответствия?
Ответ №1:
Здесь есть несколько проблем:
-
Ваши входные аргументы для
recall_score
изменены на противоположные. Фактический правильный порядок:recall_score(y_true, y_test)
Но вы делаете:
recall_score(y_pred_train, y_train, average='macro')
Исправьте это на:
recall_score(y_train, y_pred_train, average='macro')
-
Вы делаете это
rf_grid.fit(X, y)
для поиска по сетке. Это означает, что после нахождения наилучших комбинаций параметров GridSearchCV будет соответствовать всем данным (целому X, игнорируяPredefinedSplit
, потому что это используется только во время перекрестной проверки в поисках наилучших параметров). Таким образом, по сути, оценщик изGridSearchCV
увидит все данные, поэтому оценки будут отличаться от того, что вы получаете при выполненииclf.fit(X_train, y_train)
Комментарии:
1. Спасибо за информацию. Что-то все еще неясное после изменения порядка аргументов ожидается, что отзыв после переподготовки для всего набора данных улучшится (поскольку классификатор теперь просматривает все данные), однако он остается более низким как для подмножеств train, так и для devel. Есть какие-либо подсказки, почему это так?
2. @OxanaVerkholyak Извините, я не могу больше ничего сказать, не видя образцов данных. Может быть много вещей: 1) Сбалансировано ли разделение вашего обучающего теста? 2) Ваши данные несбалансированы? 3) Сколько существует классов?. «recall_macro» не учитывает дисбаланс меток. Возможно, это может быть причиной. Как насчет других показателей, точности, матрицы путаницы и т.д. Пожалуйста, опубликуйте полный код вместе с некоторыми примерами данных, которые могут привести к такому результату.
Ответ №2:
Это потому, что в вашем GridSearchCV
вы используете функцию подсчета очков as, recall-macro
которая в основном возвращает усредненное значение, recall score
которое macro
является усредненным. Смотрите эту ссылку.
Однако, когда вы возвращаете оценку по умолчанию из своего, RandomForestClassifier
она возвращает mean accuracy
. Итак, вот почему оценки разные. Смотрите Эту ссылку для получения информации о том же. (Поскольку одно из них — это отзыв, а другое — точность).