|
|
3 weeks ago | |
|---|---|---|
| .. | ||
| solution | 3 months ago | |
| README.md | 3 weeks ago | |
| assignment.md | 3 months ago | |
| notebook.ipynb | 8 months ago | |
README.md
طبقهبندهای آشپزی ۱
در این درس، شما از مجموعه دادهای که در درس قبلی ذخیره کردید استفاده خواهید کرد، مجموعه دادهای متعادل و تمیز که تماماً درباره آشپزیهاست.
شما از این مجموعه داده با انواع مختلف طبقهبندها برای پیشبینی یک آشپزی ملی مشخص بر اساس گروهی از مواد اولیه استفاده خواهید کرد. در حین انجام این کار، بیشتر با برخی از روشهای استفاده از الگوریتمها برای وظایف طبقهبندی آشنا خواهید شد.
آزمون پیشازدرس
آمادهسازی
فرض کنید درس درس ۱ را کامل کردهاید، اطمینان حاصل کنید که یک فایل cleaned_cuisines.csv در پوشه ریشه /data برای این چهار درس وجود دارد.
تمرین - پیشبینی یک آشپزی ملی
۱. در پوشه این درس با نام notebook.ipynb، آن فایل را همراه با کتابخانه Pandas وارد کنید:
```python
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 |
۱. حال، چند کتابخانه دیگر وارد کنید:
```python
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
```
۱. مختصات X و y را به دو دیتافریم برای آموزش تقسیم کنید. cuisine میتواند دیتافریم برچسبها باشد:
```python
cuisines_label_df = cuisines_df['cuisine']
cuisines_label_df.head()
```
به این شکل خواهد بود:
```output
0 indian
1 indian
2 indian
3 indian
4 indian
Name: cuisine, dtype: object
```
۱. آن ستون Unnamed: 0 و ستون cuisine را با فراخوانی drop() حذف کنید. بقیه دادهها را بهعنوان ویژگیهای قابل آموزش ذخیره کنید:
```python
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 طبقهبندی را در زیر مجموعه یادگیری نظارتشده دستهبندی میکند، و در آن دسته چندین روش برای طبقهبندی خواهید یافت. تنوع در نگاه اول بسیار گیجکننده است. روشهای زیر همه شامل تکنیکهای طبقهبندی هستند:
- مدلهای خطی
- ماشینهای بردار پشتیبان
- نزول گرادیان تصادفی
- نزدیکترین همسایهها
- فرآیندهای گاوسی
- درختهای تصمیم
- روشهای مجموعهای (voting Classifier)
- الگوریتمهای چندکلاسه و چندخروجی (طبقهبندی چندکلاسه و چندبرچسبه، طبقهبندی چندکلاسه-چندخروجی)
همچنین میتوانید از شبکههای عصبی برای طبقهبندی دادهها استفاده کنید، اما این خارج از محدوده این درس است.
کدام طبقهبند را انتخاب کنیم؟
پس، کدام طبقهبند را باید انتخاب کنید؟ اغلب، اجرای چند تا و جستجو برای نتیجه خوب روش خوبی برای آزمایش است. Scikit-learn یک مقایسه کنار هم روی یک مجموعه داده ایجاد شده ارائه میدهد که KNeighbors، دو روش SVC، GaussianProcessClassifier، DecisionTreeClassifier، RandomForestClassifier، MLPClassifier، AdaBoostClassifier، GaussianNB و QuadraticDiscrinationAnalysis را مقایسه کرده و نتایج را بهصورت تصویری نشان میدهد:
نمودارهای تولید شده در مستندات Scikit-learn
AutoML این مشکل را به خوبی با اجرای این مقایسهها در فضای ابری حل میکند، که به شما امکان میدهد بهترین الگوریتم را برای دادههای خود انتخاب کنید. آن را اینجا امتحان کنید.
رویکردی بهتر
یک روش بهتر از حدس زدن کورکورانه، پیروی از ایدههای این برگه تقلب یادگیری ماشین قابل دانلود است. در اینجا، کشف میکنیم که برای مسئله چندکلاسه خود، چند انتخاب داریم:
بخشی از برگه تقلب الگوریتم مایکروسافت، جزئیات گزینههای طبقهبندی چندکلاسه
✅ این برگه تقلب را دانلود، چاپ کنید و روی دیوار خود آویزان کنید!
استدلال
بیایید ببینیم آیا میتوانیم رویکردهای مختلف را با توجه به محدودیتهایی که داریم استدلال کنیم:
- شبکههای عصبی خیلی سنگین هستند. با توجه به مجموعه داده تمیز اما کوچک ما و اینکه آموزش به صورت محلی از طریق نوتبوکها انجام میشود، شبکههای عصبی برای این کار سنگین است.
- طبقهبند دوکلاسه نداریم. ما از طبقهبند دوکلاسه استفاده نمیکنیم، پس روش یکدرمیان را کنار میگذاریم.
- درخت تصمیم یا رگرسیون لجستیک میتواند کار کند. درخت تصمیم ممکن است موثر باشد، یا رگرسیون لجستیک برای دادههای چندکلاسه.
- درخت تصمیم تقویتشده چندکلاسه مسئله متفاوتی را حل میکند. درخت تصمیم تقویتشده چندکلاسه بیشتر برای کارهای غیرپارامتریک مناسب است، مثلاً وظایف طراحیشده برای ساخت رتبهبندی، پس برای ما مفید نیست.
استفاده از Scikit-learn
ما از Scikit-learn برای تحلیل دادههای خود استفاده خواهیم کرد. اما راههای زیادی برای استفاده از رگرسیون لجستیک در Scikit-learn وجود دارد. نگاهی به پارامترهایی که باید ارسال کنید بیندازید.
اساساً دو پارامتر مهم - multi_class و solver - وجود دارد که باید مشخص کنیم وقتی از Scikit-learn میخواهیم رگرسیون لجستیک انجام دهد. مقدار multi_class نوع خاصی از رفتار را اعمال میکند. مقدار solver الگوریتم مورد استفاده است. همه حلکنندهها نمیتوانند با همه multi_classها جفت شوند.
طبق مستندات، در حالت چندکلاسه، الگوریتم آموزش:
- از طرح یکدرمیان (OvR) استفاده میکند، اگر گزینه
multi_classرویovrتنظیم شود - از تابع هزینه آنتروپی متقاطع استفاده میکند، اگر گزینه
multi_classرویmultinomialتنظیم شود. (فعلاً گزینهmultinomialفقط توسط حلکنندههای ‘lbfgs’, ‘sag’, ‘saga’ و ‘newton-cg’ پشتیبانی میشود.)"
🎓 این 'طرح' اینجا میتواند 'ovr' (یکدرمیان) یا 'multinomial' باشد. از آنجا که رگرسیون لجستیک در اصل برای طبقهبندی دودویی طراحی شده است، این طرحها به آن کمک میکنند تا بهتر وظایف طبقهبندی چندکلاسه را مدیریت کند. منبع
🎓 'حلکننده' به عنوان "الگوریتمی که در مسئله بهینهسازی استفاده میشود" تعریف شده است. منبع
Scikit-learn این جدول را برای توضیح چگونگی برخورد حلکنندهها با چالشهای مختلف ناشی از ساختارهای مختلف داده ارائه میدهد:
تمرین - تقسیم دادهها
ما میتوانیم برای اولین آزمایش آموزش خود روی رگرسیون لجستیک تمرکز کنیم، چون اخیراً درباره آن در درس قبلی یاد گرفتید.
دادههای خود را به گروههای آموزش و تست تقسیم کنید با فراخوانی train_test_split():
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
تمرین - اعمال رگرسیون لجستیک
از آنجا که شما از حالت چندکلاسه استفاده میکنید، باید انتخاب کنید چه طرحی استفاده شود و چه حلکنندهای تنظیم شود. از LogisticRegression با تنظیمات چندکلاسه و حلکننده liblinear برای آموزش استفاده کنید.
۱. یک رگرسیون لجستیک با multi_class برابر ovr و حلکننده برابر liblinear بسازید:
```python
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))
```
✅ یک حلکننده دیگر مثل `lbfgs` که معمولا به صورت پیشفرض تنظیم میشود را امتحان کنید
> توجه کنید، از تابع [`ravel`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.ravel.html) پانداها برای صاف کردن دادهها در صورت نیاز استفاده کنید.
دقت بالای **۸۰٪** خوبی دارد!
۱. میتوانید این مدل را با تست یک سطر داده (#50) در عمل ببینید:
```python
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
✅ شماره ردیف دیگری را امتحان کنید و نتایج را بررسی کنید
-
کاوش عمیقتر، میتوانید دقت این پیشبینی را بررسی کنید:
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 ✅ میتوانید توضیح دهید چرا مدل تقریباً مطمئن است که این غذاهای هندی است؟
-
با چاپ گزارش طبقهبندی، همانطور که در درسهای رگرسیون انجام دادید، جزئیات بیشتری بگیرید:
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) بپردازید تا بفهمید پشت صحنه چه میگذرد.
آزمون پس از درس
بازبینی و مطالعه خودآموز
کمی بیشتر در ریاضیات پشت رگرسیون لجستیک در این درس عمیق شوید.
تکلیف
سلب مسئولیت:
این سند با استفاده از سرویس ترجمه ماشینی Co-op Translator ترجمه شده است. در حالی که ما در تلاش برای دقت هستیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نواقصی باشند. سند اصلی به زبان بومی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات مهم، ترجمه حرفهای انسانی توصیه میشود. ما مسئول هیچ گونه سوءتفاهم یا برداشت نادرستی که از استفاده از این ترجمه به وجود آید، نیستیم.


