Пропустить некоторые этапы преобразования (связанные с избыточной и недостаточной выборкой) в конвейере несбалансированного обучения при прогнозировании набора тестовых данных [дубликаты]

Для проблемы несбалансированной классификации я использую конвейер imblearn вместе с GridSearchCV sklearn (чтобы найти лучшие гиперпараметры). Шаги в конвейере следующие:

  1. Стандартизируйте каждую функцию
  2. Исправьте дисбаланс классов с помощью выборки ADASYN.
  3. Обучить классификатор случайного леса

Поиск гиперпараметров выполняется в указанном выше конвейере с использованием GridSearchCV (вместе со стратифицированным cv). Пространство поиска гиперпараметров включает гиперпараметры как из ADASYN, так и из Random Forest.

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

Причина в том, что для прогнозирования на тестовом наборе данных мы не должны использовать выборку ADASYN. Набор тестовых данных следует прогнозировать как есть, без какой-либо выборки. Таким образом, конвейер для прогнозирования должен быть:

  1. Стандартизируйте каждую функцию
  2. Выборка ADASYN
  3. Прогнозирование с использованием обученного классификатора случайного леса

Как я могу использовать API sklearn/imblearn, чтобы таким образом игнорировать определенное преобразование в конвейере?

Мой код (выражает ту же проблему, что и выше):

import pandas as pd
from imblearn.pipeline import Pipeline as imbPipeline
from imblearn.over_sampling import ADASYN
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold
from sklearn.ensemble import RandomForestClassifier

# Get data
df = pd.read_csv('train.csv')
y_col = 'output'
x_cols = [c for c in df.columns if c != y_col]

# Train and Test data sets
train, test = train_test_split(df, shuffle=True, stratify=df[y_col])

# Define pipeline of transforms and model
pl = imbPipeline([('std', StandardScaler()),
                  ('sample', ADASYN()),
                  ('rf', RandomForestClassifier())])

# Additional code to define params for grid-search omitted.
# params will contain hyper-parameters for ADASYN as well as random forest

# grid search cv
cv = GridSearchCV(pl, params, scoring='f1', n_jobs=-1)
cv.fit(train[x_cols], train[y_col])

# Now that the grid search has been done and the object cv contains the
# best hyper-parameters, I would like to test on test data set:

test_pred = cv.predict(test[x_cols])  # WRONG! No need to do ADASYN sampling!

person Chaos    schedule 29.10.2018    source источник
comment
Я не думаю, что вам нужно делать ADASYN после стандартизации ваших функций, на самом деле вы можете получить результаты, которые лучше соответствуют фактическим данным, если они не масштабированы. Если бы это был я, я бы сделал передискретизацию вне конвейера, тогда вы можете использовать конвейер как обычно.   -  person G. Anderson    schedule 29.10.2018
comment
Что ж, ребята из imblearn думают точно так же, так что об этом позаботились. Когда вы вызываете predict() или transform() в конвейере imblearn, он автоматически пропускает часть выборки. Подробнее см. мой другой ответ здесь (и ответ, связанный с этим ответом).   -  person Vivek Kumar    schedule 30.10.2018
comment
Спасибо, @VivekKumar! Оглядываясь назад, для меня это должно было быть очевидным, поскольку test_pred.shape имеет то же количество строк, что и test[x_cols].shape. :)   -  person Chaos    schedule 30.10.2018