Machine Learning เบื้องต้น: มาลองทำ Sentiment Analysis กัน!
Disclaimer: บทความนี้เขียนขึ้นโดยไอเดียว่าผู้อ่านไม่มีความรู้เรื่อง ML มากนัก รูปแบบการใช้งาน ML การเตรียมชุดข้อมูลในบทความนี้เลยจะขอทำให้เรียบง่ายมากที่สุดเท่าที่จะเป็นไปได้เพื่อที่ผู้อ่านจะสามารถเข้าใจได้มากขึ้น บางส่วนของวิธีการที่ซับซ้อนมากเกินไปผู้เขียนเลยจะขอข้ามไปบ้าง
ถ้าพูดถึงงานในด้าน Machine Learning อีกงานที่สำคัญมากๆงานนึงคือการที่เกี่ยวข้องกันกับภาษาครับ หรือเรียกอีกอย่างว่า Natural Language Processing (NLP)
การวิเคราะห์อะไรก็ตามที่เป็นภาษาเขียนของมนุษย์ ซึ่งแน่นอนว่ามันเป็น field ของงานที่ได้รับความสนใจมากในปัจจุบัน และสามารถนำไปประยุกต์ใช้กับอะไรได้หลายๆอย่าง
อย่างเช่นการ Detect ข่าวปลอมของ Facebook, การ Detect Spam ในกล่องอีเมลล์ของ Gmail, Hotmail
ในวันนี้เราจะมาพูดถึงการนำเอา ML ไปประยุกต์ใช้ในงานด้านนึงของ NLP ที่นิยมใช้เพื่อฝึกหัดกันตอนที่เริ่มเรียนรู้ ML ใหม่ๆ
งานๆนั้นก็คืองานที่เรียกว่า Sentiment Analysis ครับ
Sentiment Analysis คืออะไร?
ในชีวิตประจำวันเรามักจะสื่อสารกับคนอื่นๆเป็นประจำอยู่แล้วใช่มั้ยครับ ไม่ว่าจะออกจากบ้านเดินไปซื้อตั๋วรถไฟ แสดงบัตรให้ยามหน้าลิฟท์ สั่งกับข้าวกินตอนเที่ยง เนื่องจากการสื่อสารเป็นสิ่งพื้นฐานในสังคมความเป็นอยู่ของมนุษย์
แน่นอนว่าการสื่อสารทั้งหมดสิ่งนึงที่สื่อออกมาในคำพูดแต่ละคำก็จะประกอบไปด้วยหลายๆสิ่งที่อยู่ในจิตใจเราขณะนั้นครับ ทั้งความต้องการ ความรู้สึกเชิงบวกเชิงลบ ข้อคิดเห็นอะไรต่างๆ
ทุกการสื่อสารของมนุษย์ทั้งคำพูดหรือข้อความทางอินเทอร์เน็ต มักมีองค์ประกอบเหล่านี้อยู่ด้วย โดยในงานประเภท Sentiment Analysis นี้สิ่งที่เราต้องการจะพูดถึง จะทราบถึงก็คืออารมณ์ครับ
ว่าง่ายๆก็คือสิ่งที่เราต้องการทราบก็คือ ข้อความที่เราได้รับนั้นมันมีความหมายไปในเชิงบวก หรือเชิงลบนั่นเอง
พวกคำหยาบ หรือคำด่าอะไรต่างๆนี่ก็จะไปอยู่ในประเภทเชิงลบ ส่วนคำที่ใช้ชื่นชม หรือความหมายดีๆก็จะไปอยู่ในประเภทเชิงบวกครับ
ข้อมูล
ก่อนอื่นเลยเรามาทำความรู้จักข้อมูลที่จะเอามาใช้งานกันก่อน สำหรับบทความนี้เลือกใช้ข้อมูล Twitter-Sentiment-Analysis จาก Kaggle ครับ
ซึ่งข้อมูลชุดนี้ก็จะเป็นข้อมูลของ tweets ต่างๆที่อยู่ในทวิตเตอร์ซึ่งเราไปดึงมา แล้วมีการแปะป้ายบอกไว้ว่า เออ คำไหนๆมีความหมายดี ความหมายไม่ดียังไง
สำหรับคนที่จะลองทำตาม tutorials ก็ลองไปโหลดมาเล่นดูตามลิงค์ข้างล่างได้ครับ
สำรวจข้อมูลดูกันหน่อย เนื่องจากบทความนี้มีไว้สำหรับผู้เริ่มต้น เราเลยจะมาสำรวจข้อมูลกันแบบหยาบๆก่อนครับ
ข้อมูลที่เราได้มาเนี่ยจะมีอยู่ 3 คอลัมนน์ คือ ItemID, Sentiment, SentimentText ซึ่งแต่ละอย่างก็จะมีความหมายดังนี้
ItemID = ID ของข้อมูลแต่ละตัว (ข้อความแต่ละข้อความ)
Sentiment = ความหมายดีหรือไม่ดี (ดี 1, ไม่ดี 0)
SentimentText = ข้อความ Tweet
ใครกดดูละเอียดอีกทีก็น่าจะเห็นครับว่าข้อมูลเราจะมีประมาณเกือบๆแสน record ซึ่งก็คือมีจำนวนเยอะมาก พอเหมาะที่จะเอาไปใช้สร้าง Sentiment Analyzer ของเราพอดีเลย
เริ่ม Code กันเลยดีกว่า!
สำหรับบทความนี้ผมจะขออนุญาติใช้ Google Colab ในการรันโค้ดต่างๆครับ ถ้าใครที่สะดวกใช้โปรแกรมอื่นอย่างเช่น Jupyter Notebook หรือ VS Code ก็ใช้งานได้ตามสะดวกครับ ไม่ได้มีปัญหาขัดข้ออะไร
จัดการกับข้อมูล
เริ่มต้นเลยจากการ import ข้อมูลที่จำเป็นต้องใช้เข้ามาก่อน (ก็คือ datasets ข้างบนที่เราพึ่งพูดถึงไป) โดยผมจะขอใช้ความช่วยเหลือจากเพื่อนรักของเราซึ่งก็คือเจ้าหลินปิงนั่นเองครับ !!
ล้อเล่นนะครับ (ฮา 😂)
สิ่งที่เราจะใช้มาช่วย import และจัดการกับข้อมูลของเราคือไลบรารีที่ชื่อว่า pandas
ถ้าใครยังไม่ได้ติดตั้ง pandas ก็ใช้คำสั่ง pip install pandas ก่อนนะครับ
- import pandas as pd คือการอิมพอร์ตไลบรารี pandas เข้ามาก่อน แล้วก็จะขอเรียกมันย่อๆว่า pd
- df = pd.read_csv(…) เป็นขั้นตอนที่ใช้อ่านไฟล์ข้อมูลของเราเข้ามาครับ … ก็ใส่เป็นที่อยู่ของไฟล์ datasets ของเรา (เลือกที่เป็นไฟล์ train นะครับ)
- df.head() เพื่อแสดงข้อมูลออกมาดูเบื้องต้น
หลังจากที่เราได้ข้อมูลเข้ามาในโปรแกรมเรียบร้อย ก็แยกประเภทตัวที่เป็น X, y ออกครับ โดย X ผมให้เป็น SentimentText ส่วน y เป็น Sentiment (ใรจำไม่ได้ว่าอะไรเป็นอะไรให้เลื่อนไปดูข้างบน)
ที่แยกเป็น X, y ก็เพื่อที่เราจะเอาไปเทรน model ของเราครับ ปกติแล้วเรามักจะให้ X เป็นข้อมูลที่ model รับเข้าไป แล้วจะคืนค่าเป็น y ออกมาคือค่าที่มันทำนายได้
แต่เนื่องจากว่าหลังจากเราแยกข้อมูลออกเป็น X, y แล้ว เราก็ยังไม่สามารถเอาข้อมูลไป train ML ได้อยู่ดี เนื่องมาจากว่าปกติแล้วโมเดล ML จะถูกออกแบบมาให้ทำงานกับข้อมูลที่อยู่ในรูปตัวเลข หรือไม่ก็รูปแบบที่เป็น vector ซึ่งคอมพิวเตอร์สามารถเอาไปคำนวณได้
แต่ข้อมูล X ของเรามันเป็นข้อความ! (ลอง print ออกมาดูได้ครับ) ซึ่งคอมพิวเตอร์มันไม่สามารถแปลความหมายได้ เราเลยจะต้องช่วยมันโดยการแปลงข้อมูลของเราให้ไปอยู่ในรูปที่มันจะเข้าใจได้ก่อนครับ
ในการแปลงข้อมูลนี้ผมจะขอใช้ตัวช่วยจาก scikit-learn ที่มีชื่อว่า CountVectorizer ศึ่งหน้าที่ที่มันทำคือลูป Text ของเราแล้วนับจำนวนแต่ละคำๆ เอาจำนวนของคำแต่ละคำนั้นไปสร้างเป็น Vector ซึ่งคอมพิวเตอร์สามารถแปลผลได้นั่นเอง
เริ่มสร้างโมเดลตัวแรก Naive Bayes Classifier
ในบทความนี้เราจะลองเลือกใช้ algorithm หลายๆตัวมาลองทำ Sentiment Analyzer กันนะครับ แล้วมาดูกันว่าตัวไหนทำงานได้ดีกว่าตัวไหน
ตัวแรกที่เราจะพูดถึงกันคือ Naive Bayes Classifier โดย algorithm ตัวนี้มี based มาจากทฤษฎีทางความน่าจะเป็นเรื่องทฤษฎีบทของ Bayes ครับ
เพราะฉะนั้นเดี๋ยวผมจะขอเริ่มอธิบายจากส่วนทฤษฎีก่อนแล้วกัน
ก่อนจะพูดถึงทฤษฎีบทของแบย์สต้องมีการกล่าวถึงความน่าจะเป็นแบบมีเงื่อนไขกันก่อน วิชาความน่าจะเป็นเบื้องต้นที่เราเรียนๆกันมาอาจจะไม่ได้มีเรื่องนี้อยู่ด้วย แต่ว่ามันเป็นอะไรที่น่าสนใจพอสมควรครับ
P(A|B) ถูกกำหนดให้เป็นความน่าจะเป็นที่จะเกิดเหตุการณ์ A ขึ้น ถ้าเกิดมีเหตุการณ์ B เกิดขึ้น ซึ่งจะสามารถคำนวนได้จาก ความน่าจะเป็นที่จะเกิดเหตุการณ์ A และ B พร้อมกัน หารกับความน่าจะเป็นที่จะเกิดเหตุการณ์ B
เข้าใจว่างง แต่ลองอ่านๆแล้วเท่าความเข้าใจช้าๆดูนะครับ
ความน่าจะเป็นแบบมีเงื่อนไข
เมื่อเราเข้าใจความน่าจะเป็นแบบมีเงื่อนไขแล้ว เราสามารถนำความน่าจะเป็นแบบมีเงื่อนไขมาขยายความหมายออกไปได้อีก
ทฤษฎีบทของแบย์ส ทำให้เราสามารถคำนวณความน่าจะเป็นที่จะเกิดเหตุการณ์นึง โดยอิงมาจากอีกเหตุการณ์นึงได้
ปกติแล้วเราจะใช้คำนวณหาความน่าจะเป็นของเหตุการณ์ที่เราวัดได้ยากครับ โดยเราจะคำนวณได้จากเหตุการณ์อีกเหตุการณ์ที่เกี่ยวข้องกันแทน
สำหรับใครที่อยากอ่านทฤษฎีโดยละเอียดสามารถเข้าไปอ่านที่นี่
มาลองเขียนโค้ดกันดีกว่า
เนือหาคณิตศาสตร์ข้างบนอาจจะฟังดูยุบยับซับซ้อนมาก แต่โค้ดทั้งหมดที่เราต้องเขียนมีเพียงแค่ 2 บรรทัดเท่านั้นครับ
- from sklearn.naive_bayes import MultinomialNB ขั้นตอนที่ก็จะ import สิ่งที่เราต้องการเข้ามาจาก sklearn ซึ่ง MultinomialNB นี้ก็คือตัวโมเดลที่เราสามารถเอาไป train เพื่อให้มันทำนายผลนู่นนี่นั่นได้ครับ
- model = MultinomialNB() ขั้นตอนนี้เราประกาศตัวแปรขึ้นมาเพื่อเลือกโมเดลที่เราต้องการที่จะใช้ก็คือ MultinomialNB นั่นเอง
- .fit() ทำหน้าที่ในการ train model ขึ้นมานั่นเองครับ โดยมันก็จะเอาค่า X, y ที่เราป้อนเข้าไป ไปทำการประมวลผลนู่นนี่นั่น จนได้ตัวโมเดล ML ออกมาให้เราเอาไปใช้ทำงานต่างๆที่เราต้องการได้
ลองเอาไปใช้งานดู
- ประกาศคำที่อยากเอาไปให้โมเดลของเรามันทายออกมา
- examples_vectorize คือการแปลงข้อมูลที่เราอยากเอาให้โมเดลมันทายให้อยู่ในรูปที่โมเดลมันเข้าใจ เพราะอย่าลืมนะครับว่าโมเดลของเรามันถูกออกแบบมาให้เข้าใจข้อมูลที่เป็นรูปแบบของตัวเลข
- y_pred คือตัวแปรที่ผมสร้างขึ้นมาเก็บผลลัพท์ที่โมเดลทำนายออกมาได้ครับ แต่การจะให้โมเดลทำนายอะไรก็ตาม syntax ที่เราใช้คือ .predict(…) โดยที่ … คือสิ่งที่เราต้องการให้มันทาย (อย่าลืมแปลงให้อยู่ในรูปที่มันเข้าใจได้ก่อน)
- เมื่อ print() ออกมาจะได้ [1, 0] ซึ่งแปลว่าประโยคแรกเป็นคำสุภาพ ส่วนประโยคที่ 2 เป็นคำหยาบครับ ซึ่งลองย้อนกลับไปดูว่าถูกมั้ยก็ได้ว่า น่าจะถูกนะครับ (😂)
แต่ๆๆ เราจะวัดประสิทธิภาพของ Model ยังไง?
หลังจากเราเทรนโมเดลเสร็จแล้ว ผมก็อยากจะขอบอกครับว่าผมวางยาทุกคนไว้ (วะฮะฮ่า!) 😏😏
ก่อนอื่นผมจะขอแนะนำให้รู้จักกับ concept นึงในการทำ ML ครับ ซึ่งจะสำคัญมากเลยทีเดียว สิ่งนั้นก็คือการทำ Train/Test นั่นเอง
ปกติแล้วเรามักจะทำการแบ่งชุดข้อมูลก่อนที่จะเอาข้อมูลชุดนั้นๆไป train อะไรๆก็ตามครับ โดยทั่วไปมักจะแบ่งออกเป็น 2 หรือ 3 ชุด (ผมจะขอแบ่งออกเป็น 2 ชุด) โดยแต่ละชุดจะทำหน้าที่ต่างกัน
- ชุดแรกจะตั้งชื่อ Train set ครับ ซึ่งข้อมูลชุดนี้ก็ตามชื่อเลย คือเอาไปสำหรับ train หรือสอนให้ Model มันทำงานอะไรซักอย่าง
- ชุดที่สองก็จะขอเรียกว่า Test Set ครับ โดยชุดนี้ก็จะเป็นเหมือนกับข้อสอบ ที่เอาไว้วัดผลประสิทธิภาพว่าโมเดลที่เอาไปเทรนแล้ว มันทำงานได้ดีขนาดไหน
เหตุผลที่ต้องแบ่งเป็น 2 ชุดผมจะขอยกตัวอย่างง่ายๆครับ ลองนึกว่าเราเป็นอาจารย์สอนเลข หรือภาษาไทย หรือภาษาอังกฤษ หรืออะไรก็ได้แล้วแต่เราเลย (ฮา 😂)
เราก็จะมีโจทย์ที่เอาไว้ใช้สอนนักเรียน แล้วก็เอาไว้ทำข้อสอบใช่มั้ยครับ โดยโจทย์ชุดที่เราเอาไว้ทำข้อสอยเนี่ยเราก็ต้องปิดเงียบ ห้ามเอาไปบอกคนอื่น เพราะถ้านักเรียนรู้นักเรียนก็ไปจำมาตอบได้ง่ายๆเลย
แนวทางในการสร้าง ML ก็จะคล้ายๆกันครับ สามารถอ่านเพิ่มเติมได้ที่
มาโค้ดกันต่อ
สำหรับขั้นตอนการแบ่งชุดข้อมูลผมก็จะขอใช้ความช่วยเหลือจาก scikit-learn อีกครั้ง โดยเราจะรันโค้ดตามข้างบนเลยครับ
จากนั้นเราก็จะได้ตัวแปร X_train, X_test, y_train, y_test มาเสร็จสรรพ ซึ่งตัวแปรเหล่านี้เราก็สามารถที่จะเอาไปใช้งานในการ train หรือ test ตามเราต้องการได้เลยโดยไม่ติดขัดอะไร
เมื่อเราลองสอนโมเดลเราใหม่แล้วโดยใช้ข้อมูลชุดที่แบ่ง train/test เรียบร้อยแล้ว ลองเอามารันดูก็จะได้ว่ายังได้ผลดีเหมือนเดิมครับ
มาลองให้เจ้าโมเดลของเรามันทำข้อสอบดีกว่า
หลังจากได้ชุดโมเดล กับชุดข้อมูลที่เป็นข้อสอบ (test set) ออกมาแล้ว ขั้นตอนต่อไปก็คือเราจะเอามาทดสอบกับตัวโมเดลของเราว่าทำงานได้ดีขนาดไหนครับ
เปรียบเทียบก็เหมือนกับให้มันทำข้อสอบนั่นแหละ เรามาดูดีกว่าว่าโมเดล Naive bayes ของเรามันจะทำข้อสอบถูกกี่ข้อกัน
วิธีการวัดความสามารถก็จะมีหลายวิธีครับ แต่เนื่องจากจุดประสงค์ว่าบทความนี้จะทำให้ง่ายสำหรับผู้เริ่มต้นผมเลยจะขอเลือกวิธีที่ง่ายที่สุดที่เรียกว่า Accuracy Metrics ครับ โดยสิ่งที่มันวัดก็คือ % ว่าตัวโมเดลมันทายถูกกี่ชุด(ข้อ) จากทั้งหมด
สามารถคำนวณได้ง่ายๆโดยการนำจำนวน sample ที่เอาไป test ที่ถูกต้องส่วนโดยจำนวน sample ที่เอาไป test ทั้งหมด (ถ้าแปลงเป็น % ก็เอาไปคูณ 100)
เราสามารถที่จะนำโค้ดไปทดสอบได้โดยการรันคำสั่งง่ายๆเท่านั้นครับ
จะได้ว่าเราได้ผลออกมาเป็น 0.7578…. หรือเป็นเปอร์เซนต์ก็คือประมาณ 75.78% ซึ่งถ้าเอาไปตัดเกรดก็จะได้ประมาณ B+ ครับ (😂) ซึ่งก็ถือได้ว่าได้ผลลัพท์ที่ดีพอสมควรเลยทีเดียว
ลองใช้ Model KNN (ทฤษฎี)
โมเดลต่อไปที่เราจะใช้ถือเป็นโมเดลตัวนึงที่มีความนิยมมากๆครับ เนื่องมาจากความง่ายในการสร้าง และความไม่ซับซ้อนของตัวมันทำให้มันกินพลังประมวลผลต่ำ โดยที่ยังได้ประสิทธิภาพที่พอรับได้
โมเดลที่ว่านี้มีชื่อว่า KNN หรือ K-Nearest Neighbour ครับ ซึ่งความหมายของมันคือ k-เพื่อนบ้านที่ใกล้ที่สุด
แล้วมันแปลว่าอะไร?
ก่อนอื่นเราจะต้องเลือกค่า K มาก่อนค่านึง ซึ่งค่า K ตัวนี้แหละครับที่เป็นส่วนประกอบหลักของโมเดล แนวคิดของ KNN จะคล้ายๆกันกับแนวคิดที่ใช้จำแนกประเภทอะไรซักอย่างโดยเทียบจากประเภทของข้อมูลที่อยู่ใกล้ๆกัน
ยกตัวอย่างเช่น สมมติบ้านของคุณอยู่ในย่านคนจีน บ้านเพื่อนบ้านเป็นคนจีนหมดเลย เพราะฉะนั้นเราจะตั้งสมมติฐานว่า โอเค คุณก็น่าจะเป็นคนจีนเหมือนกันเพราะว่าบ้านของคุณอยู่ในย่านคนจีน
โดยค่า K ที่เราเลือกมาก็จะเป็นจำนวนบ้านที่เราเลือกไปดู ถ้าสมมติผมเลือก K เป็น 10 เราก็ต้องไปดูบ้านข้างๆที่ใกล้ที่สุด 10 หลังว่าเป็นคนอะไรแล้วได้ว่าเป็นบ้านคนจีน 7 หลัง ฝรั่ง 3 หลัง เราก็จะเลือกอิงตามค่าที่มากที่สุดที่เราพบ
หรือถ้าเลือก K เป็นเท่าไรๆเราก็ไปดูที่ใกล้ที่สุดเป็นจำนวนเท่านั้นๆไปครับ
โดยลักษณะการทำงานของมันก็สามารถดูได้ตามภาพข้างบนได้
เรื่องต่อไปที่ต้องทำความเข้าใจคือ บ้านแต่ละบ้านห่างกันเป็นระยะทางเท่าไร เราจะสามารถหาได้อย่างไร? คำตอบก็คือเราจะใช้สูตรๆนึงในวิชาเรขาคณิตวิเคราะห์ก็คือสูตรการหาระยะห่างระหว่างจุดสองจุด (ซึ่งก็มีพื้นฐานมาจากทฤษฎีบทพีธากอรัส)
x, y ทำหน้าที่เป็นค่าของจุดแต่ละจุด
โดยเราจะใส่ sigma เข้าไปด้วย เนื่องจากว่าบ้านแต่ละหลังอาจจะมีลักษณะต่างกันมากกว่า 1 อย่าง เช่นพิกัด x-y, ค่า elevation, อื่นๆ
แน่นอนว่าการใช้วิธี KNN นี่เรามีความจำเป็นที่จะต้องคำนวณทุกจุดของข้อมูลที่เรามีเลย ดังนั้นการทำงานของ algorithm นี้ก็จะนานพอสมควรถ้าไปเทียบกับตัวอื่นๆ
ลองใช้ KNN (Code)
โอเคครับ ได้เวลาจบเรื่องทฤษฎี เรามาเริ่มต้นเขียนโค้ดกันดีกว่า
- เราเริ่มต้นด้วยการ import สิ่งที่เราต้องการมาจาก scikit-learn ก่อน สิ่งที่เราต้องการแน่นอนว่าคือตัวโมเดล KNeighborsClassifier ของเรานั่นแหละ
- เราสร้างตัวแปรขึ้นมาเพื่อเก็บค่า KNeighborsClassifier โดยเราสามารถเลือกค่า k โดยการกำหนดลงไปใน n_neighbors ได้เลย ผมจะขอเลือกเป็น 3 ก่อน
- จากนั้นก็ใช้ syntax อันเดิมเหมือน algorithm ตัวที่แล้วในการสอนเจ้าโมเดลของเรา
หลังจากที่เราสร้าง train โมเดลของเราเสร็จก็ได้เวลาที่เราจะมาจัดสอบให้เจ้าโมเดลของเราให้มันทดสอบว่ามันมีความรู้มากมายขนาดไหนกัน
โดยก็ใช้โค้ดชุดเดิมกับที่เราใช้กับโมเดล Naive Bayes เลย
คำเตือน: อย่างที่บอกไปครับว่าโมเดลตัวนี้รันนานพอสมควร กดรันแล้วก็รอนิดนึงนะครับไม่ได้ค้างหรือ error อะไรมันแค่นาน 😂
หลังจากลองรันโดยเลือกให้ K มีค่าเท่ากับ 3 รอมันประมวลผลอยู่ซักพักผมก็ได้ผลลัพท์ออกมาที่ประมาณ 0.658 หรือประมาณ 65.8% ซึ่งก็แย่กว่า Naive Bayes พอสมควร ผมเลยไม่พอใจเท่าไร (ฮา)
ก็เลยลองนั่งเปลี่ยนค่า K ไปเรื่อยๆดูก็ได้ผลลัพท์ประมาณนี้
เลือกค่า K เป็น 2 ผลลัพท์ 0.620
เลือกค่า K เป็น 3 ผลลัพท์ 0.658
เลือกค่า K เป็น 4 ผลลัพท์ 0.637
เลือกค่า K เป็น 5 ผลลัพท์ 0.657
จะเห็นว่าผมเลือกค่า K ในช่วง 2–5 ก็ได้ค่าอยู่ประมาณ 0.65 ไม่มากไปกว่านี้ผมก็เลยตัดใจแล้วครับ 😂
มาต่อที่ตัวถัดไปดีกว่า
Decision Tree ต้นไม้ตัดสินใจ
ซึ่งเจ้า Decision Tree นี้ถ้าแปลเป็นภาษาไทยแล้วจะได้ว่า ต้นไม้ตัดสินใจ ซึ่งหน้าที่ของมันก็ตามชื่อครับ คือช่วยในการตัดสินใจโดยอ้างอิงจากข้อมูลที่เราป้อนให้มันเข้าไป
บทความนี้เราพูดถึงเรื่องทฤษฎีมาเยอะมากแล้วเพราะฉะนั้นจะขอข้ามตัวนี้ไปก่อนครับ สำหรับใครที่อยากอ่านการทำงานเบื้องลึกของ Decision Tree สามารถอ่านได้ที่นี่
สิ่งที่เราต้องการจากมันคือแผนภาพประมาณนี้ครับ (แต่ในบทความนี้จะขอข้ามไปเพื่อลดความซับซ้อนของเนื้อหา)
- เรา import ไลบรารีที่เราต้องการเข้ามาก่อน ซึ่งสิ่งที่เราต้องการตรงนี้คือ module tree จากไลบรารี scikit-learn (sklearn)
- ตามสเตปเดิมครับ model มาเก็บโมเดลที่เราต้องการ ซึ่งในที่นี้คือ DecisionTreeClassifier() จาก tree หรือใครจะ import เป็น from sklearn.tree import DecisionTreeClassifier เลยก็ได้ไม่มีปัญหาอะไรครับ
- จากนั้นก็เอาโมเดลมาเทรนโดยการรัน .fit() เหมือนเดิม ก็เสร็จสรรพ โมเดลของเราก็ทำงานได้แล้วครับ
เมื่อได้โมเดลออกมาแล้วสิ่งต่อไปที่เราจะทำก็คือ??
ใช่ครับ เอามันมาทดสอบนั่นแหละ ว่าตัวไหนทำงานได้ดีที่สุด ว่า Decision Tree ของเราจะทำงานได้ดีขนาดไหน
เราก็รันโค้ดชุดเดิมเลยครับแล้วมาดูกันว่าประสิทธิภาพมันได้ขนาดไหน
ตอนผมรันออกมาเนี่ยผมได้ประสิทธิภาพประมาณ 0.693 หรือเป็นเปอร์เซนต์ประมาณ 69.3% ซึ่งยังได้ผลต่ำกว่า model ตัวแรกที่เราทำอยู่บ้าง (Naive Bayes ได้ 75% กว่าๆเลยทีเดียว)
ก็ถ้าใครอยากลองปรับโมเดลเล่นก็ลองดูครับ แต่สำหรับผมจะขออณุญาติข้ามไปโมเดลตัวต่อไปเลย
ลองเอาโมเดลหลายๆตัวมาช่วยกันดีมั้ย?
เราลองทำมา 3 โมเดลแล้วครับ ซึ่งแต่ละโมเดลนี่ก็ทำงานแค่ตัวของมันแค่ตัวเดียว ไม่ได้ไปยุ่งกับใคร บางคนก็อาจจะมีความคิดขึ้นมาว่า เฮ้ย ถ้างั้นไม่ลองเอาโมเดลหลายๆตัวมาทำงานด้วยกันดูล่ะ
ใช่แล้วครับ เราจะลองเอาโมเดลหลายๆตัวมาทำงานร่วมกันดู สำหรับการทำตามแนวความคิดอย่างนี้เราจะเรียกกันว่า Ensemble Learning ครับ
โดย Ensemble Learning ก็สามารถทำได้ในหลายรูปแบบโดยมีแนวทางหลักๆประมาณนี้
- Bagging
วิธีการ bagging นี้ย่อมาจากคำว่า Bootstrap Aggregation ครับ ซึ่งมันก็คือการทำงาน 2 อย่าง ทั้ง Bootstrap แล้วก็ Aggregation มาผสมกัน
Bootstrap ก็คือการแยกชุดข้อมูลออกมาเป็นกลุ่มๆ
Aggregation แปลว่าการนำมารวมกัน หรือก็คือเอาโมเดลทุกตัวที่เราเทรนมารวมกัน
ถ้ารวมเข้ากันทั้ง 2 อย่าง Bagging ก็คือการแบ่งชุดข้อมูลของเราออกเป็นกลุ่มๆ แบ่งไปให้โมเดลแต่ละตัวเอาไปเทรน จากนั้นก็เอาโมเดลทั้งหมดมารวมกันครับ
2. Boosting
ขั้นตอนการ Boosting จะเป็นขั้นตอนที่เหมือนกับอัพเลเวลตัวละครขึ้นไปเรื่อยๆครับ โดยเราจะเอาข้อมูลของเราไปเทรนโมเดลก่อน จากนั้นเราก็จะมาดูว่ามันมีจุดอ่อนอะไรบ้างมั้ย แล้วเอาตัวที่เป็นจุดอ่อนนั่นแหละไปเทรนเพิ่มเพื่อกำจัดจุดอ่อน แล้วก็เอามาทดสอบหาจุดอ่อนอีก แล้วก็วนลูปเทรนไปเรื่อยๆจนกว่าจะได้ประสิทธิภาพที่พอใจ ก็จะได้เป็นโมเดลตัว final ของเราออกมา
3. Stacking
วิธีการ Stacking นี้จะถือว่าเป็นวิธีที่ค่อนข้างกว้างขวางที่สุด วิธีการนี้เราไม่ได้ fixes ครับว่าโมเดลแต่ละตัวที่เราเอามาเทรนมันจะต้องเป็นโมเดลประเภทเดียวกัน แต่อาจจะเป็นโมเดลคนละอัลกอริทึม โมเดลคนละรูปแบบ คนละพารามิเตอร์ หรือโมเดลที่รันไม่พร้อมกันรันอยู่เครื่องเพื่อนแล้วเราไปหยิบเอามาทำก็ได้ (😂)
โดยการทำงานของมันก็คือเอา data มาแล้วเอาไปเทรนแต่ละตัวแยกกัน จากนั้นก็ค่อยเอามารวมกันทีหลัง โดยการรวมกันเนี่ยเราก็สามารถเลือกได้หลายรูปแบบ ไม่ว่าจะให้โมเดลแต่ละตัวมาโหวตกัน ให้โมเดลแต่ละตัวเอามาหาค่าเฉลี่ย หาค่ากลาง อะไรก็ได้แล้วแต่เราเลยครับ จะถือว่ารูปแบบนี้เนี่ยมีความยืดหยุ่นมากๆ
แล้วสิ่งที่เราจะเอามาใช้งานในวันนี้คือตัวไหน?
ผมจะยกตัวอย่างตัวที่เป็นพื้นฐานที่ทุกคนน่าจะเอาไปลองทำได้ง่ายๆดูก่อนตัวนึงครับ โมเดลตัวนี้มีชื่อว่า Random Forest
ซึ่งตามชื่อของมันบอกผมคิดว่าทุกคนก็น่าจะเดากันออกว่ามันต้องมีความเกี่ยวข้องกันกับ Decision Tree แน่ๆ เพราะมันมีต้นไม้เหมือนกัน
แน่นอนครับว่ามันมีความเกี่ยวข้องกัน!
Random Forest ก็คือการนำ Decision Tree หลายๆตัวมาช่วยกันประมวลผล โดยเราจะแบ่งชุดข้อมูลของเราออกเป็นหลายๆกลุ่ม แล้วเอาไปป้อนให้กับ Decision Tree หลายๆตัว จากนั้นเราก็เอาผลลัพท์ที่ได้มาคำนวณรวมกัน (ในที่นี้เป็นการโหวตเลือก)
ลองทายกันดูครับว่า Random Forest มีลักษณะการใช้งาน Ensemble Learning ในรูปแบบไหน 🧐🧐
เฉลย: Bagging
มาโค้ดดีกว่า
คุยกันเรื่องทฤษฎีนานมากครับ เรามาเขียนโค้ดกันดีกว่า
จะเห็นว่าโค้ดก็จะอยู่ใน pattern เดิมๆครับ
- import สิ่งที่เราต้องการ ซึ่งในที่นี้ก็คือ RandomForestClassifier
- model = RandomForestClassifier() ก็คือการประกาศตัวแปรขึ้นมาเพื่อรับตัวโมเดลที่เราต้องการจะใช้ ในที่นี้ก็คือ RandomForestClassifier นั่นแหละ
- จากนั้นก็เทรนโดยการใช้ .fit()
คำเตือน: การรันโมเดลตัวนี้ใช้เวลานานมากครับ ก็พอกดรันก็รอมันรันไปหน่อยไม่ได้ค้างนะครับ
จากนั้นเราก็เอาเจ้า ML ของเรามาทำการทดสอบเหมือนเดิมครับ
โดยการใช้โค้ดชุดเดิมเลย
ส่วนตัวแล้วตอนผมรันผมได้ผลลัพท์ออกมาอยู่ที่ประมาณ 0.72 หรือก็คือประมาณ 72% ครับ จะเห็นว่าน้อยกว่า Naive Bayes ที่เรารันไปตอนแรกนิดหน่อย
แต่เวลาประมวลผลต่างกันมากเลย 😭
อันนี้ก็เนื่องมาจากว่าโมเดลตัวนี้ใช้งานการประมวลผลค่อนข้างที่จะสูงและข้อมูลของเราก็ค่อนข้างซับซ้อนด้วยครับ
เลือกโมเดลที่จะใช้
จากโมเดลทั้งหมดที่เรา train กันมาได้ผลว่า Naive Bayes นำเพื่อนที่สุดอยู่ที่ประมาณ 75% ครับ
แสดงว่าถ้าเราอยากจะเอาโมเดลตัวไหนไปใช้งาน แน่นอนว่าเราก็ต้องเลือก Naive Bayes นี่แหละ
ใครที่อยากลองเอาโค้ดไปลองรันเล่น ผมสร้าง Gist ที่รวมโค้ดทั้งหมดในบทความนี้ไว้ใน Notebook ข้างล่างนี้ สามารถลองเอาไปเล่นได้ตามสะดวกเลยครับ (แต่อาจจะต้องจัดการกับเรื่องไฟล์เองซักหน่อย)
สำหรับบทความนี้ก็จะขอจบลงเพียงเท่านี้ครับ สำหรับใครที่ชอบและสนใจในเรื่องของ ML และอยากทราบเรื่องของ ML มากกว่านี้ก็สามารถที่จะติดตามพวกเราได้ผ่านช่องทางข้างล่างนี้ได้ครับ
หรือถ้าใครที่อยากจะย้อนกลับไปอ่านบทความ ML เก่าๆที่ผม (ผู้เขียน) เคยเขียนไว้ในบล็อกส่วนตัว ก็สามารถกดติดตามได้ที่นี่ครับ
ใครที่ได้ลงคอร์ส Machine Learning for Absolute Beginner
สำหรับใครที่ลงคอร์ส Machine Learning for Absolute Beginner ของ Stackpython เอาไว้เราจะเริ่มมีการเรียนการสอนกันในวันพรุ่งนี้ (20 มิถุนายน 2562) นะครับ 😊
เจอกันในคอร์สครับทุกคน
หรือสำหรับใครที่สนใจอยากเรียนรู้เพิ่มเติมแล้วยังไม่ได้สมัครคอร์สสามารถแวะเข้าไปชมรายละเอียดได้ที่ลิงค์ข้างล่างครับ
ท่านสามารถติดตามพวกเราได้ที่ stackpython ตามช่องทางด้านล่างนี้ได้เลยครับ
Instagram: stackpython
Facebook: stackpython
Website: stackpython.co
YouTube: stackpython