Превышение выборки с помощью перекрестной проверки Leave One Out - PullRequest
0 голосов
/ 13 июня 2019

Я работаю с крайне несбалансированным набором данных с 44 пробами для моего исследовательского проекта.Это проблема бинарной классификации с 3/44 выборками из класса меньшинства, для которого я использую перекрестную проверку Leave One Out.Если я выполняю SMOTE передискретизацию всего набора данных до цикла LOOCV, точность прогноза и AUC для кривых ROC близки к 90% и 0,9 соответственно.Однако, если я выберу только обучающий набор внутри цикла LOOCV, что является более логичным подходом, AUC для кривых ROC упадет до 0,3

, я также попробовал кривые с точным возвратом и стратифицированную k-кратностьперекрестная проверка, но столкнулась с аналогичным различием в результатах избыточной выборки снаружи и внутри цикла.Пожалуйста, предложите мне, каково правильное место для передискретизации, а также объясните различие, если это возможно.

Превышение частоты внутри цикла: -

i=0
acc_dec = 0
y_test_dec=[] #Store y_test for every split
y_pred_dec=[] #Store probablity for positive label for every split

for train, test in loo.split(X):    #Leave One Out Cross Validation
    #Create training and test sets for split indices
    X_train = X.loc[train]  
    y_train = Y.loc[train]
    X_test = X.loc[test]
    y_test = Y.loc[test]

    #oversampling minority class using SMOTE technique
    sm = SMOTE(sampling_strategy='minority',k_neighbors=1)
    X_res, y_res = sm.fit_resample(X_train, y_train)

    #KNN
    clf = KNeighborsClassifier(n_neighbors=5) 
    clf = clf.fit(X_res,y_res)
    y_pred = clf.predict(X_test)
    acc_dec = acc_dec +  metrics.accuracy_score(y_test, y_pred)
    y_test_dec.append(y_test.to_numpy()[0])
    y_pred_dec.append(clf.predict_proba(X_test)[:,1][0])
    i+=1

# Compute ROC curve and ROC area for each class
fpr,tpr,threshold=metrics.roc_curve(y_test_dec,y_pred_dec,pos_label=1)
roc_auc = metrics.auc(fpr, tpr)
print(str(acc_dec/i*100)+"%")

AUC: 0,25

Точность:68,1%

Превышение частоты вне цикла:

acc_dec=0 #accuracy for decision tree classifier
y_test_dec=[] #Store y_test for every split
y_pred_dec=[] #Store probablity for positive label for every split
i=0
#Oversampling before the loop
sm = SMOTE(k_neighbors=1)
X, Y = sm.fit_resample(X, Y)   
X=pd.DataFrame(X)
Y=pd.DataFrame(Y)
for train, test in loo.split(X):    #Leave One Out Cross Validation

    #Create training and test sets for split indices
    X_train = X.loc[train]  
    y_train = Y.loc[train]
    X_test = X.loc[test]
    y_test = Y.loc[test]

    #KNN
    clf = KNeighborsClassifier(n_neighbors=5) 
    clf = clf.fit(X_res,y_res)
    y_pred = clf.predict(X_test)
    acc_dec = acc_dec +  metrics.accuracy_score(y_test, y_pred)
    y_test_dec.append(y_test.to_numpy()[0])
    y_pred_dec.append(clf.predict_proba(X_test)[:,1][0])
    i+=1

# Compute ROC curve and ROC area for each class
fpr,tpr,threshold=metrics.roc_curve(y_test_dec,y_pred_dec,pos_label=1)
roc_auc = metrics.auc(fpr, tpr)
print(str(acc_dec/i*100)+"%")

AUC: 0,99

Точность: 90,24%

Как эти два подхода могут привести к таким разнымРезультаты?За чем мне следовать?

1 Ответ

1 голос
/ 13 июня 2019

Выполнение передискретизации (например, SMOTE) перед разделением данных означает, что информация о тренировочном наборе присутствует в тестовом наборе.Это иногда называют «утечкой».Ваша первая настройка, к сожалению, правильная.

Вот сообщение , проходящее через эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...