В двоичной классификации кодирование целевой переменной из yes = 1, no = 0 дает разные результаты, чем yes = 0, no = 1 в XGboosting

#python #machine-learning #classification #xgboost #precision-recall

#python #машинное обучение #классификация #xgboost #точность-отзыв

Вопрос:

Я новичок в машинном обучении. В задаче двоичной классификации мы кодируем / преобразуем целевую переменную как yes = 1 и No = 0 (непосредственно в наборе данных), это дает следующие результаты

  • Точность: 95
  • Напомним: 90
  • Точность: 94
  • F1: 92

но если мы кодируем / преобразуем целевую переменную обратно, например, yes = 0 и No = 1 (непосредственно в dataset), то это дает следующие результаты

  • Точность: 95
  • Напомним:97
  • Точность: 94
  • F1:95

Я использую алгоритм XGBoost. Все остальные переменные являются числовыми (положительными и отрицательными) Хотя точность одинакова в обоих случаях, но я предполагаю, что F1 также должно быть одинаковым в обоих случаях. Итак, почему это дает разные результаты. Я знаю, что scikit-learn может обрабатывать кодирование, но почему F1 отличается в обоих случаях?

 xtrain,xtest,ytrain,ytest=train_test_split(X,encoded_Y,test_size=0.3,random_state=100,shuffle=True)
clf_xgb = xgb.XGBClassifier(nthread=1,random_state=100)
clf_xgb.fit(xtrain, ytrain)
xgb_pred = clf_xgb.predict(xtest)
xgb_pred_prb=clf_xgb.predict_proba(xtest)[:,1]
print(confusion_matrix(xgb_pred,ytest))
# [984   57]
# [103 1856]

#Find Accuracy of XGBoost
accuracy_xgb = accuracy_score(ytest,xgb_pred)
print("Accuracy: {}".format(accuracy_xgb)

#Find Recall of XGBoost
recall_xgb = recall_score(ytest,xgb_pred)
recall_xgb

#Find Precision of XGBoost
precision_xgb = precision_score(ytest,xgb_pred)
precision_xgb

#Find F1 Score XGB
xgb_f1=f1_score(ytest,xgb_pred)
xgb_f1
 

Комментарии:

1. Вы получали одни и те же результаты каждый раз, когда запускали код? Я имел в виду одинаковую точность каждый раз при одной и той же кодировке?

2. @coderina Да, каждый раз, когда я запускаю код с одинаковым конечным кодированием, он дает мне одинаковые результаты для точности, f1, отзыва, точности.

3. @MuhammadIbrar: причиной такого поведения может быть то, что модели ML обычно используют случайное начальное значение, которое фиксировано, поэтому результаты повторяются. Если вам это не нравится, вы должны устанавливать начальное значение на случайное число каждый раз, когда вы тренируете свою модель, а также для train_test_split сгибов or .

4. Для XGBClassifier этого аргумента назван random_state , я думаю. Просто попробуйте random_state=random.randint(0, 2147483647) . Только что понял, что вы явно фиксируете значение random_state for train_test_split равным 1, поэтому он всегда будет выбирать одни и те же записи для обучения и тестирования.

5. Кстати. это точно то же самое для light-gbm. если вы опускаете начальный параметр, все случайные начальные значения инициализируются постоянным значением int каждый раз, когда вы его запускаете, поэтому, если ничего не изменится в данных или параметрах, вы получите точно такой же результат.

Ответ №1:

Это связано с тем, что оценка f1 и точность и отзыв связаны.

Формулы:

 f1= 2/((recall^-1) (precision^-1))
 

и

 recall= true_positives / (true_positives   false_negatives)
precision= true_positives / (true_positives   false_positives)
 

Таким образом, отзыв и точность зависят от того, что вы определяете как положительное (1). Если вы переключаете свои положительные / отрицательные случаи, как вы делаете, отображая yes / no по-разному, вы получаете совершенно другой результат.
Вы можете увидеть это с помощью следующего вычисления, предполагая, что у вас есть 100 yes и 4900 nos, и получите следующий результат:

               ----------
              |YES|NO  |
|-------------|---|----|
|predicted_YES| 90|   5|
|-------------|---|----|
|predicted_NO | 10|4895|
------------------------
 

Тогда, если вы определяете YES как положительное (1), вы получаете

 precision=90/(90 5)=0.947
recall=90/(90 10)=0.9
f1= 2/(precision^(-1)   recall^(-1))=0.923
 

В то время как, если вы определяете NO как положительное (1), вы получаете:

 precision=4895/(4895 10)=0.998
recall=4895/(4895 10)=0.999
f1= 2 / (precision^(-1)   recall^(-1))=0.998
 

Обратите внимание, если YES это ваш положительный класс, приведенная выше матрица присваивается true_positives , … вот так:

               --------
              |YES|NO|
|-------------|---|--|
|predicted_YES|TP |FP|
|-------------|---|--|
|predicted_NO |FN |TN|
----------------------
 

В то время как, если вы определяете NO как положительный класс, true_positives , … присваиваются следующим образом:

               --------
              |YES|NO|
|-------------|---|--|
|predicted_YES|TN |FN|
|-------------|---|--|
|predicted_NO |FP |TP|
----------------------