News classification #1: รู้จักกับ NLP และการสร้างโมเดลแยกประเภทข่าว
เรียนรู้ รู้จัก Natural Language Processing (NLP)
วันนี้มารู้จักกับศาสตร์แห่งภาษาที่เกี่ยวข้องกับวิทยาศาสตร์ข้อมูล หรือที่ได้ยินกันอย่างคุ้นหูอยู่ทุกวันนี้คือ Natural Language Processing (NLP) ยังไม่แน่ใจว่าเรียกคำแปลอย่างเป็นทางการของศาสตร์นี้ว่าอะไร เลยลอง Google และได้ผลลัพธ์ว่า
ใช่เลย… NLP คือการทำให้คอมพิวเตอร์เข้าใจการสื่อสารด้วยภาษาของมนุษย์ ซึ่งแน่นอนว่าพอเป็นแบบนี้แล้ว ศาสตร์นี้สามารถแตกแยกย่อยไปได้หลายสาขา หลายโมเดลมาก ๆ ลองยกตัวอย่างเท่าที่นึกออกเร็ว ๆ คือ Text classification หรือการแยกประเภทของข้อความตามจุดมุ่งหมายใด ๆ ซึ่งวันนี้จะมาทำ Text classification model ด้วยข้อมูลประเภทข่าว เพื่อแยกประเภทว่าเนื้อหาข่าวแบบนี้ โมเดล Classify ให้อยู่ในหมวดข่าวใด เช่น การเมือง กีฬา เทคโนโลยี เป็นต้น
ซึ่งมันไม่ได้จำกัดอยู่เพียงเท่านี้ เรายังสามารถต่อยอดโมเดล Text classification ให้ไปทำอะไรอย่างอื่นได้อีก เช่น โมเดลการคัดแยก Spam SMS, Chat BOT, Fake news detection (อันนี้อยากทำ ซึ่งไว้ก่อน) ตัวอย่างมันมีเยอะกว่านี้มาก ๆ แต่ว่า…ขอเริ่มที่โมเดล News classification กันก่อน
Dataset
เนื่องจากเป็นโมเดล NLP แรกที่เริ่มหัดทำ ดังนั้นขอเริ่มต้นจากอะไรที่ค่อนข้างง่ายกันก่อน รวมไปถึง Dataset ชุดนี้ด้วย อย่างที่บอกไปว่า NLP เป็นการทำโมเดลเกี่ยวกับข้อความ หรือภาษาเป็นหลัก และอย่างที่รู้กันว่าภาษาไทยคงเป็นอะไรที่ไม่ง่ายนักสำหรับการเริ่มต้น เพราะข้อจำกัดทางไวยากรณ์ทางภาษา ที่ทำให้การทำงานในเชิงโมเดล ต้องมีความชำนาญมากกว่าภาษาอังกฤษ ดังนั้นขอเริ่มต้นด้วยภาษาอังกฤษ
Dataset ในวันนี้ ขอใช้เป็นข่าวจาก BBC News ที่เป็นแบบฝึกหัดการทำโมเดล NLP ที่นิยมกัน ซึ่งสามารถโหลดได้จากที่ Link ด้านล่าง
Code
เริ่มต้นเหมือนเดิมในทุก ๆ โมเดลคือ Process ที่ต้อง Import libraries ที่จำเป็นต้องใช้งาน ซึ่งแบ่งออกเป็น 2 ส่วนใหญ่ ๆ คือส่วนที่จัดการกับ Data และส่วนที่จัดการกับ Text ซึ่งส่วนหลังขอยกไปพูดในตอนต่อไป ถ้ารัน Code ตรงส่วนที่เป็นการ Download เกี่ยวกับ NLTK ตัว Script จะมีการโหลดอะไรเพิ่มเติม ซึ่งขอยังไม่พูดถึงวันนี้ เพราะมันเกี่ยวข้องกับ Libraries ที่ไม่ได้พูดถึงเช่นกัน ดังนั้นรวมกันไปพูดในตอนต่อไปครั้งเดียว เพื่อความชัดเจน
[nltk_data] Downloading package punkt to /root/nltk_data...
[nltk_data] Package punkt is already up-to-date!
[nltk_data] Downloading package stopwords to /root/nltk_data...
[nltk_data] Package stopwords is already up-to-date!
True
| Category | Text |
|---------------|------|
| business | 336 |
| entertainment | 273 |
| politics | 274 |
| sport | 346 |
| tech | 261 |
ตัวอย่างของ Dataset ที่ใช้ในการพัฒนาโมเดล ที่ต้องสนใจคือ Column Text
ซึ่งเก็บ Actical ของข่าวเอาไว้ และ Category
ซึ่งเป็นประเภทของข่าวนั้น ๆ ว่าจัดอยู่ในหมวดหมู่ไหน สังเกตได้ว่าข้อมูลถูกเก็บเป็น String อยู่ ดังนั้นจึงยังไม่ได้สามารถ Train model ได้ เพราะ Machine learning รู้จักเฉพาะตัวเลข เพื่อความง่ายจึงขอแทน String ด้วยตัวเลขเรียงไปตั้งแต่ 0, 1, …, 4
การแทนค่า String ด้วยตัวเลข สามารถใช้ pandas.Categorical()
แล้วผ่าน Column ที่ต้องการเข้าไป จากนั้นใช้ .cat.codes
เพื่อดึงตัวเลขออกมา หลังจากที่เปลี่ยนค่าเป็นตัวเลขแล้ว ควรได้ข้อมูลสรุปตามด้านล่าง
| Category | Text |
|----------|------|
| 0 | 336 |
| 1 | 273 |
| 2 | 274 |
| 3 | 346 |
| 4 | 261 |
สังเกตเห็นว่าข่าวแต่ละประเภทมีจำนวนมากน้อยที่ไม่เท่ากันอยู่ ซึ่งจริง ๆ แล้วจำนวนมันก็ต่างกันไม่มาก สามารถนำไปทำโมเดลต่อได้เลย แต่ว่าอยากทำให้มันมีค่าเท่ากันตั้งแต่แรกก่อนเริ่ม Train model เพราะไม่อยากให้มีความ Bias ไปทางใดทางหนึ่ง
เนื่องจากประเภทของข่าวมีทั้งหมด 5 ประเภท ดังนั้นขอ Sample ออกมาหัวข้อละ 200 ข่าว เพื่อให้เท่ากับ 1000 พอดี สามารถเขียน .apply(lambda function)
ขึ้นมา แล้วใช้ sample()
เพื่อทำการดึงจำนวนข่าวที่เราต้องการออกมาได้ จากนั้นขอ Ramdom dataset อีกรอบนึง ใช้ .sample(frac = 1)
ได้ Dataset สุดท้ายออกมาเท่ากันในแต่ละประเภทข่าว
| Category | Text |
|----------|------|
| 0 | 200 |
| 1 | 200 |
| 2 | 200 |
| 3 | 200 |
| 4 | 200 |
มาถึงตอนนี้ Dataset สำหรับการพัฒนาโมเดลก็พร้อมแล้ว ซึ่งขอหยุดไว้เท่านี้ก่อน เพราะตอนต่อไปต้องมาทำความรู้จักกับ Word2Vec model และการทำ Tokenization ซึ่งรายละเอียดมีเยอะพอสมควร