Как применить передискретизацию при проведении перекрестной проверки Leave-One-Group-Out? - PullRequest
6 голосов
/ 10 июля 2019

Я работаю над несбалансированными данными для классификации и ранее пытался использовать метод передовой выборки синтетического меньшинства (SMOTE) для передискретизации обучающих данных.Однако в этот раз я думаю, что мне также нужно использовать перекрестную проверку Leave One Group Out (LOGO), потому что я хочу оставить один предмет в каждом резюме.

Я не уверен, смогу ли я объяснить это хорошо, но, насколько я понимаю, для выполнения k-кратного CV с использованием SMOTE мы можем зацикливать SMOTE на каждом сгибе, как я видел в этом коде в другом посте .Ниже приведен пример реализации SMOTE для k-кратного CV.

from sklearn.model_selection import KFold
from imblearn.over_sampling import SMOTE
from sklearn.metrics import f1_score

kf = KFold(n_splits=5)

for fold, (train_index, test_index) in enumerate(kf.split(X), 1):
    X_train = X[train_index]
    y_train = y[train_index]  
    X_test = X[test_index]
    y_test = y[test_index]  
    sm = SMOTE()
    X_train_oversampled, y_train_oversampled = sm.fit_sample(X_train, y_train)
    model = ...  # classification model example
    model.fit(X_train, y_train)  
    y_pred = model.predict(X_test)
    print(f'For fold {fold}:')
    print(f'Accuracy: {model.score(X_test, y_test)}')
    print(f'f-score: {f1_score(y_test, y_pred)}')

Без SMOTE я попытался сделать это, чтобы сделать LOGO CV.Но, делая это, я буду использовать супер несбалансированный набор данных.

X = X
y = np.array(df.loc[:, df.columns == 'label'])
groups = df["cow_id"].values #because I want to leave cow data with same ID on each run
logo = LeaveOneGroupOut()

logo.get_n_splits(X_std, y, groups)

cv=logo.split(X_std, y, groups)

scores=[]
for train_index, test_index in cv:
    print("Train Index: ", train_index, "\n")
    print("Test Index: ", test_index)
    X_train, X_test, y_train, y_test = X[train_index], X[test_index], y[train_index], y[test_index]
    model.fit(X_train, y_train.ravel())
    scores.append(model.score(X_test, y_test.ravel()))

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

Я был бы рад предоставить больше информации.Спасибо!

1 Ответ

0 голосов
/ 15 июля 2019

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

В вашем случае следующий код будет правильным способом реализации SMOTE внутри цикла LOGO CV.

for train_index, test_index in cv:
    print("Train Index: ", train_index, "\n")
    print("Test Index: ", test_index)
    X_train, X_test, y_train, y_test = X[train_index], X[test_index], y[train_index], y[test_index]
    sm = SMOTE()
    X_train_oversampled, y_train_oversampled = sm.fit_sample(X_train, y_train)
    model.fit(X_train_oversampled, y_train_oversampled.ravel())
    scores.append(model.score(X_test, y_test.ravel()))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...