Tingkatkan klasifikasi dengan banyak variabel kategori

37

Saya sedang mengerjakan dataset dengan 200.000+ sampel dan sekitar 50 fitur per sampel: 10 variabel kontinu dan yang lainnya ~ 40 adalah variabel kategori (negara, bahasa, bidang ilmiah, dll.). Untuk variabel kategori ini, misalnya Anda memiliki 150 negara yang berbeda, 50 bahasa, 50 bidang ilmiah dll ...

Sejauh ini pendekatan saya adalah:

  1. Untuk setiap variabel kategori dengan banyak nilai yang memungkinkan, ambil hanya satu yang memiliki lebih dari 10.000 sampel yang mengambil nilai ini. Ini berkurang menjadi 5-10 kategori, bukan 150.

  2. Bangun variabel dummy untuk masing-masing kategori (jika 10 negara maka untuk setiap sampel tambahkan vektor biner ukuran 10).

  3. Feed a classifier hutan acak (lintas-validasi parameter dll ...) dengan data ini.

Saat ini dengan pendekatan ini, saya hanya berhasil mendapatkan akurasi 65% dan saya merasa lebih banyak yang bisa dilakukan. Terutama saya tidak puas dengan 1 saya) karena saya merasa saya seharusnya tidak boleh secara sewenang-wenang menghapus "nilai yang paling relevan" sesuai dengan jumlah sampel yang mereka miliki, karena nilai yang kurang terwakili ini bisa lebih diskriminatif. Di sisi lain, RAM saya tidak mampu menambahkan 500 kolom * 200000 baris ke data dengan menjaga semua nilai yang mungkin.

Apakah Anda punya saran untuk mengatasi banyak variabel kategori ini?

Bertrand R
sumber
2
Jika Anda masih tertarik, Anda mungkin ingin memeriksa jawaban saya tentang pengurangan dimensi dan jawaban saya tentang klasifikasi hierarkis .
Aleksandr Blekh
1
Ketika Anda mengatakan "membangun variabel dummy untuk masing-masing kategori" , sepertinya Anda menggunakan Python bukan R? R randomforest secara asli dapat menangani kategorikal, juga pengurangan memori secara konsekuensial. Coba R.
smci
Lihat juga stats.stackexchange.com/questions/146907/…
kjetil b halvorsen

Jawaban:

20

1) Hutan acak seharusnya dapat menangani nilai kategorikal secara asli sehingga mencari implementasi yang berbeda sehingga Anda tidak perlu menyandikan semua fitur itu dan menggunakan semua memori Anda.

2) Masalah dengan fitur kategori kardinalitas tinggi adalah bahwa hal itu mudah untuk cocok dengannya. Anda mungkin memiliki cukup data sehingga ini bukan masalah tetapi hati-hati.

3) Saya menyarankan melihat pemilihan fitur berbasis hutan acak menggunakan metode yang diusulkan Brieman atau kontras buatan . Metode kontras buatan (ACE) menarik karena membandingkan pentingnya fitur dengan pentingnya versi yang dikocok sendiri yang melawan beberapa masalah kardinalitas tinggi. Ada sebuah makalah baru "Modul Hutan Beruntun Modul" yang mungkin menarik jika Anda memiliki lebih banyak fitur karena menggunakan metode pemilihan fitur yang menyadari kelompok fitur yang sangat berkorelasi.

4) Opsi lain yang kadang-kadang digunakan adalah untuk mengubah algoritma sehingga menggunakan kotak case keluar untuk melakukan pemilihan fitur akhir setelah mencocokkan splits pada case bag yang terkadang membantu melawan overfitting.

Ada implementasi ace yang hampir lengkap di sini dan saya memiliki lebih banyak memori / implementasi rf cepat yang menangani variabel kategoris secara asli di sini ... opsi -evaloob mendukung opsi 4 Saya sedang bekerja untuk menambahkan dukungan untuk ACE dan beberapa rf lainnya metode pemilihan fitur berdasarkan tetapi belum dilakukan.

Ryan Bressler
sumber
4
Semua saran ini menarik, saya setuju bahwa hutan acak harus menangani variabel kategori asli, tetapi scikit-belajar tidak ... Saya pikir itu salah satu kelemahan utama scikit btw. Saya akan mencoba kode Anda pada data saya untuk melihat apa yang terjadi, dan saya akan melihat saran Anda yang lain!
Bertrand R
1
Cobalah implementasi R. Menjalankannya adalah satu liner. Membaca data sangat mudah dan ada implementasi paralell baru yang sangat cepat dan efisien memori: r-bloggers.com/... Di sisi lain. Apakah kelas Anda tidak seimbang? dalam implementasi r Anda dapat menumbuhkan setiap pohon dari sampel bootstrap seimbang sampsize = c (x, x). Ini telah menghasilkan klasifikasi biner yang lebih baik untuk saya. Anda dapat bermain-main dengan ukuran dan menyesuaikan klasifikasi dengan sangat mudah menggunakan OOB confusion matrix R outputs.
JEquihua
2
Implementasi randomForest R memungkinkan faktor dengan maksimum 32 level. scikit-learn tidak terlalu membatasi, asalkan Anda terlebih dahulu membuat variabel dummy (lihat pandas.get_dummiesfungsinya). Implementasi hutan acak H2O telah bekerja sangat baik untuk saya (lihat 0xdata.com/docs/master/model/rf ).
Alex Woolford
1
ada implementasi hutan acak yang lebih baru dan lebih cepat, paket ini disebut ranger. Benar-benar hebat. Pesanan besarnya lebih cepat dan tidak memiliki batas level 32.
marbel
6

Alih-alih mengumum kategori Anda, mengapa Anda tidak hanya menggunakan variabel numerik tunggal untuk masing-masing? Dalam konteks hutan acak, saya sering bertanya-tanya tentang konsekuensi melakukan hal itu (karena saya setuju bahwa terdengar mencurigakan untuk memperkenalkan tata cara dalam data kategorikal yang jika sering tidak masuk akal), tetapi dalam praktiknya (setidaknya dalam praktiknya) dengan implementasi scikit-learning dari RF yang saya gunakan), saya sering mengamati bahwa itu tidak membuat perbedaan pada hasil (saya tidak yakin mengapa).

cjauvin
sumber
1
Ini bagus untuk fitur kategorikal dengan n <= 3 karena Anda dapat menghasilkan semua pemisahan yang sama seperti yang Anda lakukan dengan mempertimbangkan fitur tersebut secara native sebagai kategorikal. Untuk n yang lebih besar adalah mungkin untuk mencapai serangkaian pemisahan yang setara dengan pemisahan kategorikal tetapi algoritme mungkin atau mungkin tidak menemukannya seefisien ... namun jika Anda membagi fitur menjadi n fitur numerik Anda juga mengurangi efisiensi yang dengannya algoritma dapat menemukan perpecahan. Seseorang perlu menambahkan dukungan variabel kategoris ke dalam implementasi scikit-learning karena itu sangat bagus.
Ryan Bressler
Saya setuju dengan Anda ketika Anda mengatakan bahwa kedengarannya mencurigakan untuk memperkenalkan ordinalitas dalam data kategorikal ... Saya lebih suka tidak harus melakukannya, tapi setidaknya saya bisa mencobanya dan melihat apa yang terjadi!
Bertrand R
4
Saya telah berdiskusi panjang tentang pertanyaan ini di milis sklearn (Anda dapat membaca bagiannya di sini: mail-archive.com/[email protected]/… ). Pendapat salah satu pelaksana adalah bahwa dengan pohon-pohon yang cukup dalam, fitur kategori yang dikodekan-ordinal mungkin bekerja dengan cukup baik (selain lebih efisien secara komputasi). Ngomong-ngomong, jika Anda mencobanya, saya akan sangat tertarik untuk mendengar tentang hasil / kesimpulan Anda, karena ini adalah masalah yang terus saya bahas.
cjauvin
1
Jadi saya mencoba untuk menjaga satu variabel numerik tunggal untuk yang kategorikal, dan ini benar-benar bekerja dengan sangat baik, dan jauh lebih baik daripada menambahkan sejumlah besar entri biner ... Saya juga mencoba mengurutkan nilai-nilai sesuai dengan rata-rata nilai rata-rata mereka pada target . Dan itu juga berfungsi dengan baik
Bertrand R
Saya tidak terkejut dengan hal itu sebenarnya .. ini sejalan dengan apa yang saya amati dalam beberapa pengaturan yang berbeda, walaupun dilihat dari jumlah upvote, ini adalah ide yang agak berlawanan dengan intuisi.
cjauvin
5

Saya pikir Anda harus mempertimbangkan / lebih teknik reduksi variabel . Ini menghilangkan prediksi yang tidak begitu berpengaruh.

Saya telah membaca banyak hal tentang pra-pemrosesan data dan ini merupakan solusi yang bagus untuk mengurangi n ° variabel Anda.

Saran saya adalah sebagai berikut:

  • untuk variabel kualitatif , ganti nilai yang hilang dengan kategori "hilang". Ini bisa menimbulkan bias jika data tidak hilang secara acak, tetapi setidaknya Anda akan memiliki semua pengamatan Anda utuh dan hilangnya mungkin mengungkapkan perilaku yang berbeda.
  • menghilangkan prediktor varians nol atau prediktor varians mendekati nol (berhati-hatilah untuk tidak menghilangkan variabel dummy dengan kategori tidak seimbang tinggi yang dapat memisahkan Y Anda secara efisien. Buat beberapa grafik untuk variabel yang menurut Anda mungkin penting). Di R, Anda dapat menggunakan 'nzv'fungsi dari 'caret'paket. Ini akan sangat mengurangi dimensi data Anda.
  • menghilangkan prediktor yang berkorelasi . Gunakan matriks korelasi Kendall karena lebih cocok untuk dibangun di hadapan variabel kategori. Kelemahannya adalah Anda harus mengubah semua vars nominal Anda menjadi kategoris.
  • ada metode pemilihan fitur yang akan mengurangi jumlah mereka lebih banyak (pengelompokan - Anda memilih satu perwakilan dari setiap klaster, regresi LASSO, dll ...). Saya belum sempat mengujinya karena langkah-langkah lain mengurangi variabel saya menjadi di bawah 100.

Juga, saya akan menyarankan menggunakan algoritma AdaBoost bukan RF. Secara pribadi, penelitian yang saya lakukan memberi saya koefisien Gini yang sangat mirip untuk kedua metode ini. Bagian yang baik tentang AdaBoost adalah bahwa di R, ia menangani pengamatan yang hilang. Jadi, Anda dapat melewati langkah pertama dari daftar ini

Saya harap itu sedikit membantu. Semoga berhasil

lorelai
sumber
4

Anda mungkin ingin mempertimbangkan model efek campuran. Mereka populer dalam ilmu sosial karena kinerjanya pada data kategori kardinalitas tinggi, dan saya telah menggunakannya untuk membuat model prediksi yang hebat mengungguli pendekatan pembelajaran mesin yang populer seperti pohon yang didorong oleh gradien, hutan acak, dan regresi logistik yang diatur elastis-net yang diatur. Implementasi yang paling terkenal adalah paket lme4 R; fungsi yang Anda gunakan untuk klasifikasi adalah glmer, yang mengimplementasikan regresi logistik efek campuran. Anda mungkin memiliki masalah dengan penskalaan ke dataset Anda, tetapi saya telah melakukan baris 80k dengan 15 fitur tanpa terlalu banyak kesulitan.

Paul
sumber
2
  1. Ketika Anda mengatakan "membangun variabel dummy untuk masing-masing kategori" , sepertinya Anda menggunakan Python bukan R? R randomforest secara asli dapat menangani kategorikal, juga pengurangan memori secara konsekuensial. Coba r.

  2. Selanjutnya, Anda tidak perlu memangkas / menggabungkan level kategori secara manual, yang terdengar seperti rasa sakit yang hebat. Dan bahkan jika Anda melakukannya, Anda tidak dijamin bahwa kategori terpadat adalah yang paling prediktif. Mengontrol kerumitan hutan acak dengan parameter nodesize : mulai dengan nodesize besar , dan kurangi secara bertahap (ini adalah pencarian hyperparameter).

  3. Seleksi variabel akan berguna. @lorelai memberikan rekomendasi yang bagus. Cobalah untuk menghilangkan fitur yang tidak berguna (penting rendah atau berkorelasi tinggi). Konstruksi pohon kuadratik dengan sejumlah fitur, jadi jika Anda menghilangkan sepertiga, ia akan membayar dividen.

smci
sumber
0

Anda harus melihat pada paket H2O.ai. Ini menangani variabel kategori keluar dari kotak tanpa harus melakukan pengkodean (pastikan variabel adalah faktor).

Saya terutama menyukai penerapan Gradient Boosted Machine (GBM) karena Anda kemudian dapat melihat pentingnya variabel setelah membangun model. GBM juga memiliki fitur bagus yang tahan terhadap overfitting.

Jika Anda ingin menjelajahi model lain, mereka memiliki: GLM, Random Forest, Naif Bayes, Deep Learning, dll.

Lihat: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/gbm.html

Ini juga mudah untuk menginstal (Windows, Linux, Mac) dan mudah dijalankan dengan API menggunakan R, Python, Java, dan Scala.

Ini dapat menggunakan banyak core untuk mempercepat.

Dalam waktu dekat, mereka akan mendukung GPU.

Ini juga open source dan gratis (Ada dukungan Enterprise).

Clem Wang
sumber