# บทนำสู่การจำแนกประเภท ในบทเรียนทั้งสี่นี้ คุณจะได้สำรวจหัวข้อพื้นฐานของการเรียนรู้ด้วยเครื่องแบบคลาสสิก - _การจำแนกประเภท_ เราจะเดินผ่านการใช้หลากหลายอัลกอริทึมการจำแนกประเภทกับชุดข้อมูลเกี่ยวกับอาหารที่ยอดเยี่ยมของเอเชียและอินเดีย หวังว่าคุณจะหิวแล้ว! ![แค่หยิบเล็กน้อย!](../../../../4-Classification/1-Introduction/images/pinch.png) > ฉลองอาหารเอเชียในบทเรียนเหล่านี้! ภาพโดย [Jen Looper](https://twitter.com/jenlooper) การจำแนกประเภทเป็นรูปแบบหนึ่งของ [การเรียนรู้แบบมีผู้สอน](https://wikipedia.org/wiki/Supervised_learning) ที่มีความคล้ายคลึงกับเทคนิคการถดถอย หากการเรียนรู้ด้วยเครื่องเกี่ยวกับการทำนายค่าหรือชื่อของสิ่งต่าง ๆ โดยใช้ชุดข้อมูล การจำแนกประเภทมักแบ่งออกเป็นสองกลุ่ม: _การจำแนกประเภทแบบไบนารี_ และ _การจำแนกประเภทแบบหลายคลาส_ [![บทนำสู่การจำแนกประเภท](https://img.youtube.com/vi/eg8DJYwdMyg/0.jpg)](https://youtu.be/eg8DJYwdMyg "บทนำสู่การจำแนกประเภท") > 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ: John Guttag จาก MIT แนะนำการจำแนกประเภท จำไว้ว่า: - **การถดถอยเชิงเส้น** ช่วยให้คุณทำนายความสัมพันธ์ระหว่างตัวแปรและทำการทำนายที่แม่นยำเกี่ยวกับตำแหน่งที่จุดข้อมูลใหม่จะตกอยู่ในความสัมพันธ์กับเส้นนั้น ตัวอย่างเช่น คุณสามารถทำนาย _ราคาของฟักทองในเดือนกันยายนเทียบกับเดือนธันวาคม_ - **การถดถอยโลจิสติก** ช่วยให้คุณค้นพบ "หมวดหมู่ไบนารี": ที่จุดราคานี้ _ฟักทองนี้เป็นสีส้มหรือไม่เป็นสีส้ม_? การจำแนกประเภทใช้หลากหลายอัลกอริทึมเพื่อกำหนดวิธีอื่นในการกำหนดป้ายหรือคลาสของจุดข้อมูล ลองทำงานกับข้อมูลอาหารนี้เพื่อดูว่า โดยการสังเกตกลุ่มของส่วนผสม เราสามารถกำหนดแหล่งกำเนิดของอาหารได้หรือไม่ ## [แบบทดสอบก่อนบทเรียน](https://ff-quizzes.netlify.app/en/ml/) > ### [บทเรียนนี้มีให้ใน R!](../../../../4-Classification/1-Introduction/solution/R/lesson_10.html) ### บทนำ การจำแนกประเภทเป็นหนึ่งในกิจกรรมพื้นฐานของนักวิจัยการเรียนรู้ด้วยเครื่องและนักวิทยาศาสตร์ข้อมูล ตั้งแต่การจำแนกค่าของไบนารีพื้นฐาน ("อีเมลนี้เป็นสแปมหรือไม่?") ไปจนถึงการจำแนกภาพและการแบ่งส่วนที่ซับซ้อนโดยใช้การมองเห็นด้วยคอมพิวเตอร์ การสามารถจัดเรียงข้อมูลเป็นคลาสและตั้งคำถามกับมันเป็นสิ่งที่มีประโยชน์เสมอ หากจะกล่าวถึงกระบวนการในเชิงวิทยาศาสตร์ วิธีการจำแนกประเภทของคุณจะสร้างแบบจำลองการทำนายที่ช่วยให้คุณสามารถจับคู่ความสัมพันธ์ระหว่างตัวแปรอินพุตกับตัวแปรเอาต์พุตได้ ![การจำแนกประเภทแบบไบนารี vs. หลายคลาส](../../../../4-Classification/1-Introduction/images/binary-multiclass.png) > ปัญหาแบบไบนารี vs. หลายคลาสสำหรับอัลกอริทึมการจำแนกประเภท อินโฟกราฟิกโดย [Jen Looper](https://twitter.com/jenlooper) ก่อนเริ่มกระบวนการทำความสะอาดข้อมูลของเรา การแสดงภาพ และการเตรียมข้อมูลสำหรับงาน ML ของเรา ลองเรียนรู้เล็กน้อยเกี่ยวกับวิธีต่าง ๆ ที่การเรียนรู้ด้วยเครื่องสามารถนำมาใช้เพื่อจำแนกข้อมูลได้ การจำแนกประเภทที่ได้มาจาก [สถิติ](https://wikipedia.org/wiki/Statistical_classification) โดยใช้การเรียนรู้ด้วยเครื่องแบบคลาสสิกใช้คุณสมบัติต่าง ๆ เช่น `smoker`, `weight`, และ `age` เพื่อกำหนด _ความน่าจะเป็นของการพัฒนาโรค X_ ในฐานะเทคนิคการเรียนรู้แบบมีผู้สอนที่คล้ายกับการฝึกถดถอยที่คุณทำมาก่อนหน้านี้ ข้อมูลของคุณจะถูกติดป้ายกำกับ และอัลกอริทึม ML จะใช้ป้ายกำกับเหล่านั้นเพื่อจำแนกและทำนายคลาส (หรือ 'คุณสมบัติ') ของชุดข้อมูลและกำหนดให้กับกลุ่มหรือผลลัพธ์ ✅ ลองจินตนาการถึงชุดข้อมูลเกี่ยวกับอาหาร คุณคิดว่าโมเดลแบบหลายคลาสจะสามารถตอบคำถามอะไรได้บ้าง? โมเดลแบบไบนารีจะตอบคำถามอะไรได้บ้าง? ถ้าคุณต้องการกำหนดว่าอาหารที่กำหนดมีแนวโน้มที่จะใช้เมล็ดฟีนูกรีกหรือไม่? หรือถ้าคุณต้องการดูว่า หากคุณได้รับของขวัญเป็นถุงช้อปปิ้งที่เต็มไปด้วยโป๊ยกั๊ก อาร์ติโชก กะหล่ำดอก และฮอร์สแรดิช คุณจะสามารถสร้างอาหารอินเดียทั่วไปได้หรือไม่? [![ตะกร้าปริศนาแสนบ้าคลั่ง](https://img.youtube.com/vi/GuTeDbaNoEU/0.jpg)](https://youtu.be/GuTeDbaNoEU "ตะกร้าปริศนาแสนบ้าคลั่ง") > 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ รายการ 'Chopped' มีแนวคิดเกี่ยวกับ 'ตะกร้าปริศนา' ที่เชฟต้องทำอาหารจากส่วนผสมที่สุ่มเลือก แน่นอนว่าโมเดล ML น่าจะช่วยได้! ## สวัสดี 'ตัวจำแนก' คำถามที่เราต้องการถามจากชุดข้อมูลอาหารนี้เป็นคำถามแบบ **หลายคลาส** เนื่องจากเรามีอาหารประจำชาติหลายประเภทที่สามารถทำงานได้ จากชุดของส่วนผสม อาหารเหล่านี้จะเข้ากับคลาสใด? Scikit-learn มีอัลกอริทึมหลากหลายให้เลือกใช้เพื่อจำแนกข้อมูล ขึ้นอยู่กับประเภทของปัญหาที่คุณต้องการแก้ไข ในสองบทเรียนถัดไป คุณจะได้เรียนรู้เกี่ยวกับอัลกอริทึมเหล่านี้ ## แบบฝึกหัด - ทำความสะอาดและปรับสมดุลข้อมูลของคุณ งานแรกที่ต้องทำก่อนเริ่มโครงการนี้คือการทำความสะอาดและ **ปรับสมดุล** ข้อมูลของคุณเพื่อให้ได้ผลลัพธ์ที่ดีขึ้น เริ่มต้นด้วยไฟล์ _notebook.ipynb_ ที่ว่างเปล่าในโฟลเดอร์รากนี้ สิ่งแรกที่ต้องติดตั้งคือ [imblearn](https://imbalanced-learn.org/stable/) ซึ่งเป็นแพ็กเกจ Scikit-learn ที่จะช่วยให้คุณปรับสมดุลข้อมูลได้ดีขึ้น (คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับงานนี้ในอีกสักครู่) 1. เพื่อติดตั้ง `imblearn` ให้รัน `pip install` ดังนี้: ```python pip install imblearn ``` 1. นำเข้าแพ็กเกจที่คุณต้องการเพื่อดึงข้อมูลและแสดงภาพ นอกจากนี้ให้นำเข้า `SMOTE` จาก `imblearn` ```python import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np from imblearn.over_sampling import SMOTE ``` ตอนนี้คุณพร้อมที่จะนำเข้าข้อมูลในขั้นตอนถัดไปแล้ว 1. งานถัดไปคือการนำเข้าข้อมูล: ```python df = pd.read_csv('../data/cuisines.csv') ``` การใช้ `read_csv()` จะอ่านเนื้อหาของไฟล์ csv _cusines.csv_ และวางไว้ในตัวแปร `df` 1. ตรวจสอบรูปร่างของข้อมูล: ```python df.head() ``` ห้าบรรทัดแรกมีลักษณะดังนี้: ```output | | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini | | --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- | | 0 | 65 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 1 | 66 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 2 | 67 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 3 | 68 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 4 | 69 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | ``` 1. รับข้อมูลเกี่ยวกับข้อมูลนี้โดยเรียก `info()`: ```python df.info() ``` ผลลัพธ์ของคุณจะคล้ายกับ: ```output RangeIndex: 2448 entries, 0 to 2447 Columns: 385 entries, Unnamed: 0 to zucchini dtypes: int64(384), object(1) memory usage: 7.2+ MB ``` ## แบบฝึกหัด - เรียนรู้เกี่ยวกับอาหาร ตอนนี้งานเริ่มน่าสนใจมากขึ้น ลองค้นพบการกระจายของข้อมูลต่ออาหาร 1. แสดงข้อมูลเป็นแถบโดยเรียก `barh()`: ```python df.cuisine.value_counts().plot.barh() ``` ![การกระจายข้อมูลอาหาร](../../../../4-Classification/1-Introduction/images/cuisine-dist.png) มีจำนวนอาหารที่จำกัด แต่การกระจายข้อมูลไม่เท่ากัน คุณสามารถแก้ไขได้! ก่อนทำเช่นนั้น ลองสำรวจเพิ่มเติมเล็กน้อย 1. ค้นหาว่ามีข้อมูลเท่าใดต่ออาหารและพิมพ์ออกมา: ```python thai_df = df[(df.cuisine == "thai")] japanese_df = df[(df.cuisine == "japanese")] chinese_df = df[(df.cuisine == "chinese")] indian_df = df[(df.cuisine == "indian")] korean_df = df[(df.cuisine == "korean")] print(f'thai df: {thai_df.shape}') print(f'japanese df: {japanese_df.shape}') print(f'chinese df: {chinese_df.shape}') print(f'indian df: {indian_df.shape}') print(f'korean df: {korean_df.shape}') ``` ผลลัพธ์มีลักษณะดังนี้: ```output thai df: (289, 385) japanese df: (320, 385) chinese df: (442, 385) indian df: (598, 385) korean df: (799, 385) ``` ## ค้นพบส่วนผสม ตอนนี้คุณสามารถเจาะลึกลงไปในข้อมูลและเรียนรู้ว่าส่วนผสมทั่วไปต่ออาหารคืออะไร คุณควรลบข้อมูลที่เกิดซ้ำซึ่งสร้างความสับสนระหว่างอาหาร ดังนั้นลองเรียนรู้เกี่ยวกับปัญหานี้ 1. สร้างฟังก์ชัน `create_ingredient()` ใน Python เพื่อสร้าง dataframe ของส่วนผสม ฟังก์ชันนี้จะเริ่มต้นด้วยการลบคอลัมน์ที่ไม่เป็นประโยชน์และจัดเรียงส่วนผสมตามจำนวน: ```python def create_ingredient_df(df): ingredient_df = df.T.drop(['cuisine','Unnamed: 0']).sum(axis=1).to_frame('value') ingredient_df = ingredient_df[(ingredient_df.T != 0).any()] ingredient_df = ingredient_df.sort_values(by='value', ascending=False, inplace=False) return ingredient_df ``` ตอนนี้คุณสามารถใช้ฟังก์ชันนั้นเพื่อดูแนวคิดเกี่ยวกับส่วนผสมยอดนิยมสิบอันดับแรกต่ออาหาร 1. เรียก `create_ingredient()` และแสดงภาพโดยเรียก `barh()`: ```python thai_ingredient_df = create_ingredient_df(thai_df) thai_ingredient_df.head(10).plot.barh() ``` ![ไทย](../../../../4-Classification/1-Introduction/images/thai.png) 1. ทำเช่นเดียวกันสำหรับข้อมูลญี่ปุ่น: ```python japanese_ingredient_df = create_ingredient_df(japanese_df) japanese_ingredient_df.head(10).plot.barh() ``` ![ญี่ปุ่น](../../../../4-Classification/1-Introduction/images/japanese.png) 1. ตอนนี้สำหรับส่วนผสมของจีน: ```python chinese_ingredient_df = create_ingredient_df(chinese_df) chinese_ingredient_df.head(10).plot.barh() ``` ![จีน](../../../../4-Classification/1-Introduction/images/chinese.png) 1. แสดงภาพส่วนผสมของอินเดีย: ```python indian_ingredient_df = create_ingredient_df(indian_df) indian_ingredient_df.head(10).plot.barh() ``` ![อินเดีย](../../../../4-Classification/1-Introduction/images/indian.png) 1. สุดท้าย แสดงภาพส่วนผสมของเกาหลี: ```python korean_ingredient_df = create_ingredient_df(korean_df) korean_ingredient_df.head(10).plot.barh() ``` ![เกาหลี](../../../../4-Classification/1-Introduction/images/korean.png) 1. ตอนนี้ ลบส่วนผสมที่พบมากที่สุดที่สร้างความสับสนระหว่างอาหารที่แตกต่างกัน โดยเรียก `drop()`: ทุกคนชอบข้าว กระเทียม และขิง! ```python feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1) labels_df = df.cuisine #.unique() feature_df.head() ``` ## ปรับสมดุลชุดข้อมูล ตอนนี้คุณได้ทำความสะอาดข้อมูลแล้ว ใช้ [SMOTE](https://imbalanced-learn.org/dev/references/generated/imblearn.over_sampling.SMOTE.html) - "เทคนิคการสุ่มตัวอย่างชนกลุ่มน้อยแบบสังเคราะห์" - เพื่อปรับสมดุลข้อมูล 1. เรียก `fit_resample()` กลยุทธ์นี้สร้างตัวอย่างใหม่โดยการแทรกแซง ```python oversample = SMOTE() transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df) ``` โดยการปรับสมดุลข้อมูล คุณจะได้ผลลัพธ์ที่ดีขึ้นเมื่อจำแนกข้อมูล ลองคิดถึงการจำแนกประเภทแบบไบนารี หากข้อมูลส่วนใหญ่ของคุณเป็นคลาสเดียว โมเดล ML จะทำนายคลาสนั้นบ่อยขึ้น เพียงเพราะมีข้อมูลสำหรับมันมากกว่า การปรับสมดุลข้อมูลจะช่วยลบความไม่สมดุลนี้ 1. ตอนนี้คุณสามารถตรวจสอบจำนวนป้ายกำกับต่อส่วนผสม: ```python print(f'new label count: {transformed_label_df.value_counts()}') print(f'old label count: {df.cuisine.value_counts()}') ``` ผลลัพธ์ของคุณมีลักษณะดังนี้: ```output new label count: korean 799 chinese 799 indian 799 japanese 799 thai 799 Name: cuisine, dtype: int64 old label count: korean 799 indian 598 chinese 442 japanese 320 thai 289 Name: cuisine, dtype: int64 ``` ข้อมูลสะอาด สมดุล และน่ากินมาก! 1. ขั้นตอนสุดท้ายคือการบันทึกข้อมูลที่สมดุลของคุณ รวมถึงป้ายกำกับและคุณสมบัติ ลงใน dataframe ใหม่ที่สามารถส่งออกไปยังไฟล์: ```python transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer') ``` 1. คุณสามารถดูข้อมูลอีกครั้งโดยใช้ `transformed_df.head()` และ `transformed_df.info()` บันทึกสำเนาของข้อมูลนี้เพื่อใช้ในบทเรียนในอนาคต: ```python transformed_df.head() transformed_df.info() transformed_df.to_csv("../data/cleaned_cuisines.csv") ``` CSV ใหม่ที่สดนี้สามารถพบได้ในโฟลเดอร์ข้อมูลราก --- ## 🚀ความท้าทาย หลักสูตรนี้มีชุดข้อมูลที่น่าสนใจหลายชุด ลองค้นหาในโฟลเดอร์ `data` และดูว่ามีชุดข้อมูลใดที่เหมาะสมสำหรับการจำแนกประเภทแบบไบนารีหรือหลายคลาส? คุณจะถามคำถามอะไรจากชุดข้อมูลนี้? ## [แบบทดสอบหลังบทเรียน](https://ff-quizzes.netlify.app/en/ml/) ## ทบทวนและศึกษาด้วยตนเอง สำรวจ API ของ SMOTE กรณีการใช้งานใดที่เหมาะสมที่สุดสำหรับมัน? ปัญหาใดที่มันแก้ไข? ## งานที่ได้รับมอบหมาย [สำรวจวิธีการจำแนกประเภท](assignment.md) --- **ข้อจำกัดความรับผิดชอบ**: เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้การแปลมีความถูกต้องมากที่สุด แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษาจากผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้