Bag of Words (BoW)
Term Frequency-Inverse Document Frequency (TF-IDF)
Word Embeddings (Word2Vec, GloVe)
Sentence Embedding
อธิบายแนวคิดพื้นฐานของการแปลงข้อความเป็นตัวเลข
สร้าง BoW และ TF-IDF ด้วย Scikit-learn
อธิบายวิธีการทำงานของ Word Embeddings เช่น Word2Vec และ GloVe
ใช้ Word2Vec และ GloVe เพื่อสร้างเวกเตอร์ข้อความ
สร้าง Word2Vec ด้วยจากคลังข้อความ และนำไปใช้งาน
สร้าง Sentence Embedding โดยใช้เทคนิคต่างๆ
เป็นขั้นตอนสำคัญในการสร้างโมเดล Machine Learning และ Deep Learning ในงาน NLP เนื่องจากทั้งสองโมเดลไม่สามารถประมวลผลข้อความในรูปแบบตัวอักษร (raw text) ได้โดยตรง จำเป็นต้องแปลงข้อความให้อยู่ในรูปแบบตัวเลข (numeric representation) เพื่อให้โมเดลเข้าใจคำหรือข้อความ และนำไปประมวลผลต่อได้
แปลงข้อมูลที่มนุษย์เข้าใจได้ให้เป็นข้อมูลที่คอมพิวเตอร์เข้าใจได้
การแปลงข้อความเป็นตัวเลขช่วยให้โมเดลสามารถทำความเข้าใจคำ ข้อความ หรือเอกสารในรูปแบบที่เหมาะสมสำหรับการคำนวณ
ดึงความหมายหรือบริบทของข้อความมาใช้
เทคนิคการแปลงข้อมูล เช่น Word Embeddings ช่วยให้คอมพิวเตอร์สามารถหาความสัมพันธ์ระหว่างคำ เช่น คำที่มีความหมายคล้ายกัน และเข้าใจความหมายได้ในระดับที่ใกล้เคียงกับมนุษย์
ลดมิติของข้อมูล
การแปลงข้อความเป็นตัวเลขสามารถลดความซับซ้อนของข้อมูล โดยใช้เทคนิคที่เน้นเฉพาะคำสำคัญหรือบริบทที่สำคัญ
เป็นรากฐานสำหรับงาน NLP ที่ซับซ้อน
การแปลงข้อความเป็นตัวเลขเป็นขั้นตอนพื้นฐานสำหรับงาน NLP เช่น การวิเคราะห์ความรู้สึก การสรุปข้อความ และการแปลภาษา
วิธีการที่นิยมใช้แปลงข้อความเป็นตัวเลข
1. Bag of Words (BoW) เป็นสร้างเวกเตอร์จากการนับจำนวนครั้งของคำในเอกสาร เป็นวิธีการเรียบง่ายที่สุด เหมาะสำหรับงานง่าย เช่น การจัดประเภทข้อความ แต่ข้อเสียคือ ไม่สามารถจัดเก็บบริบทของคำได้ ทำให้ตีความหมายของคำได้แง่เดียว เช่น ไม่สามารถแยกความต่างระหว่างคำว่า "bank" ในประโยค "I deposited money in the bank" กับ "The bank of the river is steep"
2. TF-IDF ใช้แนวคิดคล้ายกับ BoW แต่มีการเพิ่มน้ำหนักคำที่สำคัญโดยใช้ค่า TF และลดน้ำหนักคำทั่วไปด้วยค่า IDF โดย TF (Term Frequency) คือ การคำนวณความถี่ของคำในเอกสาร และ IDF (Inverse Document Frequency) คือการคำนวณโดยลดน้ำหนักคำที่ปรากฏบ่อยในหลายเอกสาร เช่น "the", "is", "and"
3. Word Embeddings (เช่น Word2Vec, GloVe) ใช้เทคนิค Deep Learning เพื่อสร้างเวกเตอร์ที่เก็บความหมายเชิงบริบท ตัวอย่างเช่น คำว่า "king" - "man" + "woman" = "queen" เหมาะกับงานที่ต้องการความเข้าใจบริบท
ตัวอย่างขั้นตอนมีดังนี้ (กรณีที่ทำงานในระดับคำและประโยค)
ทำ text preprocessing (ถ้าจำเป็น) เช่น เปลี่ยนเป็นตัวพิมพ์เล็ก ตัดสัญลักษณ์พิเศษ ตัด stop word
ดึงคำที่ไม่ซ้ำกัน แล้วกำหนดหมายเลขให้แต่ละคำ ซึ่งเป็นที่มาของชื่อ bag of words นั่นเอง จากตัวอย่าง corpus text ในรูปจะได้ vocabulary เก็บอยู่ในรูปดิกชันนารีดังนี้ {'and': 0, 'document': 1, 'first': 2, 'is': 3, 'one': 4, 'second': 5, 'the': 6, 'third': 7, 'this': 8} เมื่อนำไปใช้ในการสร้างโมเดลจะเป็นจำนวน feature หรือ vocab size
แปลงคำในแต่ละประโยคเป็นชุดตัวเลข (vector) โดยค่าที่เก็บใน vector คือ ค่าความถี่ของแต่ละคำที่มีในดิกชันนารี (เรียงตามลำดับตัวเลขที่กำหนดในขั้นตอนที่ 2) หรือบางวิธีอาจจะเก็บเพียงค่า 1 หรือ 0 เพื่อแทนการระบุว่ามีหรือไม่มีก็ได้ จากตัวอย่างประโยคที่ 1 "This is the first document" เมื่อแปลงเป็น vector จะได้ [0 1 1 1 0 0 1 0 1] ความหมายของ vector นี้คือ ประโยคที่ 1 ประกอบด้วยคำว่า document, first, is, the, this อย่างละ 1 ครั้ง จะเห็นว่าการเปลี่ยนข้อความเป็นตัวเลขแบบนี้ จะรู้ว่าประโยคประกอบด้วยคำใดบ้าง และมีความถี่เท่าไหร่ แต่จะไม่ทราบตำแหน่งของคำเหล่านั้นในประโยค
การเขียนโปรแกรม
ใช้ CountVectorizer ใน Scikit-learn ในการนับจำนวนคำในเอกสาร โดยสร้าง object ของ CountVectorizer แล้วเรียกใช้ method fit แปลงคำให้เป็นตัวเลข และใช้ method transform แปลงข้อความให้อยู่ในรูป vector ที่เก็บความถี่ของคำ หรือจะทำทั้งสองขั้นตอนพร้อมกันโดยใช้ method fit_transform ก็ได้เช่นกัน
ศึกษา parameter และการใช้งานเพิ่มเติมได้จากคู่มือการใช้งาน API จากเว็บของ Scikit-learn
คล้ายกับวิธีการของ BoW แตกต่างกันที่จะเก็บค่า TF-IDF แทนค่าความถี่
สูตรคำนวณหาค่า TF-IDF
Term Frequency (TF) — จำนวนคำนั้นในประโยค
Inverse Document Frequency (IDF) — log (จำนวนประโยคทั้งหมด / จำนวนประโยคที่มีคำนั้น)
TF-IDF = TF * IDF
สูตรค่า TF และ IDF อาจจะมีแตกต่างจากนี้บ้าง ขึ้นอยู่กับว่ามีการทำ normalization หรือทำ smoothing
การเขียนโปรแกรม
แนะนำให้ใช้ TfidfVectorizer ใน Scikit-learn ในการหาค่า TF-IDF ของคำในเอกสาร โดยสร้าง object ของ TfidfVectorizer แล้วเรียกใช้ method fit แปลงคำให้เป็นตัวเลข และใช้ method transform แปลงข้อความให้อยู่ในรูป vector ที่เก็บความถี่ของคำ หรือจะทำทั้งสองขั้นตอนพร้อมกันโดยใช้ method fit_transform ก็ได้เช่นกัน โดยการแปลงคำให้เป็นตัวเลข และแปลงข้อความให้อยู่ในรูป vector ที่แสดงค่า TF-IDF ของคำ
ศึกษา parameter และการใช้งานเพิ่มเติมได้จากคู่มือการใช้งาน API จากเว็บของ Scikit-learn
จากตัวอย่างในรูปเป็นการหาค่า IDF โดยใช้สูตรการทำ smoothing (parameter smooth_idf=True เป็นค่า default) เพื่อแก้ปัญหาตัวหารหรือ log มีค่าเป็น 0 ใช้สูตรดังนี้
Inverse Document Frequency (IDF) — [log (1+จำนวนประโยคทั้งหมด / 1+จำนวนประโยคที่มีคำนั้น)] +1
สูตรหาค่า TF ที่มีการทำ normalization แบบ L1 (parameter norm = 'L1' ใน TfidfVectorizer)
Term Frequency (TF) — จำนวนคำนั้นในประโยค / จำนวนคำทั้งหมดในประโยค
L1 Normalized TF (t, d) = TF (t, d) / Σ TF(i, d)
สูตรหาค่า TF ที่มีการทำ normalization แบบ L2 (parameter norm = 'L2' ใน TfidfVectorizer เป็นค่า default)
Term Frequency (TF) — จำนวนคำนั้นในประโยค / sqrt(จำนวนคำทั้งหมดในประโยค^2)
L2 Normalized TF (t, d) = TF (t, d) / sqrt(Σ TF(i, d)^2)
การแปลงคำเป็นเวกเตอร์ที่เก็บความสัมพันธ์เชิงความหมาย ใช้ gensim เพื่อสร้างเวกเตอร์คำจากชุดข้อความ
อ่านเพิ่มเติมที่: https://jalammar.github.io/illustrated-word2vec/
Sentence Embeddings คือการแปลงข้อความ (sentence) ให้เป็นเวกเตอร์ในรูปแบบที่สามารถนำไปใช้งานได้ในเชิงคณิตศาสตร์ โดยสามารถเก็บความหมายของประโยคโดยรวม (semantic meaning) ได้ เหมาะสำหรับการนำไปใช้งานเปรียบเทียบความคล้ายคลึง (semantic similarity) การค้นคืนข้อมูล (Information Retrieval) และการจัดกลุ่มเอกสาร (Document Clustering)
เทคนิคการทำ Sentence Embedding ที่นิยมในปัจจุบัน
Averaging Word Embeddings: ใช้ Word Embeddings (เช่น Word2Vec, GloVe) ของแต่ละคำในประโยค แล้วนำค่าเฉลี่ยของเวกเตอร์มาเป็นตัวแทนประโยค วิธีนี้พัฒนาง่าย แต่ข้อเสีย คือ การขาดบริบทระหว่างคำ
Universal Sentence Encoder (USE): โมเดลที่พัฒนาโดย Google ใช้ Deep Neural Networks เพื่อเรียนรู้ Sentence Embeddings พัฒนาได้ง่ายโดยใช้ TensorFlow Hub และ Hugging Face โดยที่ embeding ของ 16 ภาษานั้นจะอยู่ใน Vector Space เดียวกัน นั่นคือเป็นลักษณะ multilingual ทำให้สามารถหาความเหมือนของประโยคข้ามภาษากันได้ (อ่านเพิ่มเติมที่นี่)
Sentence-BERT (SBERT): พัฒนาต่อจาก BERT โดยปรับให้รองรับการใช้งาน Sentence Pair Tasks เช่น Semantic Textual Similarity มีข้อดีคือรวดเร็วและมีประสิทธิภาพสูงในงานเปรียบเทียบข้อความ