Saya sedang mengerjakan dataset berlabel biner yang sangat tidak seimbang, di mana jumlah label yang benar hanya 7% dari keseluruhan dataset. Tetapi beberapa kombinasi fitur dapat menghasilkan jumlah yang lebih tinggi dari yang di himpunan bagian.
Misalnya kita memiliki dataset berikut dengan satu fitur (warna):
180 sampel merah - 0
20 sampel merah - 1
300 sampel hijau - 0
100 sampel hijau - 1
Kita dapat membangun pohon keputusan sederhana:
(color)
red / \ green
P(1 | red) = 0.1 P(1 | green) = 0.25
P (1) = 0,2 untuk keseluruhan dataset
Jika saya menjalankan XGBoost pada dataset ini, ia dapat memprediksi probabilitas tidak lebih besar dari 0,25. Yang berarti, bahwa jika saya membuat keputusan pada ambang 0,5:
- 0 - P <0,5
- 1 - P> = 0,5
Maka saya akan selalu mendapatkan semua sampel berlabel nol . Semoga saya jelas menggambarkan masalahnya.
Sekarang, pada dataset awal saya mendapatkan plot berikut (ambang x-axis):
Memiliki maksimum f1_score pada ambang = 0,1. Sekarang saya punya dua pertanyaan:
- haruskah saya menggunakan f1_score untuk dataset struktur seperti itu?
- apakah selalu masuk akal untuk menggunakan ambang 0,5 untuk memetakan probabilitas label ketika menggunakan XGBoost untuk klasifikasi biner?
Memperbarui. Saya melihat bahwa topik tersebut menarik minat. Di bawah ini adalah kode Python untuk mereproduksi percobaan merah / hijau menggunakan XGBoost. Ini sebenarnya menghasilkan probabilitas yang diharapkan:
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
import numpy as np
X0_0 = np.zeros(180) # red - 0
Y0_0 = np.zeros(180)
X0_1 = np.zeros(20) # red - 1
Y0_1 = np.ones(20)
X1_0 = np.ones(300) # green - 0
Y1_0 = np.zeros(300)
X1_1 = np.ones(100) # green - 1
Y1_1 = np.ones(100)
X = np.concatenate((X0_0, X0_1, X1_0, Y1_1))
Y = np.concatenate((Y0_0, Y0_1, Y1_0, Y1_1))
# reshaping into 2-dim array
X = X.reshape(-1, 1)
import xgboost as xgb
xgb_dmat = xgb.DMatrix(X_train, label=y_train)
param = {'max_depth': 1,
'eta': 0.01,
'objective': 'binary:logistic',
'eval_metric': 'error',
'nthread': 4}
model = xgb.train(param, xg_mat, 400)
X0_sample = np.array([[0]])
X1_sample = np.array([[1]])
print('P(1 | red), predicted: ' + str(model.predict(xgb.DMatrix(X0_sample))))
print('P(1 | green), predicted: ' + str(model.predict(xgb.DMatrix(X1_sample))))
Keluaran:
P(1 | red), predicted: [ 0.1073855]
P(1 | green), predicted: [ 0.24398108]
sumber
xgboost
mendukung bobot kelas, OP harus bermain dengan mereka jika ia tidak puas dengan metrik apa pun yang ingin dimaksimalkan.n_samples / (n_classes * np.bincount(y))
. Ini menghindari pengklasifikasi yang memberi bobot lebih ke kelas yang lebih padat.