Saya mengalami banyak masalah dalam memahami bagaimana class_weight
parameter dalam Regresi Logistik scikit-learn beroperasi.
Situasi
Saya ingin menggunakan regresi logistik untuk melakukan klasifikasi biner pada kumpulan data yang sangat tidak seimbang. Kelas diberi label 0 (negatif) dan 1 (positif) dan data yang diamati memiliki rasio sekitar 19: 1 dengan mayoritas sampel memiliki hasil negatif.
Upaya Pertama: Menyiapkan Data Pelatihan Secara Manual
Saya membagi data yang saya miliki menjadi beberapa set terpisah untuk pelatihan dan pengujian (sekitar 80/20). Kemudian saya secara acak mengambil sampel data pelatihan dengan tangan untuk mendapatkan data pelatihan dalam proporsi yang berbeda dari 19: 1; dari 2: 1 -> 16: 1.
Saya kemudian melatih regresi logistik pada subset data pelatihan yang berbeda ini dan memplot recall (= TP / (TP + FN)) sebagai fungsi dari proporsi pelatihan yang berbeda. Tentu saja, penarikan dihitung pada sampel TEST terputus-putus yang memiliki proporsi teramati 19: 1. Perhatikan, meskipun saya melatih model yang berbeda pada data pelatihan yang berbeda, saya menghitung penarikan kembali untuk semuanya pada data pengujian (terputus-putus) yang sama.
Hasilnya seperti yang diharapkan: penarikan kembali sekitar 60% pada proporsi pelatihan 2: 1 dan jatuh agak cepat pada saat mencapai 16: 1. Ada beberapa proporsi 2: 1 -> 6: 1 di mana penarikan cukup di atas 5%.
Percobaan Kedua: Pencarian Grid
Selanjutnya, saya ingin menguji parameter regularisasi yang berbeda, jadi saya menggunakan GridSearchCV dan membuat kisi dari beberapa nilai C
parameter serta class_weight
parameter. Untuk menerjemahkan proporsi n: m saya dari sampel pelatihan negatif: positif ke dalam kamus bahasa class_weight
saya pikir saya hanya menentukan beberapa kamus sebagai berikut:
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
dan saya juga termasuk None
dan auto
.
Kali ini hasilnya benar-benar aneh. Semua penarikan saya keluar kecil (<0,05) untuk setiap nilai class_weight
kecuali auto
. Jadi saya hanya bisa berasumsi bahwa pemahaman saya tentang cara mengatur class_weight
kamus itu salah. Menariknya, class_weight
nilai 'auto' dalam pencarian grid sekitar 59% untuk semua nilai C
, dan saya kira itu seimbang dengan 1: 1?
Pertanyaan saya
Bagaimana Anda menggunakan dengan benar
class_weight
untuk mencapai keseimbangan yang berbeda dalam data pelatihan dari apa yang sebenarnya Anda berikan? Secara khusus, kamus apa yang saya berikanclass_weight
untuk menggunakan proporsi n: m sampel pelatihan negatif: positif?Jika Anda meneruskan berbagai
class_weight
kamus ke GridSearchCV, selama validasi silang akankah itu menyeimbangkan kembali data lipatan pelatihan menurut kamus tetapi menggunakan proporsi sampel yang diberikan secara benar untuk menghitung fungsi penilaian saya pada lipatan tes? Ini penting karena metrik apa pun hanya berguna bagi saya jika berasal dari data dalam proporsi yang diamati.Apa
auto
nilaiclass_weight
do sejauh proporsi? Saya membaca dokumentasinya dan saya berasumsi "menyeimbangkan data berbanding terbalik dengan frekuensinya" berarti menjadikannya 1: 1. Apakah ini benar? Jika tidak, dapatkah seseorang menjelaskan?
sumber
Jawaban:
Pertama, mungkin tidak baik untuk hanya mengingat saja. Anda dapat dengan mudah mencapai perolehan kembali 100% dengan mengklasifikasikan semuanya sebagai kelas positif. Saya biasanya menyarankan menggunakan AUC untuk memilih parameter, dan kemudian menemukan ambang untuk titik operasi (katakanlah tingkat presisi tertentu) yang Anda minati.
Untuk cara
class_weight
kerjanya: Ini menghukum kesalahan dalam sampelclass[i]
denganclass_weight[i]
daripada 1. Jadi bobot kelas yang lebih tinggi berarti Anda ingin lebih menekankan pada kelas. Dari apa yang Anda katakan tampaknya kelas 0 19 kali lebih sering daripada kelas 1. Jadi Anda harus meningkatkanclass_weight
kelas 1 relatif terhadap kelas 0, katakan {0: .1, 1: .9}. Jikaclass_weight
tidak berjumlah 1, itu pada dasarnya akan mengubah parameter regularisasi.Untuk cara
class_weight="auto"
kerjanya, Anda bisa melihat pembahasan ini . Dalam versi dev, Anda dapat menggunakanclass_weight="balanced"
, yang lebih mudah dipahami: ini pada dasarnya berarti mereplikasi kelas yang lebih kecil hingga Anda memiliki sampel sebanyak di kelas yang lebih besar, tetapi secara implisit.sumber
Jawaban pertama bagus untuk memahami cara kerjanya. Tetapi saya ingin memahami bagaimana saya harus menggunakannya dalam praktik.
RINGKASAN
class_weight="balanced"
berfungsi dengan baik jika Anda tidak ingin mengoptimalkan secara manualclass_weight="balanced"
Anda menangkap lebih banyak peristiwa sebenarnya (ingatan TRUE lebih tinggi) tetapi juga Anda lebih cenderung mendapatkan peringatan palsu (presisi TRUE lebih rendah)NB
Hasilnya mungkin berbeda saat menggunakan RF atau GBM. sklearn tidak memiliki
class_weight="balanced"
GBM tetapi lightgbm memilikiLGBMClassifier(is_unbalance=False)
KODE
sumber