Skip to content

Latest commit

 

History

History
246 lines (168 loc) · 23.5 KB

File metadata and controls

246 lines (168 loc) · 23.5 KB

ตัวจำแนกอาหารประจำชาติ 1

ในบทเรียนนี้ คุณจะใช้ชุดข้อมูลที่คุณบันทึกไว้จากบทเรียนก่อนหน้า ซึ่งเต็มไปด้วยข้อมูลที่สมดุลและสะอาดทั้งหมดเกี่ยวกับอาหารประจำชาติ

คุณจะใช้ชุดข้อมูลนี้กับตัวจำแนกประเภทหลากหลายแบบเพื่อ ทำนายอาหารประจำชาติที่กำหนดโดยอิงจากกลุ่มของส่วนผสม ในขณะทำเช่นนั้น คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับวิธีต่างๆ ที่อัลกอริทึมสามารถนำมาใช้ในงานจำแนกประเภทได้

การเตรียมตัว

สมมติว่าคุณทำ บทเรียน 1 เสร็จแล้ว ให้ตรวจสอบให้แน่ใจว่าไฟล์ cleaned_cuisines.csv มีอยู่ในโฟลเดอร์ราก /data สำหรับบทเรียนเหล่านี้สี่บท

แบบฝึกหัด - ทำนายอาหารประจำชาติ

  1. ทำงานในไฟล์ notebook.ipynb ของบทเรียนนี้ ให้นำเข้าไฟล์นั้นพร้อมกับไลบรารี Pandas:

    import pandas as pd
    cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv")
    cuisines_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 0 indian 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
1 1 indian 1 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2 2 indian 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
3 3 indian 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
4 4 indian 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 1 0
  1. ตอนนี้ ให้นำเข้าไลบรารีเพิ่มเติมหลายตัว:

    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import train_test_split, cross_val_score
    from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
    from sklearn.svm import SVC
    import numpy as np
  2. แบ่งแกน X และ y เป็นสอง dataframes สำหรับการฝึกอบรม โดย ที่ cuisine จะเป็น dataframe ของป้ายกำกับ:

    cuisines_label_df = cuisines_df['cuisine']
    cuisines_label_df.head()

    จะมีลักษณะดังนี้:

    0    indian
    1    indian
    2    indian
    3    indian
    4    indian
    Name: cuisine, dtype: object
    
  3. ลบคอลัมน์ Unnamed: 0 และคอลัมน์ cuisine โดยใช้คำสั่ง drop() แล้วบันทึกข้อมูลที่เหลือเป็นคุณลักษณะที่จะใช้ฝึกอบรม:

    cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)
    cuisines_feature_df.head()

    คุณลักษณะของคุณจะมีลักษณะดังนี้:

almond angelica anise anise_seed apple apple_brandy apricot armagnac artemisia artichoke ... whiskey white_bread white_wine whole_grain_wheat_flour wine wood yam yeast yogurt zucchini
0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 1 0

ตอนนี้คุณพร้อมที่จะฝึกแบบจำลองของคุณแล้ว!

การเลือกตัวจำแนกของคุณ

เมื่อข้อมูลของคุณสะอาดและพร้อมสำหรับการฝึกอบรมแล้ว คุณต้องตัดสินใจว่าจะใช้อัลกอริทึมใดในการทำงานนี้

Scikit-learn จัดกลุ่มงานจำแนกประเภทภายใต้การเรียนรู้แบบมีผู้ดูแล (Supervised Learning) และในประเภทนี้คุณจะพบวิธีหลายวิธีในการจำแนกประเภท ความหลากหลาย นั้นดูน่าหลงใหลในครั้งแรก วิธีการต่อไปนี้ล้วนมีเทคนิคการจำแนกประเภท:

  • แบบจำลองเชิงเส้น
  • Support Vector Machines
  • Stochastic Gradient Descent
  • Nearest Neighbors
  • Gaussian Processes
  • ต้นไม้ตัดสินใจ (Decision Trees)
  • วิธีกลุ่ม (Ensemble methods เช่น voting Classifier)
  • อัลกอริทึมมัลติคลาสและมัลติเอาต์พุต (multiclass และ multilabel classification, multiclass-multioutput classification)

คุณยังสามารถใช้ เครือข่ายประสาทเทียมเพื่อจำแนกข้อมูล แต่สิ่งนั้นอยู่นอกขอบเขตของบทเรียนนี้

ควรเลือกตัวจำแนกประเภทใด?

แล้วควรเลือกตัวจำแนกประเภทไหน? โดยปกติแล้ว การทดลองใช้หลายตัวแล้วมองหาผลลัพธ์ที่ดีเป็นวิธีทดสอบ Scikit-learn มีการ เปรียบเทียบเคียงข้างกัน บนชุดข้อมูลที่สร้างขึ้น โดยเปรียบเทียบ KNeighbors, SVC สองวิธี, GaussianProcessClassifier, DecisionTreeClassifier, RandomForestClassifier, MLPClassifier, AdaBoostClassifier, GaussianNB และ QuadraticDiscrinationAnalysis พร้อมแสดงผลลัพธ์ในรูปแบบกราฟ:

comparison of classifiers

กราฟที่สร้างขึ้นในเอกสารของ Scikit-learn

AutoML แก้ปัญหานี้ได้อย่างลงตัวโดยการรันการเปรียบเทียบเหล่านี้ในระบบคลาวด์ ช่วยให้คุณเลือกอัลกอริทึมที่ดีที่สุดสำหรับข้อมูลของคุณ ลองได้ที่นี่ here

วิธีที่ดีกว่า

วิธีที่ดีกว่าการเดาแบบสุ่ม คือการปฏิบัติตามแนวคิดใน ML Cheat sheet ที่ดาวน์โหลดได้ ที่นี่เราค้นพบว่า สำหรับปัญหามัลติคลาสของเรา เรามีตัวเลือกบางอย่าง:

cheatsheet for multiclass problems

ส่วนหนึ่งของ Algorithm Cheat Sheet ของ Microsoft ซึ่งอธิบายตัวเลือกสำหรับการจำแนกประเภทมัลติคลาส

✅ ดาวน์โหลดแผ่นช่วยจำนี้ พิมพ์ออกมา และแขวนไว้บนผนังของคุณ!

การให้เหตุผล

ลองดูว่าเราจะให้เหตุผลเกี่ยวกับวิธีการต่าง ๆ ตามข้อจำกัดที่เรามีได้อย่างไร:

  • เครือข่ายประสาทเทียมหนักเกินไป กล่าวคือชุดข้อมูลของเราสะอาดแต่น้อย และการฝึกสอนทำในเครื่องผ่านโน้ตบุ๊ก เครือข่ายประสาทเทียมจึงหนักเกินไปสำหรับงานนี้
  • ไม่มีตัวจำแนกสองคลาส เราไม่ได้ใช้ตัวจำแนกสองคลาส ดังนั้นจึงตัดเมธอด one-vs-all ออก
  • ต้นไม้ตัดสินใจหรือลอจิสติกส์รีเกรสชันอาจใช้ได้ ต้นไม้ตัดสินใจอาจใช้ได้ หรือ ลอจิสติกส์รีเกรสชันสำหรับข้อมูลมัลติคลาส
  • มัลติคลาส บูสท์เทด ต้นไม้ตัดสินใจแก้ปัญหาที่ต่างออกไป มัลติคลาสบูสท์เทดต้นไม้ตัดสินใจเหมาะสมที่สุดกับงานที่ไม่ใช่แบบพารามิเทริก เช่น งานที่ออกแบบมาเพื่อสร้างการจัดอันดับ ซึ่งจึงไม่เหมาะกับเรา

การใช้ Scikit-learn

เราจะใช้ Scikit-learn ในการวิเคราะห์ข้อมูลของเรา อย่างไรก็ตาม มีหลายวิธีในการใช้ลอจิสติกส์รีเกรสชันใน Scikit-learn ดูที่ พารามิเตอร์ที่ต้องส่ง

โดยทั่วไป มีพารามิเตอร์สำคัญสองตัว - multi_class และ solver - ที่เราต้องระบุ เมื่อเราขอให้ Scikit-learn ทำการลอจิสติกส์รีเกรสชัน ค่า multi_class จะใช้พฤติกรรมเฉพาะ ส่วนค่า solver คืออัลกอริทึมที่ใช้ ไม่ใช่ทุก solver จะจับคู่กับค่า multi_class ได้ทั้งหมด

ตามเอกสาร ในกรณีมัลติคลาส อัลกอริทึมฝึกอบรม:

  • ใช้แผนผัง one-vs-rest (OvR) หากตัวเลือก multi_class ตั้งค่าเป็น ovr
  • ใช้ cross-entropy loss หากตัวเลือก multi_class ตั้งค่าเป็น multinomial (ขณะนี้ตัวเลือก multinomial รองรับเฉพาะ solver ‘lbfgs’, ‘sag’, ‘saga’ และ ‘newton-cg’ เท่านั้น)"

🎓 ‘แผนผัง’ ในที่นี้หมายถึง 'ovr' (one-vs-rest) หรือ 'multinomial' เนื่องจากลอจิสติกส์รีเกรสชันออกแบบมาเพื่อรองรับการจำแนกประเภทแบบไบนารี เทคนิคนั้นช่วยให้มันจัดการกับงานจำแนกประเภทมัลติคลาสได้ดียิ่งขึ้น ที่มา

🎓 ‘solver’ ถูกกำหนดเป็น "อัลกอริทึมที่ใช้ในปัญหาการเพิ่มประสิทธิภาพ" ที่มา.

Scikit-learn มีตารางนี้เพื่ออธิบายว่า solver แต่ละตัวจัดการกับความท้าทายของโครงสร้างข้อมูลประเภทต่าง ๆ อย่างไร:

solvers

แบบฝึกหัด - แบ่งชุดข้อมูล

เราสามารถเน้นที่ลอจิสติกส์รีเกรสชันสำหรับการทดลองฝึกครั้งแรกของเรา เนื่องจากคุณเพิ่งเรียนรู้เกี่ยวกับสิ่งนี้ในบทเรียนก่อนหน้า แบ่งข้อมูลของคุณออกเป็นกลุ่มฝึกและทดสอบโดยเรียก train_test_split():

X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)

แบบฝึกหัด - ใช้ลอจิสติกส์รีเกรสชัน

เนื่องจากคุณใช้กรณีมัลติคลาส คุณต้องเลือกว่าจะใช้ แผนผัง อะไรและจะตั้งค่า solver แบบใด ใช้ LogisticRegression โดยตั้งค่า multi_class และใช้ solver liblinear เพื่อฝึก

  1. สร้างลอจิสติกส์รีเกรสชันโดยตั้งค่า multi_class เป็น ovr และตั้งค่า solver เป็น liblinear:

    lr = LogisticRegression(multi_class='ovr',solver='liblinear')
    model = lr.fit(X_train, np.ravel(y_train))
    
    accuracy = model.score(X_test, y_test)
    print ("Accuracy is {}".format(accuracy))

    ✅ ลองใช้ solver อื่น เช่น lbfgs ซึ่งมักถูกตั้งเป็นค่าดีฟอลต์

    หมายเหตุ ใช้ฟังก์ชัน ravel ของ Pandas เพื่อแปลงข้อมูลให้เป็นแบบแถวเดียวเมื่อจำเป็น

    ความแม่นยำดีมากเกินกว่า 80%!

  2. คุณสามารถดูโมเดลนี้ทำงานโดยทดสอบข้อมูลแถวหนึ่ง (#50):

    print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')
    print(f'cuisine: {y_test.iloc[50]}')

    ผลลัพธ์จะถูกพิมพ์ออกมา:

    ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object')
    cuisine: indian
    

    ✅ ลองแถวอื่นและตรวจสอบผลลัพธ์ดู

  3. สำรวจให้ลึกขึ้น คุณสามารถตรวจสอบความแม่นยำของการทำนายนี้ได้:

    test= X_test.iloc[50].values.reshape(-1, 1).T
    proba = model.predict_proba(test)
    classes = model.classes_
    resultdf = pd.DataFrame(data=proba, columns=classes)
    
    topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])
    topPrediction.head()

    ผลลัพธ์จะถูกพิมพ์ออกมา - อาหารอินเดียเป็นการทำนายที่ดีที่สุด โดยมีความน่าจะเป็นที่ดี:

    0
    indian 0.715851
    chinese 0.229475
    japanese 0.029763
    korean 0.017277
    thai 0.007634

    ✅ คุณอธิบายได้ไหมว่าทำไมโมเดลถึงมั่นใจว่าคืออาหารอินเดีย?

  4. รับรายละเอียดเพิ่มเติมโดยการพิมพ์รายงานการจำแนกประเภท ดังที่คุณทำในบทเรียนการวิเคราะห์การถดถอย:

    y_pred = model.predict(X_test)
    print(classification_report(y_test,y_pred))
    precision recall f1-score support
    chinese 0.73 0.71 0.72 229
    indian 0.91 0.93 0.92 254
    japanese 0.70 0.75 0.72 220
    korean 0.86 0.76 0.81 242
    thai 0.79 0.85 0.82 254
    accuracy 0.80 1199
    macro avg 0.80 0.80 0.80 1199
    weighted avg 0.80 0.80 0.80 1199

🚀ท้าทาย

ในบทเรียนนี้ คุณใช้ข้อมูลที่ทำความสะอาดแล้วเพื่อสร้างโมเดลแมชชีนเลิร์นนิงที่สามารถทำนายอาหารประจำชาติจากชุดส่วนผสมต่างๆ ใช้เวลาอ่านผ่านตัวเลือกมากมายที่ Scikit-learn มีให้เพื่อจำแนกข้อมูล ทำความเข้าใจให้ลึกซึ้งเกี่ยวกับแนวคิด 'solver' เพื่อเข้าใจสิ่งที่เกิดขึ้นเบื้องหลัง

ทบทวน & ศึกษาด้วยตัวเอง

ขุดลึกเข้าไปในคณิตศาสตร์เบื้องหลังการถดถอยลอจิสติกใน บทเรียนนี้

การบ้าน

ศึกษาตัวแก้ปัญหา


ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator ขณะที่เราพยายามให้ความถูกต้อง โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาต้นฉบับควรถูกพิจารณาเป็นแหล่งข้อมูลที่ถูกต้อง สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้การแปลโดยมืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดใด ๆ ที่เกิดจากการใช้การแปลนี้