25 KiB
บทนำสู่การจำแนกประเภท
ในบทเรียนทั้งสี่นี้ คุณจะได้สำรวจหัวข้อพื้นฐานของการเรียนรู้ด้วยเครื่องแบบคลาสสิก - การจำแนกประเภท เราจะเดินผ่านการใช้หลากหลายอัลกอริทึมการจำแนกประเภทกับชุดข้อมูลเกี่ยวกับอาหารที่ยอดเยี่ยมของเอเชียและอินเดีย หวังว่าคุณจะหิวแล้ว!
ฉลองอาหารเอเชียในบทเรียนเหล่านี้! ภาพโดย Jen Looper
การจำแนกประเภทเป็นรูปแบบหนึ่งของ การเรียนรู้แบบมีผู้สอน ที่มีความคล้ายคลึงกับเทคนิคการถดถอย หากการเรียนรู้ด้วยเครื่องเกี่ยวกับการทำนายค่าหรือชื่อของสิ่งต่าง ๆ โดยใช้ชุดข้อมูล การจำแนกประเภทมักแบ่งออกเป็นสองกลุ่ม: การจำแนกประเภทแบบไบนารี และ การจำแนกประเภทแบบหลายคลาส
🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ: John Guttag จาก MIT แนะนำการจำแนกประเภท
จำไว้ว่า:
- การถดถอยเชิงเส้น ช่วยให้คุณทำนายความสัมพันธ์ระหว่างตัวแปรและทำการทำนายที่แม่นยำเกี่ยวกับตำแหน่งที่จุดข้อมูลใหม่จะตกอยู่ในความสัมพันธ์กับเส้นนั้น ตัวอย่างเช่น คุณสามารถทำนาย ราคาของฟักทองในเดือนกันยายนเทียบกับเดือนธันวาคม
- การถดถอยโลจิสติก ช่วยให้คุณค้นพบ "หมวดหมู่ไบนารี": ที่จุดราคานี้ ฟักทองนี้เป็นสีส้มหรือไม่เป็นสีส้ม?
การจำแนกประเภทใช้หลากหลายอัลกอริทึมเพื่อกำหนดวิธีอื่นในการกำหนดป้ายหรือคลาสของจุดข้อมูล ลองทำงานกับข้อมูลอาหารนี้เพื่อดูว่า โดยการสังเกตกลุ่มของส่วนผสม เราสามารถกำหนดแหล่งกำเนิดของอาหารได้หรือไม่
แบบทดสอบก่อนบทเรียน
บทเรียนนี้มีให้ใน R!
บทนำ
การจำแนกประเภทเป็นหนึ่งในกิจกรรมพื้นฐานของนักวิจัยการเรียนรู้ด้วยเครื่องและนักวิทยาศาสตร์ข้อมูล ตั้งแต่การจำแนกค่าของไบนารีพื้นฐาน ("อีเมลนี้เป็นสแปมหรือไม่?") ไปจนถึงการจำแนกภาพและการแบ่งส่วนที่ซับซ้อนโดยใช้การมองเห็นด้วยคอมพิวเตอร์ การสามารถจัดเรียงข้อมูลเป็นคลาสและตั้งคำถามกับมันเป็นสิ่งที่มีประโยชน์เสมอ
หากจะกล่าวถึงกระบวนการในเชิงวิทยาศาสตร์ วิธีการจำแนกประเภทของคุณจะสร้างแบบจำลองการทำนายที่ช่วยให้คุณสามารถจับคู่ความสัมพันธ์ระหว่างตัวแปรอินพุตกับตัวแปรเอาต์พุตได้
ปัญหาแบบไบนารี vs. หลายคลาสสำหรับอัลกอริทึมการจำแนกประเภท อินโฟกราฟิกโดย Jen Looper
ก่อนเริ่มกระบวนการทำความสะอาดข้อมูลของเรา การแสดงภาพ และการเตรียมข้อมูลสำหรับงาน ML ของเรา ลองเรียนรู้เล็กน้อยเกี่ยวกับวิธีต่าง ๆ ที่การเรียนรู้ด้วยเครื่องสามารถนำมาใช้เพื่อจำแนกข้อมูลได้
การจำแนกประเภทที่ได้มาจาก สถิติ โดยใช้การเรียนรู้ด้วยเครื่องแบบคลาสสิกใช้คุณสมบัติต่าง ๆ เช่น smoker
, weight
, และ age
เพื่อกำหนด ความน่าจะเป็นของการพัฒนาโรค X ในฐานะเทคนิคการเรียนรู้แบบมีผู้สอนที่คล้ายกับการฝึกถดถอยที่คุณทำมาก่อนหน้านี้ ข้อมูลของคุณจะถูกติดป้ายกำกับ และอัลกอริทึม ML จะใช้ป้ายกำกับเหล่านั้นเพื่อจำแนกและทำนายคลาส (หรือ 'คุณสมบัติ') ของชุดข้อมูลและกำหนดให้กับกลุ่มหรือผลลัพธ์
✅ ลองจินตนาการถึงชุดข้อมูลเกี่ยวกับอาหาร คุณคิดว่าโมเดลแบบหลายคลาสจะสามารถตอบคำถามอะไรได้บ้าง? โมเดลแบบไบนารีจะตอบคำถามอะไรได้บ้าง? ถ้าคุณต้องการกำหนดว่าอาหารที่กำหนดมีแนวโน้มที่จะใช้เมล็ดฟีนูกรีกหรือไม่? หรือถ้าคุณต้องการดูว่า หากคุณได้รับของขวัญเป็นถุงช้อปปิ้งที่เต็มไปด้วยโป๊ยกั๊ก อาร์ติโชก กะหล่ำดอก และฮอร์สแรดิช คุณจะสามารถสร้างอาหารอินเดียทั่วไปได้หรือไม่?
🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ รายการ 'Chopped' มีแนวคิดเกี่ยวกับ 'ตะกร้าปริศนา' ที่เชฟต้องทำอาหารจากส่วนผสมที่สุ่มเลือก แน่นอนว่าโมเดล ML น่าจะช่วยได้!
สวัสดี 'ตัวจำแนก'
คำถามที่เราต้องการถามจากชุดข้อมูลอาหารนี้เป็นคำถามแบบ หลายคลาส เนื่องจากเรามีอาหารประจำชาติหลายประเภทที่สามารถทำงานได้ จากชุดของส่วนผสม อาหารเหล่านี้จะเข้ากับคลาสใด?
Scikit-learn มีอัลกอริทึมหลากหลายให้เลือกใช้เพื่อจำแนกข้อมูล ขึ้นอยู่กับประเภทของปัญหาที่คุณต้องการแก้ไข ในสองบทเรียนถัดไป คุณจะได้เรียนรู้เกี่ยวกับอัลกอริทึมเหล่านี้
แบบฝึกหัด - ทำความสะอาดและปรับสมดุลข้อมูลของคุณ
งานแรกที่ต้องทำก่อนเริ่มโครงการนี้คือการทำความสะอาดและ ปรับสมดุล ข้อมูลของคุณเพื่อให้ได้ผลลัพธ์ที่ดีขึ้น เริ่มต้นด้วยไฟล์ notebook.ipynb ที่ว่างเปล่าในโฟลเดอร์รากนี้
สิ่งแรกที่ต้องติดตั้งคือ imblearn ซึ่งเป็นแพ็กเกจ Scikit-learn ที่จะช่วยให้คุณปรับสมดุลข้อมูลได้ดีขึ้น (คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับงานนี้ในอีกสักครู่)
-
เพื่อติดตั้ง
imblearn
ให้รันpip install
ดังนี้:pip install imblearn
-
นำเข้าแพ็กเกจที่คุณต้องการเพื่อดึงข้อมูลและแสดงภาพ นอกจากนี้ให้นำเข้า
SMOTE
จากimblearn
import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np from imblearn.over_sampling import SMOTE
ตอนนี้คุณพร้อมที่จะนำเข้าข้อมูลในขั้นตอนถัดไปแล้ว
-
งานถัดไปคือการนำเข้าข้อมูล:
df = pd.read_csv('../data/cuisines.csv')
การใช้
read_csv()
จะอ่านเนื้อหาของไฟล์ csv cusines.csv และวางไว้ในตัวแปรdf
-
ตรวจสอบรูปร่างของข้อมูล:
df.head()
ห้าบรรทัดแรกมีลักษณะดังนี้:
| | 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 |
-
รับข้อมูลเกี่ยวกับข้อมูลนี้โดยเรียก
info()
:df.info()
ผลลัพธ์ของคุณจะคล้ายกับ:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 2448 entries, 0 to 2447 Columns: 385 entries, Unnamed: 0 to zucchini dtypes: int64(384), object(1) memory usage: 7.2+ MB
แบบฝึกหัด - เรียนรู้เกี่ยวกับอาหาร
ตอนนี้งานเริ่มน่าสนใจมากขึ้น ลองค้นพบการกระจายของข้อมูลต่ออาหาร
-
แสดงข้อมูลเป็นแถบโดยเรียก
barh()
:df.cuisine.value_counts().plot.barh()
มีจำนวนอาหารที่จำกัด แต่การกระจายข้อมูลไม่เท่ากัน คุณสามารถแก้ไขได้! ก่อนทำเช่นนั้น ลองสำรวจเพิ่มเติมเล็กน้อย
-
ค้นหาว่ามีข้อมูลเท่าใดต่ออาหารและพิมพ์ออกมา:
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}')
ผลลัพธ์มีลักษณะดังนี้:
thai df: (289, 385) japanese df: (320, 385) chinese df: (442, 385) indian df: (598, 385) korean df: (799, 385)
ค้นพบส่วนผสม
ตอนนี้คุณสามารถเจาะลึกลงไปในข้อมูลและเรียนรู้ว่าส่วนผสมทั่วไปต่ออาหารคืออะไร คุณควรลบข้อมูลที่เกิดซ้ำซึ่งสร้างความสับสนระหว่างอาหาร ดังนั้นลองเรียนรู้เกี่ยวกับปัญหานี้
-
สร้างฟังก์ชัน
create_ingredient()
ใน Python เพื่อสร้าง dataframe ของส่วนผสม ฟังก์ชันนี้จะเริ่มต้นด้วยการลบคอลัมน์ที่ไม่เป็นประโยชน์และจัดเรียงส่วนผสมตามจำนวน: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
ตอนนี้คุณสามารถใช้ฟังก์ชันนั้นเพื่อดูแนวคิดเกี่ยวกับส่วนผสมยอดนิยมสิบอันดับแรกต่ออาหาร
-
เรียก
create_ingredient()
และแสดงภาพโดยเรียกbarh()
:thai_ingredient_df = create_ingredient_df(thai_df) thai_ingredient_df.head(10).plot.barh()
-
ทำเช่นเดียวกันสำหรับข้อมูลญี่ปุ่น:
japanese_ingredient_df = create_ingredient_df(japanese_df) japanese_ingredient_df.head(10).plot.barh()
-
ตอนนี้สำหรับส่วนผสมของจีน:
chinese_ingredient_df = create_ingredient_df(chinese_df) chinese_ingredient_df.head(10).plot.barh()
-
แสดงภาพส่วนผสมของอินเดีย:
indian_ingredient_df = create_ingredient_df(indian_df) indian_ingredient_df.head(10).plot.barh()
-
สุดท้าย แสดงภาพส่วนผสมของเกาหลี:
korean_ingredient_df = create_ingredient_df(korean_df) korean_ingredient_df.head(10).plot.barh()
-
ตอนนี้ ลบส่วนผสมที่พบมากที่สุดที่สร้างความสับสนระหว่างอาหารที่แตกต่างกัน โดยเรียก
drop()
:ทุกคนชอบข้าว กระเทียม และขิง!
feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1) labels_df = df.cuisine #.unique() feature_df.head()
ปรับสมดุลชุดข้อมูล
ตอนนี้คุณได้ทำความสะอาดข้อมูลแล้ว ใช้ SMOTE - "เทคนิคการสุ่มตัวอย่างชนกลุ่มน้อยแบบสังเคราะห์" - เพื่อปรับสมดุลข้อมูล
-
เรียก
fit_resample()
กลยุทธ์นี้สร้างตัวอย่างใหม่โดยการแทรกแซงoversample = SMOTE() transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df)
โดยการปรับสมดุลข้อมูล คุณจะได้ผลลัพธ์ที่ดีขึ้นเมื่อจำแนกข้อมูล ลองคิดถึงการจำแนกประเภทแบบไบนารี หากข้อมูลส่วนใหญ่ของคุณเป็นคลาสเดียว โมเดล ML จะทำนายคลาสนั้นบ่อยขึ้น เพียงเพราะมีข้อมูลสำหรับมันมากกว่า การปรับสมดุลข้อมูลจะช่วยลบความไม่สมดุลนี้
-
ตอนนี้คุณสามารถตรวจสอบจำนวนป้ายกำกับต่อส่วนผสม:
print(f'new label count: {transformed_label_df.value_counts()}') print(f'old label count: {df.cuisine.value_counts()}')
ผลลัพธ์ของคุณมีลักษณะดังนี้:
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
ข้อมูลสะอาด สมดุล และน่ากินมาก!
-
ขั้นตอนสุดท้ายคือการบันทึกข้อมูลที่สมดุลของคุณ รวมถึงป้ายกำกับและคุณสมบัติ ลงใน dataframe ใหม่ที่สามารถส่งออกไปยังไฟล์:
transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer')
-
คุณสามารถดูข้อมูลอีกครั้งโดยใช้
transformed_df.head()
และtransformed_df.info()
บันทึกสำเนาของข้อมูลนี้เพื่อใช้ในบทเรียนในอนาคต:transformed_df.head() transformed_df.info() transformed_df.to_csv("../data/cleaned_cuisines.csv")
CSV ใหม่ที่สดนี้สามารถพบได้ในโฟลเดอร์ข้อมูลราก
🚀ความท้าทาย
หลักสูตรนี้มีชุดข้อมูลที่น่าสนใจหลายชุด ลองค้นหาในโฟลเดอร์ data
และดูว่ามีชุดข้อมูลใดที่เหมาะสมสำหรับการจำแนกประเภทแบบไบนารีหรือหลายคลาส? คุณจะถามคำถามอะไรจากชุดข้อมูลนี้?
แบบทดสอบหลังบทเรียน
ทบทวนและศึกษาด้วยตนเอง
สำรวจ API ของ SMOTE กรณีการใช้งานใดที่เหมาะสมที่สุดสำหรับมัน? ปัญหาใดที่มันแก้ไข?
งานที่ได้รับมอบหมาย
ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามให้การแปลมีความถูกต้องมากที่สุด แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษาจากผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้