สวัสดีครับผู้อ่านทุกท่าน เนื้อหาส่วนใหญ่จะมาจาก วิดีโอ tech talk เรื่อง Word2Vec ของพี่อาร์ม, blog post ของ the morning paper, และ Course NLP ใน Cousera ใครสนใจอ่านและดูแบบฉบับเต็ม ผมได้แปะลิ้งไว้ด้านล่างบทความแล้วนะครับ ถ้าพร้อมแล้วก็ ไปอ่านกันเล้ย!
แต่หากใครยังไม่รู้จัก Word2Vec ไปอ่านกันก่อนได้ที่
สำหรับภาษาไทย ลองใช้ Thai2Vec ดูครับ
Outline
- Language Modeling
- Word2Vec ทำอย่างไร
ไอเดียของการหาค่า vector แต่ละคำเนี่ยมันเริ่มมาจาก language modeling
Language Modeling
Language modeling คือการหาค่าทางสถิติหรือความเป็นไปได้ของการเกิดของข้อความในภาษา ยกตัวอย่างเช่น
Chain rule
เนื่องจาก 1 ประโยค(w) เกิดจาก คำ หลายๆ คำ (w1, w2, w3, …, wk)
เมื่อเราใช้ chain rule ก็จะได้ว่า
จะเห็นว่า ถ้าเราคำนวณแบบนี้ term สุดท้าย ต้องคิดจากคำ context ก่อนหน้าทั้งหมด เราสามารถคิดความน่าจะเป็นจะเป็นจากการนับได้ไหม?
- ปัญหาคือ ต้องนับเยอะมาก เพราะถ้าฐานข้อมูลมีข้อมูลเยอะ เราต้องคำนวณ context ก่อนหน้าทั้งหมด ของแต่ละคำ
- และเราจะไม่มีข้อมูลมากพอในการประมาณค่าได้เลย เพราะว่า term สุดท้าย ต้องคำนวณคำจาก context ก่อนหน้าทั้งหมด
แล้วมันสามารถใช้วิธีอื่นได้ไหม? คำตอบคือได้ครับ นั่นคือการใช้ Markov assumption
Markov assumption
Markov assumption คือการดูแค่ n คำก่อนหน้า มันเลยเกิดเป็น n-gram model
N-Gram model
แล้วเราควรจะใช้กี่ n-gram ละ ซึ่งถ้าใช้ n เยอะๆเป็น 5, 6-gram บางทีมันก็ดี แต่บางทีก็หาไม่เจอในฐานข้อมูลเลยทำยังไงดี ก็เลยมีการนำ Backoff method มาใช้ โดยมันจะค่อย ๆ ลดจำนวน n ลงจนหาค่าได้ เช่นอาจจะเริ่มที่ 5-gram แล้วลดลงเหลือ 4-gram, 3-gram ไปเรื่อย ๆ แต่การลด n ลงยังเดียวมันใช้ไม่ได้ มันจำเป็นต้องใช้เทคนิค interpolation เข้ามาช่วยเพื่อจัดการกับพวก zero counts
จากการทดลองเค้าพบว่าใช้แค่ bigram ก็พอแล้ว
ไอเดียการหาค่าของ vector แต่ละคำมันมีแค่นี้ มันคือการดูว่าคำที่เราสนใจ มี probability ของคำนั้น เมื่อมี context นั้นๆ เท่าไหร่ ซึ่งมันเกิดขึ้นมานานแล้ว และมีหลายวิธีที่ทำได้อยู่แล้วเช่น Latent Semantic Analysis หรือ PMI แต่มันช้า และ word2vec เร็วกว่ามาก ยังไงตามไปดูกันครับ
อ่านเพิ่มเติมที่ Language modelling
Word2Vec ทำอย่างไร
ไอเดียที่ว่ามานี้มันมีปัญหาอยู่ 3 อย่าง
- Coverage: คำที่เกิดขึ้นร่วมกัน อาจจะไม่ได้เกิดจากคำที่อยู่ที่ติดกันก็ได้
- Space: ยกตัวอย่างเช่น ภาษาอังกฤษ มีคำมากกว่า 700k+ คำ เราจะต้องคำนวณ vector ที่มีขนาด 700k x 700k เลยนะ
- Speed: แล้วในเมื่อขนาดมันใหญ่ขนาดนี้ ตอนคำนวณจะไม่นานมากเลยหรอ
และปัญหาที่ว่ามานี้คือสาเหตุที่ทำให้เกิด Word2Vec ครับ เกิดขึ้นมาเพื่อแก้ปัญหาเหล่านี้
Coverage
สามารถแก้ไขด้วยการใช้โมเดล Word embedding ที่ชื่อว่า CBOW(Continuous Bag-of-Words) และ Skip-Gram
ซึ่งทั้งโมเดล CBOW และโมเดล Skip-Gram สามารถใช้ Neural Network สร้างขึ้นมาได้ดังนี้ครับ
โดยมี input เป็น one-hot encoding ของ context และมี output เป็น softmax ของ one-hot ของ next word
CBOW(Continuous Bag-of-Words)
ถ้าเราจะทำ CBOW เราก็แก้เปลี่ยน input จาก one-hot เป็น 1/C โดยที่ C คือจำนวน context size ที่เราจะใช้ เช่น ถ้า context size เราต้องการดู 4 คำ ค่าของ context แต่ละคำก็จะเป็น 1/4 = 0.25 แทนที่จะเป็น 1
Skip-Gram
ถ้าจะทำ Skip-Gram เราก็เปลี่ยน output เป็น 1 หลายคำแทนที่จะเป็นคำเดียว
นำไปใช้
แล้วเราจะนำ Word Vector ที่เทรนเสร็จแล้วไปใช้ยังไงล่ะ วิธีนำไปใช้ก็คือ ตัด output layer ออกครับ
ใช้ 2 layer แรก (input, hidden) เป็น embedding layer แล้วนำ layer อื่น ๆ มาต่อได้เลย
Performance optimization
เราสามารถใช้เทคนิคต่อไปนี้ทำให้มันตอนเทรน word vector เร็วขึ้นได้ครับ ส่วนรายละเอียดจะมาว่ากันในบทความต่อ ๆ ไปนะครับ เนื่องจากยาวมากแล้ว
- Branching factorization (Hierarchical Softmax)
- Negative sampling
- Frequent word subsampling
- Mini-Batch
- Dropout
Summary
- Word2Vec เกิดขึ้นมาเพื่อแก้ปัญหา 3 อย่าง (Coverage, Space, Speed) ที่มีในวิธีแบบเดิม (Latent semantic analysis, Point-wise mutual information)
- Coverage สามารถแก้ไขด้วย CBOW(Continuous Bag-of-Words) และ Skip-Gram model
- CBOW — ใช้ context หลายคำเพื่อหา next word 1 คำ
- Skip-Gram — ใช้ Context 1 คำ เพื่อหา next word หลายคำ
- CBOW และ Skip-Gram สามารถสร้างได้ด้วย Neural network 3 layer
- เมื่อเทรนแล้ว สามารถตัด output layer ออก เพื่อนำไปใช้เป็น embedding layer แล้วต่อกับ layer อื่น สำหรับงานประเภทต่าง ๆ
- Performance optimization ทำได้หลายวิธี เช่น Branching factorization, negative sampling, frequent word subsamping, mini-batch, dropout
หากใครสนใจเรื่อง Natural Language Processing ภาษาไทยก็เข้ามาพูดคุยแลกเปลี่ยนความรู้กันได้ที่ Thai NLP นะครับ แล้วพบกันใหม่บทความหน้า สวัสดีครับ :D