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

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

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

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

  • Точность: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

person Muhammad Ibrar    schedule 28.11.2020    source источник
comment
Получали ли вы одинаковые результаты каждый раз, когда запускали код? Я имел в виду одинаковую точность каждый раз с одной и той же кодировкой?   -  person coderina    schedule 28.11.2020
comment
@coderina Да, каждый раз, когда я запускаю код с одним и тем же кодированием, я получаю одинаковые результаты для точности, f1, отзыва, точности.   -  person Muhammad Ibrar    schedule 28.11.2020
comment
@MuhammadIbrar: причина такого поведения может заключаться в том, что модели ML обычно используют случайное начальное число, которое является фиксированным, поэтому результаты повторяются. Если вам это не нравится, вы должны устанавливать начальное число на случайное число каждый раз, когда вы обучаете свою модель, а также для train_test_split или сгибов.   -  person jottbe    schedule 29.11.2020
comment
Думаю, для XGBClassifier этот аргумент называется random_state. Просто попробуйте random_state=random.randint(0, 2147483647). Только что узнал, что вы явно исправляете random_state для train_test_split на 1, поэтому он всегда будет выбирать одни и те же записи для обучения и тестирования.   -  person jottbe    schedule 29.11.2020
comment
Кстати. это точно так же для light-gbm. если вы опустите здесь параметр seed, все случайные начальные значения инициализируются константой int каждый раз, когда вы его запускаете, поэтому, если ничего не изменится в данных или параметрах, вы получите точно такой же результат.   -  person jottbe    schedule 29.11.2020


Ответы (1)


Это связано с тем, что счет f1, точность и отзыв связаны между собой.

Формулы:

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

а также

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

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

              ----------
              |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|
----------------------
person jottbe    schedule 28.11.2020