Data multikelas tidak seimbang dengan XGBoost


20

Saya memiliki 3 kelas dengan distribusi ini:

Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163

Dan saya menggunakan xgboostuntuk klasifikasi. Saya tahu bahwa ada parameter bernama scale_pos_weight.

Tetapi bagaimana penanganannya untuk kasus 'multi-kelas', dan bagaimana cara mengaturnya dengan benar?

Jawaban:


18

scale_pos_weightdigunakan untuk klasifikasi biner seperti yang Anda nyatakan. Ini adalah solusi yang lebih umum untuk menangani kelas yang tidak seimbang. Pendekatan yang baik saat menetapkan nilai scale_pos_weightadalah:

sum(negative instances) / sum(positive instances)

Untuk kasus spesifik Anda, ada opsi lain untuk mempertimbangkan masing-masing titik data dan mempertimbangkan bobotnya saat bekerja dengan booster, dan membiarkan pengoptimalan terjadi terkait bobotnya sehingga setiap titik diwakili secara sama. Anda hanya perlu menggunakan:

xgboost.DMatrix(..., weight = *weight array for individual weights*)

Anda dapat menentukan bobot sesuai keinginan dan dengan melakukannya, Anda bahkan dapat menangani ketidakseimbangan di dalam kelas dan juga ketidakseimbangan di berbagai kelas.


> Pendekatan yang baik ketika memberikan nilai ke scale_pos_weight adalah: jumlah (contoh negatif) / jumlah (contoh positif)
lcrmorin

1
Saya melihat saran ini di mana-mana dan masuk akal untuk memberikan bobot yang lebih tinggi untuk kelas yang kurang terwakili. Namun saya kesulitan menemukan sumber yang membahas nilai persis ini. Saya mendapatkan intuisi di balik nilai spesifik itu (membuat sampel seimbang) tetapi saya curiga ada varian trade-off di suatu tempat, yang akan membuat Anda ingin mempertimbangkan bobot yang lebih rendah.
lcrmorin

7

Jawaban oleh @KeremT ini benar. Saya memberikan contoh bagi mereka yang masih memiliki masalah dengan implementasi yang tepat.

weightparameter dalam XGBoost per instance tidak per kelas. Oleh karena itu, kita perlu menetapkan bobot masing-masing kelas untuk instance-nya, yang merupakan hal yang sama.

Sebagai contoh, jika kita memiliki tiga kelas yang tidak seimbang dengan rasio

class A = 10%
class B = 30%
class C = 60%

Bobot mereka akan (membagi kelas terkecil dengan yang lain)

class A = 1.000
class B = 0.333
class C = 0.167

Lalu, apakah data pelatihannya

index   class
0       A
1       A
2       B
3       C
4       B

kami membuat weightvektor sebagai berikut:

index   class    weight
0       A        1.000
1       A        1.000
2       B        0.333
3       C        0.167
4       B        0.333

5

Semua orang tersandung pada pertanyaan ini ketika berhadapan dengan masalah klasifikasi multi-kelas yang tidak seimbang menggunakan XGBoost di R. Saya juga melakukannya!

Saya sedang mencari contoh untuk lebih memahami bagaimana menerapkannya. Investasikan hampir satu jam untuk menemukan tautan yang disebutkan di bawah ini. Untuk semua yang mencari contoh, begini -

/datascience//a/9493/37156

Terima kasih wacax


0

Cukup berikan setiap instance data kereta Anda dengan bobot kelasnya. Pertama, dapatkan bobot kelas dengan class_weight.compute_class_weightsklearn lalu tetapkan setiap baris data kereta sesuai bobotnya.

Saya berasumsi di sini bahwa data kereta memiliki kolom 'kelas' yang berisi nomor kelas. Saya berasumsi juga bahwa ada nb_class yang dari 1 ke nb_classes.

from sklearn.utils import class_weight
class_weights = list(class_weight.compute_class_weight('balanced',
                                             np.unique(train['class']),
                                             train['class']))

w_array = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
    w_array[i] = class_weights[val-1]

xgb_classifier.fit(X, y, sample_weight=w_array)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.