Saya agak baru dalam hal ini dan tidak bisa mengatakan saya memiliki pemahaman yang lengkap tentang konsep-konsep teoritis di balik ini. Saya mencoba untuk menghitung KL Divergence antara beberapa daftar poin dengan Python. Saya menggunakan http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html untuk mencoba dan melakukan ini. Masalah yang saya hadapi adalah bahwa nilai yang dikembalikan sama untuk setiap 2 daftar angka (1,3862943611198906). Saya merasa bahwa saya membuat semacam kesalahan teoretis di sini tetapi tidak dapat menemukannya.
values1 = [1.346112,1.337432,1.246655]
values2 = [1.033836,1.082015,1.117323]
metrics.mutual_info_score(values1,values2)
Itu adalah contoh dari apa yang saya jalankan - hanya saja saya mendapatkan output yang sama untuk 2 input. Setiap saran / bantuan akan dihargai!
python
clustering
scikit-learn
Nanda
sumber
sumber
sklearn.metrics.mutual_info_score([1.346112,1.337432,1.246655], [1.033836,1.082015,1.117323])
, saya mendapatkan nilai1.0986122886681096
.Jawaban:
Pertama-tama,
sklearn.metrics.mutual_info_score
mengimplementasikan informasi timbal balik untuk mengevaluasi hasil pengelompokan, bukan perbedaan murni Kullback-Leibler!Divergensi KL (dan ukuran lain apa pun) mengharapkan data input memiliki jumlah 1 . Kalau tidak, mereka bukan distribusi probabilitas yang tepat . Jika data Anda tidak memiliki jumlah 1, kemungkinan besar biasanya tidak tepat untuk menggunakan perbedaan KL! (Dalam beberapa kasus, dapat diterima untuk memiliki jumlah kurang dari 1, misalnya dalam kasus data yang hilang.)
Perhatikan juga bahwa umum untuk menggunakan logaritma basis 2. Ini hanya menghasilkan faktor penskalaan konstan dalam perbedaan, tetapi logaritma basis 2 lebih mudah untuk diinterpretasikan dan memiliki skala yang lebih intuitif (0 ke 1 bukannya 0 ke log2 = 0,69314 ..., mengukur informasi dalam bit alih-alih nats).
seperti yang bisa kita lihat dengan jelas, hasil MI dari sklearn diskalakan menggunakan logaritma natural, bukan log2. Ini adalah pilihan yang tidak menguntungkan, seperti dijelaskan di atas.
Sayangnya, perbedaan Kullback-Leibler rapuh. Pada contoh di atas tidak terdefinisi dengan baik:
KL([0,1],[1,0])
menyebabkan pembagian dengan nol, dan cenderung tak hingga. Ini juga asimetris .sumber
scipy.stats.entropy
digunakan, itu akan menormalkan probabilitas menjadi satu. Dari dokumen ( scipy.github.io/devdocs/generated/scipy.stats.entropy.html ): "Rutin ini akan menormalkan pk dan qk jika mereka tidak berjumlah 1."Fungsi entropi Scipy akan menghitung divergensi KL jika memberi makan dua vektor p dan q, masing-masing mewakili distribusi probabilitas. Jika kedua vektor bukan pdf, maka akan dinormalisasi terlebih dahulu.
Informasi timbal balik terkait, tetapi tidak sama dengan KL Divergence.
"Informasi timbal balik tertimbang ini adalah bentuk KL-Divergence tertimbang, yang diketahui mengambil nilai negatif untuk beberapa input, dan ada contoh di mana informasi timbal balik tertimbang juga mengambil nilai negatif"
sumber
Saya tidak yakin dengan implementasi ScikitLearn, tetapi berikut ini adalah implementasi cepat dari divergence KL dengan Python:
Keluaran:
0.775279624079
Mungkin ada konflik implementasi di beberapa perpustakaan, jadi pastikan Anda membaca dokumen mereka sebelum menggunakan.
sumber
0.775279624079
untuk input Anda dan metrik sklearn kembali1.3862943611198906
. Masih bingung! Tapi, sepertinya memasukkan cek nilai tersebut sesuai dengan qn, ke dalam skrip harus dilakukan :)Trik ini menghindari kode kondisional dan karenanya dapat memberikan kinerja yang lebih baik.
sumber
Pertimbangkan tiga sampel berikut dari suatu distribusi.
Jelas, nilai1 dan nilai2 lebih dekat, jadi kami berharap ukuran
surprise
atau entropi, lebih rendah jika dibandingkan dengan nilai3.Kami melihat output berikut:
Kami melihat ini masuk akal karena nilai antara nilai1 dan nilai3 dan nilai 2 dan nilai 3 hanya lebih drastis dalam perubahan daripada nilai1 ke nilai 2. Ini adalah validasi saya untuk memahami KL-D dan paket yang dapat dimanfaatkan untuk itu.
sumber