ปรับปรุง Chatbot: เพิ่มความสามารถในการเข้าใจเจตนาของผู้ใช้ (Intent Recognition)
ในบทที่แล้ว เราได้สร้าง Chatbot ที่สามารถตอบคำถามเกี่ยวกับสภาพอากาศได้ โดยใช้เทคนิค Keyword Matching ซึ่งเป็นวิธีที่ง่ายและตรงไปตรงมา แต่มีข้อจำกัดคือ Chatbot จะตอบได้เฉพาะคำถามที่มีคำหลักตรงกับที่กำหนดไว้เท่านั้น ถ้าผู้ใช้ถามด้วยประโยคที่แตกต่างออกไป Chatbot อาจไม่เข้าใจเจตนาและไม่สามารถให้คำตอบที่ถูกต้องได้
ในบทนี้ เราจะมาปรับปรุง Chatbot ของเราให้มีความสามารถในการเข้าใจเจตนา (Intent Recognition) ของผู้ใช้ได้ดีขึ้น โดยใช้เทคนิคการเรียนรู้ของเครื่อง (Machine Learning) อย่างง่าย ซึ่งจะช่วยให้ Chatbot สามารถตอบคำถามได้หลากหลายรูปแบบมากขึ้น แม้ว่าผู้ใช้จะไม่ได้ใช้คำหลักที่ตรงกับที่กำหนดไว้
ทำไมต้อง Intent Recognition?
ลองพิจารณาคำถามเหล่านี้:
- "วันนี้อากาศเป็นยังไงบ้าง"
- "วันนี้ฝนจะตกไหม"
- "ช่วยบอกสภาพอากาศวันนี้หน่อย"
- "อากาศวันนี้"
ถึงแม้ว่าคำถามเหล่านี้จะใช้คำที่แตกต่างกัน แต่ทั้งหมดมีเจตนาเดียวกันคือต้องการทราบสภาพอากาศวันนี้ Chatbot ที่ใช้ Keyword Matching อาจต้องมีกฎสำหรับแต่ละคำถาม ซึ่งเป็นเรื่องที่ยุ่งยากและไม่สามารถครอบคลุมทุกรูปแบบที่เป็นไปได้
Intent Recognition ช่วยให้เราสามารถระบุเจตนาของผู้ใช้ (เช่น ต้องการทราบสภาพอากาศ) จากประโยคที่ผู้ใช้พิมพ์เข้ามา โดยไม่จำเป็นต้องพึ่งพาการจับคู่คำหลักแบบตรงไปตรงมา ทำให้ Chatbot มีความยืดหยุ่นและสามารถเข้าใจภาษาที่เป็นธรรมชาติมากขึ้น
ขั้นตอนการสร้าง Intent Recognition
การสร้างระบบ Intent Recognition โดยทั่วไปประกอบด้วยขั้นตอนหลักๆ ดังนี้:
- การเก็บรวบรวมข้อมูลตัวอย่าง: รวบรวมประโยคตัวอย่างที่แสดงถึงเจตนาต่างๆ ที่ Chatbot ของเราต้องการรองรับ
- การเตรียมข้อมูล: ทำความสะอาดและแปลงข้อมูลตัวอย่างให้เป็นรูปแบบที่เหมาะสมสำหรับใช้ในการฝึกโมเดล
- การฝึกโมเดล: ใช้ข้อมูลที่เตรียมไว้เพื่อฝึกโมเดล Machine Learning ให้สามารถจำแนกเจตนาจากประโยคที่ผู้ใช้พิมพ์เข้ามา
- การประเมินผลโมเดล: ทดสอบประสิทธิภาพของโมเดลโดยใช้ข้อมูลที่ไม่เคยใช้ในการฝึก
- การผสานรวมโมเดลเข้ากับ Chatbot: นำโมเดลที่ฝึกเสร็จแล้วไปใช้งานใน Chatbot เพื่อให้สามารถเข้าใจเจตนาของผู้ใช้และให้คำตอบที่เหมาะสม
1. การเก็บรวบรวมข้อมูลตัวอย่างเจตนาของผู้ใช้
ขั้นตอนแรกคือการเก็บรวบรวมข้อมูลตัวอย่างประโยคที่แสดงถึงเจตนาต่างๆ ที่ Chatbot ของเราต้องการรองรับ ในกรณีนี้ เราจะเน้นที่เจตนาเกี่ยวกับการถามสภาพอากาศ ตัวอย่างเช่น:
weather_intents = {
"ask_weather": [
"วันนี้อากาศเป็นยังไงบ้าง",
"วันนี้ฝนจะตกไหม",
"ช่วยบอกสภาพอากาศวันนี้หน่อย",
"อากาศวันนี้",
"พรุ่งนี้อากาศจะเป็นยังไง",
"อากาศวันพรุ่งนี้",
"สภาพอากาศตอนนี้",
"ฝนจะตกเมื่อไหร่",
"วันนี้ร้อนไหม",
"วันนี้หนาวไหม"
],
"greet": [
"สวัสดี",
"หวัดดี",
"Hi",
"Hello",
"ดีจ้า",
"สบายดีไหม",
"เป็นไงบ้าง"
],
"thank": [
"ขอบคุณ",
"ขอบใจ",
"Thank you",
"Thanks",
"ขอบคุณมาก",
"ขอบคุณครับ",
"ขอบคุณค่ะ"
]
}
ในตัวอย่างนี้ เราได้กำหนดเจตนา 3 แบบคือ ask_weather (ถามสภาพอากาศ), greet (ทักทาย) และ thank (ขอบคุณ) แต่ละเจตนาจะมีรายการของประโยคตัวอย่างที่แสดงถึงเจตน่านั้นๆ
เหตุผลเชิงออกแบบ: การมีข้อมูลตัวอย่างที่หลากหลายและครอบคลุมเป็นสิ่งสำคัญในการฝึกโมเดล Machine Learning ที่มีประสิทธิภาพ จำนวนข้อมูลตัวอย่างที่มากขึ้นจะช่วยให้โมเดลสามารถเรียนรู้รูปแบบของภาษาและเข้าใจเจตนาของผู้ใช้ได้ดีขึ้น
2. การเตรียมข้อมูล
ก่อนที่จะนำข้อมูลตัวอย่างไปใช้ในการฝึกโมเดล เราจำเป็นต้องเตรียมข้อมูลให้อยู่ในรูปแบบที่เหมาะสม ซึ่งโดยทั่วไปแล้วจะเกี่ยวข้องกับการทำความสะอาดข้อมูลและการแปลงข้อมูลให้เป็นตัวเลข (Numerical Representation)
ในกรณีนี้ เราจะใช้เทคนิค Bag-of-Words (BoW) ซึ่งเป็นวิธีที่ง่ายและได้รับความนิยมในการแปลงข้อความเป็นตัวเลข โดย BoW จะสร้างเวกเตอร์ (Vector) ที่แสดงถึงความถี่ของแต่ละคำในประโยค ตัวอย่างเช่น ถ้าเรามีคำศัพท์ทั้งหมด 5 คำคือ "วันนี้", "อากาศ", "เป็น", "ยังไง", "บ้าง" ประโยค "วันนี้อากาศเป็นยังไงบ้าง" จะถูกแปลงเป็นเวกเตอร์ [1, 1, 1, 1, 1] (แต่ละตำแหน่งในเวกเตอร์แทนจำนวนครั้งที่คำศัพท์นั้นปรากฏในประโยค)
from sklearn.feature_extraction.text import CountVectorizer
sentences = []
labels = []
for intent, examples in weather_intents.items():
for example in examples:
sentences.append(example)
labels.append(intent)
vectorizer = CountVectorizer()
vectorizer.fit(sentences)
X = vectorizer.transform(sentences)
y = labels
print(X.shape) # แสดงขนาดของข้อมูล (จำนวนประโยค, จำนวนคำศัพท์)
print(y) # แสดงรายการเจตนา
โค้ดนี้จะสร้าง CountVectorizer ซึ่งเป็นเครื่องมือสำหรับแปลงข้อความเป็นเวกเตอร์ BoW จากนั้นจะแปลงประโยคทั้งหมดใน weather_intents เป็นเวกเตอร์ BoW และเก็บไว้ในตัวแปร X ส่วน y จะเก็บรายการเจตนาที่สอดคล้องกับแต่ละประโยค
เหตุผลเชิงออกแบบ: การใช้ BoW เป็น trade-off ระหว่างความง่ายในการใช้งานและความแม่นยำ BoW ไม่คำนึงถึงลำดับของคำในประโยค ซึ่งอาจส่งผลต่อความแม่นยำในการจำแนกเจตนา แต่ก็เป็นวิธีที่รวดเร็วและง่ายต่อการเข้าใจ สำหรับผู้เริ่มต้น
3. การฝึกโมเดล Machine Learning
เมื่อเรามีข้อมูลที่อยู่ในรูปแบบที่เหมาะสมแล้ว เราสามารถฝึกโมเดล Machine Learning เพื่อจำแนกเจตนาได้ ในที่นี้ เราจะใช้โมเดล Logistic Regression ซึ่งเป็นโมเดลที่ง่ายและมีประสิทธิภาพสำหรับการจำแนกประเภท (Classification)
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# แบ่งข้อมูลเป็นส่วนสำหรับฝึก (train) และทดสอบ (test)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# สร้างและฝึกโมเดล Logistic Regression
model = LogisticRegression()
model.fit(X_train, y_train)
# ประเมินผลโมเดล
accuracy = model.score(X_test, y_test)
print(f"Accuracy: {accuracy}")
โค้ดนี้จะแบ่งข้อมูลออกเป็นสองส่วนคือ ส่วนสำหรับฝึก (80%) และส่วนสำหรับทดสอบ (20%) จากนั้นจะสร้างโมเดล Logistic Regression และฝึกโมเดลโดยใช้ข้อมูลส่วนที่ใช้ฝึก สุดท้ายจะประเมินผลโมเดลโดยใช้ข้อมูลส่วนที่ใช้ทดสอบ และแสดงค่าความถูกต้อง (Accuracy)
เหตุผลเชิงออกแบบ: การแบ่งข้อมูลออกเป็นส่วนสำหรับฝึกและทดสอบเป็นแนวปฏิบัติที่ดีในการประเมินประสิทธิภาพของโมเดล โดยข้อมูลส่วนที่ใช้ทดสอบจะไม่ถูกใช้ในการฝึกโมเดล เพื่อให้เราสามารถวัดประสิทธิภาพของโมเดลในการทำนายข้อมูลที่ไม่เคยเห็นมาก่อนได้อย่างแม่นยำ
4. การผสานรวมโมเดลเข้ากับ Chatbot
เมื่อเราได้โมเดลที่ฝึกเสร็จแล้ว เราสามารถนำโมเดลไปผสานรวมเข้ากับ Chatbot ของเราได้ โดยเมื่อผู้ใช้พิมพ์ข้อความเข้ามา เราจะแปลงข้อความนั้นเป็นเวกเตอร์ BoW แล้วใช้โมเดลเพื่อทำนายเจตนา จากนั้นเราจะให้ Chatbot ตอบสนองตามเจตนาที่ทำนายได้
def get_response(user_input):
user_input_vector = vectorizer.transform([user_input])
intent = model.predict(user_input_vector)[0]
if intent == "ask_weather":
return "วันนี้อากาศดีมากครับ/ค่ะ" # แทนที่ด้วยการดึงข้อมูลสภาพอากาศจริง
elif intent == "greet":
return "สวัสดีครับ/ค่ะ ยินดีที่ได้คุยกับคุณ"
elif intent == "thank":
return "ด้วยความยินดีครับ/ค่ะ"
else:
return "ขออภัย ฉันไม่เข้าใจคำถามของคุณ"
# ตัวอย่างการใช้งาน
user_input = "วันนี้อากาศเป็นยังไงบ้าง"
response = get_response(user_input)
print(response)
โค้ดนี้จะสร้างฟังก์ชัน get_response ซึ่งรับข้อความที่ผู้ใช้พิมพ์เข้ามาเป็นอินพุต จากนั้นจะแปลงข้อความนั้นเป็นเวกเตอร์ BoW และใช้โมเดลเพื่อทำนายเจตนา สุดท้ายจะคืนค่าข้อความตอบกลับที่เหมาะสมตามเจตนาที่ทำนายได้
ข้อควรระวัง: ตัวอย่างนี้เป็นเพียงการสาธิตแนวคิด Intent Recognition อย่างง่าย ในการใช้งานจริง เราอาจต้องใช้เทคนิคที่ซับซ้อนกว่านี้ เช่น การใช้ Word Embeddings แทน BoW เพื่อให้โมเดลสามารถเข้าใจความหมายของคำได้ดีขึ้น หรือการใช้โมเดล Deep Learning เช่น Recurrent Neural Networks (RNNs) หรือ Transformers เพื่อให้สามารถจับใจความและเข้าใจบริบทของประโยคได้ดียิ่งขึ้น
สรุป
ในบทนี้ เราได้เรียนรู้วิธีการเพิ่มความสามารถในการเข้าใจเจตนาของผู้ใช้ให้กับ Chatbot ของเรา โดยใช้เทคนิคการเรียนรู้ของเครื่องอย่างง่าย ซึ่งจะช่วยให้ Chatbot สามารถตอบคำถามได้หลากหลายรูปแบบมากขึ้น แม้ว่าผู้ใช้จะไม่ได้ใช้คำหลักที่ตรงกับที่กำหนดไว้ การนำเทคนิค Intent Recognition ไปใช้จะช่วยให้ Chatbot ของเรามีความฉลาดและเป็นประโยชน์มากยิ่งขึ้น