Penjelasan klasik dari word2vec sebagai arsitektur Skip-gram sampel negatif dalam artikel ilmiah asli dan posting blog yang tak terhitung jumlahnya terlihat seperti ini:
while(1) { 1. vf = vector of focus word 2. vc = vector of focus word 3. train such that (vc . vf = 1) 4. for(0 <= i <= negative samples): vneg = vector of word *not* in context train such that (vf . vneg = 0) }
Memang, jika Anda google [word2vec skipgram], apa yang kita lihat:
Tetapi semua implementasi ini salah .
Implementasi asli word2vec di C bekerja secara berbeda dan secara
fundamental berbeda dari ini. Mereka yang secara profesional menerapkan sistem dengan embeddings kata dari word2vec melakukan salah satu dari yang berikut:
- Langsung menyebut implementasi asli C.
- Gunakan implementasi
gensim
, yang ditransliterasikan dari sumber C sejauh nama-nama variabel cocok.
Memang,
gensim
adalah
satu -
satunya implementasi C yang benar yang saya tahu .
Implementasi C
Implementasi C sebenarnya mendukung
dua vektor untuk setiap kata . Satu vektor untuk kata dalam fokus, dan yang kedua untuk kata dalam konteks. (Tampaknya familier? Benar, pengembang GloVe meminjam ide dari word2vec tanpa menyebutkan fakta ini!)
Implementasi dalam kode C sangat kompeten:
Mengapa inisialisasi acak dan nol?
Sekali lagi, karena ini tidak dijelaskan sama sekali dalam artikel asli
dan di mana saja di Internet , saya hanya bisa berspekulasi.
Hipotesisnya adalah ketika sampel negatif berasal dari keseluruhan teks dan tidak diperhitungkan berdasarkan frekuensi, Anda dapat memilih
kata apa saja , dan paling sering kata yang
vektornya tidak dilatih sama sekali . Jika vektor ini memiliki makna, maka secara acak akan menggeser kata yang sangat penting menjadi fokus.
Intinya adalah untuk mengatur semua contoh negatif menjadi nol, sehingga
hanya vektor yang muncul lebih atau kurang sering akan mempengaruhi penyajian vektor lain.
Ini sebenarnya cukup rumit, dan saya tidak pernah memikirkan betapa pentingnya strategi inisialisasi.
Kenapa saya menulis ini
Saya menghabiskan dua bulan hidup saya mencoba mereproduksi word2vec seperti yang dijelaskan dalam publikasi ilmiah asli dan banyak artikel di Internet, tetapi gagal. Saya tidak dapat mencapai hasil yang sama dengan word2vec, meskipun saya mencoba yang terbaik.
Saya tidak dapat membayangkan bahwa para penulis publikasi secara harfiah membuat sebuah algoritma yang tidak berfungsi, sementara implementasinya melakukan sesuatu yang sangat berbeda.
Pada akhirnya, saya memutuskan untuk mempelajari sumbernya. Selama tiga hari saya yakin bahwa saya salah mengerti kode, karena secara harfiah semua orang di Internet berbicara tentang implementasi yang berbeda.
Saya tidak tahu mengapa publikasi asli dan artikel di Internet tidak mengatakan apa-apa tentang mekanisme
sebenarnya dari word2vec, jadi saya memutuskan untuk mempublikasikan informasi ini sendiri.
Ini juga menjelaskan pilihan radikal GloVe untuk mengatur vektor terpisah untuk konteks negatif - mereka hanya melakukan apa yang dilakukan word2vec, tetapi memberi tahu orang-orang tentang hal itu :).
Apakah ini trik ilmiah? Saya tidak tahu, pertanyaan yang sulit. Tapi jujur ββsaja, saya sangat marah. Mungkin, saya tidak akan pernah lagi dapat menganggap serius penjelasan algoritma dalam pembelajaran mesin: lain kali saya akan
segera melihat sumbernya.