Saya sedang mengerjakan masalah analisis sentimen, datanya terlihat seperti ini:
label instances
5 1190
4 838
3 239
1 204
2 127
Jadi data saya tidak seimbang sejak 1190 instances
diberi label 5
. Untuk klasifikasi saya menggunakan SVC scikit . Masalahnya adalah saya tidak tahu bagaimana menyeimbangkan data saya dengan cara yang benar untuk menghitung secara akurat presisi, perolehan, akurasi, dan skor f1 untuk casing multikelas. Jadi saya mencoba pendekatan berikut:
Pertama:
wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
wclf.fit(X, y)
weighted_prediction = wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)
Kedua:
auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)
print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Recall:', recall_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, auto_weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)
Ketiga:
clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)
from sklearn.metrics import precision_score, \
recall_score, confusion_matrix, classification_report, \
accuracy_score, f1_score
print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)
F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
0.930416613529
Namun, saya mendapatkan peringatan seperti ini:
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with
multiclass or multilabel data or pos_label=None will result in an
exception. Please set an explicit value for `average`, one of (None,
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for
instance, scoring="f1_weighted" instead of scoring="f1"
Bagaimana saya bisa menangani dengan benar data saya yang tidak seimbang untuk menghitung dengan cara yang benar metrik pengklasifikasi?
python
machine-learning
nlp
artificial-intelligence
scikit-learn
new_with_python
sumber
sumber
average
parameter dalam kasus ketiga?Jawaban:
Saya pikir ada banyak kebingungan tentang bobot mana yang digunakan untuk apa. Saya tidak yakin saya tahu persis apa yang mengganggu Anda jadi saya akan membahas topik yang berbeda, bersabarlah;).
Bobot kelas
Bobot dari
class_weight
parameter digunakan untuk melatih pengklasifikasi . Mereka tidak digunakan dalam penghitungan metrik mana pun yang Anda gunakan : dengan bobot kelas yang berbeda, angkanya akan berbeda hanya karena pengklasifikasi berbeda.Pada dasarnya di setiap pengklasifikasi scikit-learn, bobot kelas digunakan untuk memberi tahu model Anda betapa pentingnya sebuah kelas. Artinya, selama pelatihan, pengklasifikasi akan melakukan upaya ekstra untuk mengklasifikasikan kelas dengan bobot tinggi dengan benar.
Cara mereka melakukannya tergantung pada algoritme. Jika Anda menginginkan detail tentang cara kerjanya untuk SVC dan dokumen tersebut tidak masuk akal bagi Anda, silakan sebutkan.
Metriknya
Setelah Anda memiliki pengklasifikasi, Anda ingin mengetahui seberapa baik kinerjanya. Di sini Anda dapat menggunakan metrik yang Anda sebutkan:
accuracy
,recall_score
,f1_score
...Biasanya ketika distribusi kelas tidak seimbang, akurasi dianggap sebagai pilihan yang buruk karena memberikan skor tinggi untuk model yang hanya memprediksi kelas yang paling sering.
Saya tidak akan merinci semua metrik ini tetapi perhatikan bahwa, dengan pengecualian
accuracy
, metrik tersebut secara alami diterapkan di tingkat kelas: seperti yang Anda lihat diprint
laporan klasifikasi ini, metrik tersebut ditentukan untuk setiap kelas. Mereka mengandalkan konsep sepertitrue positives
ataufalse negative
yang membutuhkan definisi kelas mana yang positif .Peringatan
Anda mendapatkan peringatan ini karena Anda menggunakan skor f1, recall, dan presisi tanpa menentukan cara penghitungannya! Pertanyaannya dapat diubah: dari laporan klasifikasi di atas, bagaimana Anda mengeluarkan satu angka global untuk f1-score? Anda bisa:
avg / total
hasil di atas. Ini juga disebut makro rata-rata.'weighted'
dalam scikit-learn akan menimbang skor f1 dengan dukungan kelas: semakin banyak elemen yang dimiliki kelas, semakin penting skor f1 untuk kelas ini dalam penghitungan.Ini adalah 3 opsi di scikit-learn, ada peringatan yang mengatakan Anda harus memilih satu . Jadi, Anda harus menentukan
average
argumen untuk metode skor.Yang mana yang Anda pilih tergantung bagaimana Anda ingin mengukur kinerja pengklasifikasi: misalnya, rata-rata makro tidak memperhitungkan ketidakseimbangan kelas dan skor f1 kelas 1 akan sama pentingnya dengan skor kelas f1 5. Namun, jika Anda menggunakan rata-rata tertimbang, Anda akan menjadi lebih penting untuk kelas 5.
Seluruh spesifikasi argumen dalam metrik ini tidak terlalu jelas di scikit-learn sekarang, itu akan menjadi lebih baik di versi 0.18 menurut dokumen. Mereka menghapus beberapa perilaku standar yang tidak jelas dan mereka mengeluarkan peringatan sehingga pengembang menyadarinya.
Menghitung skor
Hal terakhir yang ingin saya sebutkan (jangan ragu untuk melewatinya jika Anda menyadarinya) adalah bahwa skor hanya berarti jika dihitung pada data yang belum pernah dilihat oleh pengklasifikasi . Ini sangat penting karena skor apa pun yang Anda peroleh pada data yang digunakan untuk menyesuaikan pengklasifikasi sama sekali tidak relevan.
Berikut adalah cara untuk melakukannya dengan menggunakan
StratifiedShuffleSplit
, yang memberi Anda pemisahan data secara acak (setelah pengacakan) yang mempertahankan distribusi label.Semoga ini membantu.
sumber
class_weight={1:10}
artinya data yang memiliki 3 kelas?ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.
. Ini berfungsi dengan baik dengan train-test split tetapi adakah yang bisa membantu saya mengapa saya menerima kesalahan ini dengan SSS? Terima kasih.Banyak jawaban yang sangat rinci di sini tetapi saya rasa Anda tidak menjawab pertanyaan yang tepat. Saat saya memahami pertanyaannya, ada dua masalah:
1.
Anda dapat menggunakan sebagian besar fungsi penilaian di scikit-learn dengan masalah multikelas dan masalah kelas tunggal. Ex.:
Dengan cara ini Anda akan mendapatkan angka yang nyata dan dapat ditafsirkan untuk masing-masing kelas.
Kemudian...
2.
... Anda dapat mengetahui apakah data yang tidak seimbang bahkan menjadi masalah. Jika skor untuk kelas yang kurang terwakili (kelas 1 dan 2) lebih rendah daripada kelas dengan sampel pelatihan lebih banyak (kelas 4 dan 5) maka Anda tahu bahwa data yang tidak seimbang sebenarnya merupakan masalah, dan Anda dapat bertindak sesuai dengan itu, seperti dijelaskan dalam beberapa jawaban lain di utas ini. Namun, jika distribusi kelas yang sama ada dalam data yang ingin Anda prediksi, data pelatihan Anda yang tidak seimbang adalah perwakilan yang baik dari data tersebut, dan karenanya, ketidakseimbangan adalah hal yang baik.
sumber
precision_recall_fscore_support
? Apakah label dicetak berdasarkan pesanan?average=None
dan tentukan label, lalu Anda mendapatkan metrik yang Anda cari, untuk setiap label yang Anda tentukan.Pertanyaan yang diajukan
Menanggapi pertanyaan 'metrik apa yang harus digunakan untuk klasifikasi kelas jamak dengan data tidak seimbang': Pengukuran makro-F1. Macro Precision dan Macro Recall juga dapat digunakan, tetapi tidak mudah diinterpretasikan seperti untuk klasifikasi biner, keduanya sudah dimasukkan ke dalam F-measure, dan kelebihan metrik mempersulit perbandingan metode, penyetelan parameter, dan sebagainya.
Micro averaging sensitif terhadap ketidakseimbangan kelas: jika metode Anda, misalnya, berfungsi baik untuk label yang paling umum dan benar-benar mengacaukan label lain, metrik micro-rata-rata menunjukkan hasil yang baik.
Pembobotan rata-rata tidak cocok untuk data yang tidak seimbang, karena menimbang menurut jumlah label. Selain itu, ini terlalu sulit untuk ditafsirkan dan tidak populer: misalnya, tidak disebutkan rata-rata seperti itu dalam survei yang sangat rinci berikut, saya sangat menyarankan untuk melihat-lihat:
Pertanyaan khusus aplikasi
Namun, kembali ke tugas Anda, saya akan meneliti 2 topik:
Metrik yang umum digunakan. Seperti yang dapat saya simpulkan setelah melihat literatur, ada 2 metrik evaluasi utama:
( tautan ) - perhatikan bahwa penulis bekerja dengan distribusi peringkat yang hampir sama, lihat Gambar 5.
( tautan )
( tautan ) - mereka mengeksplorasi akurasi dan MSE, menganggap yang terakhir lebih baik
( link ) - mereka menggunakan scikit-learn untuk evaluasi dan pendekatan baseline dan menyatakan bahwa kode mereka tersedia; namun, saya tidak dapat menemukannya, jadi jika Anda membutuhkannya, tulis surat kepada penulis, pekerjaan ini cukup baru dan sepertinya ditulis dengan Python.
Biaya kesalahan yang berbeda . Jika Anda lebih peduli untuk menghindari kesalahan besar, misalnya menilai ulasan 1 bintang hingga 5 bintang atau semacamnya, lihat MSE; jika perbedaan itu penting, tetapi tidak terlalu banyak, coba MAE, karena tidak mengkuadratkan diff; jika tidak tetap dengan Akurasi.
Tentang pendekatan, bukan metrik
Coba pendekatan regresi, misalnya SVR , karena umumnya mengungguli pengklasifikasi Multikelas seperti SVC atau OVA SVM.
sumber
Pertama-tama, sedikit lebih sulit menggunakan analisis penghitungan untuk mengetahui apakah data Anda tidak seimbang atau tidak. Misal: 1 dari 1000 observasi positif hanyalah noise, error atau terobosan dalam ilmu? Kau tak pernah tahu.
Jadi selalu lebih baik untuk menggunakan semua pengetahuan yang tersedia dan memilih statusnya dengan bijak.
Oke, bagaimana jika benar-benar tidak seimbang?
Sekali lagi - lihat data Anda. Terkadang Anda dapat menemukan satu atau dua observasi dikalikan ratusan kali. Terkadang berguna untuk membuat observasi satu kelas palsu ini.
Jika semua data bersih, langkah selanjutnya adalah menggunakan bobot kelas dalam model prediksi.
Jadi bagaimana dengan metrik multikelas?
Menurut pengalaman saya, tidak ada metrik Anda yang biasanya digunakan. Ada dua alasan utama.
Pertama: bekerja dengan probabilitas selalu lebih baik daripada dengan prediksi yang solid (karena bagaimana lagi Anda bisa memisahkan model dengan prediksi 0,9 dan 0,6 jika keduanya memberikan kelas yang sama?)
Dan kedua: jauh lebih mudah untuk membandingkan model prediksi Anda dan membuat model baru yang hanya bergantung pada satu metrik yang baik.
Dari pengalaman saya, saya dapat merekomendasikan logloss atau MSE (atau hanya berarti kesalahan kuadrat).
Bagaimana cara memperbaiki peringatan sklearn?
Cukup (seperti yang diperhatikan yangjie) timpa
average
parameter dengan salah satu nilai berikut:'micro'
(hitung metrik secara global),'macro'
(hitung metrik untuk setiap label) atau'weighted'
(sama seperti makro tetapi dengan bobot otomatis).Semua Peringatan Anda muncul setelah memanggil fungsi metrik dengan
average
nilai default'binary'
yang tidak sesuai untuk prediksi multikelas.Semoga beruntung dan bersenang-senanglah dengan pembelajaran mesin!
Edit:
Saya menemukan rekomendasi penjawab lain untuk beralih ke pendekatan regresi (misalnya SVR) yang tidak saya setujui. Sejauh yang saya ingat, tidak ada yang namanya regresi multikelas. Ya, ada regresi multilabel yang jauh berbeda dan ya itu mungkin dalam beberapa kasus beralih antara regresi dan klasifikasi (jika kelas entah bagaimana diurutkan) tetapi cukup jarang.
Apa yang akan saya rekomendasikan (dalam lingkup scikit-learn) adalah mencoba alat klasifikasi lain yang sangat kuat: peningkatan gradien , hutan acak (favorit saya), KNeighbours dan banyak lagi.
Setelah itu Anda dapat menghitung rata-rata aritmatika atau geometri antara prediksi dan sebagian besar waktu Anda akan mendapatkan hasil yang lebih baik.
sumber