طبقه‌بندی چندکلاسه و چندبرچسبی | تحلیل خطا در MNIST

طبقه‌بندی چندکلاسه، تحلیل خطا و سامانه‌های چندبرچسبی

توسط admin | گروه هوش مصنوعی | 1405/06/01

نظرات 0

طبقه‌بندی چندکلاسه، تحلیل خطا و سامانه‌های چندبرچسبی

عنوان اصلی
Performance Measures; Multiclass Classification; Error Analysis; Multilabel Classification; Multioutput Classification; Exercises
عنوان ترجمه‌شده
طبقه‌بندی چندکلاسه، تحلیل خطا و سامانه‌های چندبرچسبی
اثر
Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow - ویرایش سوم
نویسنده
Aurelien Geron
سمت/سابقهٔ نویسنده
مشاور یادگیری ماشین؛ مدیر پیشین تیم طبقه‌بندی ویدئوی YouTube
زبان اصلی
انگلیسی
صفحات منبع
15-28 از PDF فعلی؛ صفحات چاپی کتاب 117-130
وضعیت حقوق
حق‌نشر اثر اصلی متعلق به صاحب اثر است؛ کاربر حق ترجمه و استفاده/بازنشر را برای این پردازش تأیید کرده است.
تاریخ ترجمه
1405/06/01 / 2026-08-23
اعتبار ترجمه
ترجمه با کمک هوش مصنوعی

انتخاب میان منحنی Precision/Recall و ROC

از آنجا که منحنی ROC بسیار شبیه منحنی Precision/Recall است، انتخاب میان آن‌ها مهم است. یک قاعدهٔ عملی این است که وقتی کلاس مثبت نادر است یا مثبت‌های کاذب برای شما مهم‌تر از منفی‌های کاذب‌اند، منحنی PR را ترجیح دهید؛ در غیر این صورت ROC گزینهٔ مناسبی است. در مثال تشخیص رقم ۵، نگاه‌کردن به ROC و ROC AUC ممکن است تصور بسیار خوبی از مدل بدهد، اما یکی از علت‌ها این است که تعداد ۵ها نسبت به غیر ۵ها کم است. منحنی PR واضح‌تر نشان می‌دهد که هنوز جای پیشرفت وجود دارد و منحنی می‌تواند به گوشهٔ بالا-راست نزدیک‌تر شود.

مقایسه با RandomForestClassifier

اکنون یک RandomForestClassifier می‌سازیم تا منحنی PR و امتیاز F1 آن را با SGDClassifier مقایسه کنیم:

from sklearn.ensemble import RandomForestClassifier
forest_clf = RandomForestClassifier(random_state=42)

تابع precision_recall_curve() برای هر نمونه به برچسب و یک امتیاز نیاز دارد. RandomForestClassifier به‌دلیل سازوکارش decision_function() ندارد، اما predict_proba() احتمال کلاس‌ها را برمی‌گرداند. بنابراین می‌توان احتمال کلاس مثبت را به‌عنوان امتیاز استفاده کرد. با cross_val_predict() طبقه‌بند را در Cross-Validation آموزش می‌دهیم و برای همهٔ تصاویر احتمال کلاس‌ها را می‌گیریم:

y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,
                                    method="predict_proba")

احتمال دو تصویر نخست:

>>> y_probas_forest[:2]
array([[0.11, 0.89],
       [0.99, 0.01]])

مدل برای تصویر نخست ۸۹ درصد احتمال مثبت‌بودن و برای تصویر دوم ۹۹ درصد احتمال منفی‌بودن تخمین زده است. چون هر تصویر یا مثبت است یا منفی، مجموع احتمال‌های هر سطر ۱۰۰ درصد است.

ستون دوم احتمال کلاس مثبت است؛ آن را برای ساخت منحنی PR استفاده می‌کنیم:

y_scores_forest = y_probas_forest[:, 1]
precisions_forest, recalls_forest, thresholds_forest = precision_recall_curve(
    y_train_5, y_scores_forest)

اکنون منحنی PR جنگل تصادفی و SGD را کنار هم رسم می‌کنیم:

plt.plot(recalls_forest, precisions_forest, "b-", linewidth=2,
         label="Random Forest")
plt.plot(recalls, precisions, "--", linewidth=2, label="SGD")
[...] # beautify the figure: add labels, grid, and legend
plt.show()
مقایسه منحنی Precision Recall جنگل تصادفی و SGD
شکل ۳-۸. مقایسهٔ منحنی‌های PR؛ جنگل تصادفی بهتر است، زیرا منحنی آن به گوشهٔ بالا-راست نزدیک‌تر و سطح زیر منحنی آن بزرگ‌تر است.

امتیاز F1 و ROC AUC جنگل تصادفی نیز به‌طور محسوسی بهتر است:

>>> y_train_pred_forest = y_probas_forest[:, 1] >= 0.5 # positive proba ≥ 50%
>>> f1_score(y_train_5, y_train_pred_forest)
0.9242275142688446
>>> roc_auc_score(y_train_5, y_scores_forest)
0.9983436731328145

اگر Precision و Recall را نیز اندازه بگیرید، تقریباً به ۹۹٫۱ درصد Precision و ۸۶٫۶ درصد Recall می‌رسید. اکنون شیوهٔ آموزش طبقه‌بند دودویی، انتخاب معیار مناسب، ارزیابی با Cross-Validation، تنظیم موازنهٔ Precision/Recall و مقایسهٔ مدل‌ها با چند معیار و منحنی را می‌دانید. وقت آن است که بیش از یک رقم را تشخیص دهیم.

طبقه‌بندی چندکلاسه

طبقه‌بند دودویی فقط دو کلاس را از هم جدا می‌کند، اما طبقه‌بند چندکلاسه - که گاهی Multinomial Classifier نیز نامیده می‌شود - قادر است بیش از دو کلاس را تشخیص دهد. بعضی طبقه‌بندهای Scikit-Learn مانند LogisticRegression، RandomForestClassifier و GaussianNB به‌صورت بومی چندکلاسه هستند. بعضی دیگر، مانند SGDClassifier و SVC، اساساً دودویی‌اند، اما می‌توان با چند راهبرد از چند طبقه‌بند دودویی یک سامانهٔ چندکلاسه ساخت.

راهبرد One-versus-the-Rest

برای تشخیص ارقام ۰ تا ۹ می‌توان ۱۰ طبقه‌بند دودویی ساخت: تشخیص‌دهندهٔ ۰، تشخیص‌دهندهٔ ۱ و به همین ترتیب. هنگام طبقه‌بندی یک تصویر، امتیاز تصمیم همهٔ طبقه‌بندها گرفته می‌شود و کلاسی انتخاب می‌شود که طبقه‌بند مربوط به آن بیشترین امتیاز را داده است. این روش One-versus-the-Rest (OvR) یا گاهی One-versus-All (OvA) نام دارد.

راهبرد One-versus-One

روش دیگر آموزش یک طبقه‌بند دودویی برای هر جفت کلاس است: یکی برای ۰ در برابر ۱، دیگری برای ۰ در برابر ۲، یکی برای ۱ در برابر ۲ و ... . این روش One-versus-One (OvO) نام دارد. با N کلاس به N × (N − 1) / 2 طبقه‌بند نیاز است. برای MNIST یعنی ۴۵ طبقه‌بند دودویی. هنگام پیش‌بینی، تصویر از همهٔ ۴۵ طبقه‌بند عبور می‌کند و کلاسی انتخاب می‌شود که بیشترین «دوئل» را برده باشد.

مزیت اصلی OvO این است که هر طبقه‌بند فقط روی نمونه‌های دو کلاس مربوط آموزش می‌بیند. الگوریتم‌هایی مانند SVM با افزایش اندازهٔ مجموعهٔ آموزشی به‌خوبی مقیاس نمی‌شوند، بنابراین OvO برای آن‌ها می‌تواند سریع‌تر باشد. برای بیشتر الگوریتم‌های دودویی دیگر، OvR معمولاً ترجیح داده می‌شود.

Scikit-Learn وقتی متوجه شود الگوریتم دودویی برای مسئلهٔ چندکلاسه استفاده شده، بسته به الگوریتم به‌طور خودکار OvR یا OvO را اجرا می‌کند. مثلاً SVC را فقط روی ۲۰۰۰ تصویر نخست آموزش می‌دهیم تا زمان آموزش زیاد نشود:

from sklearn.svm import SVC

svm_clf = SVC(random_state=42)
svm_clf.fit(X_train[:2000], y_train[:2000]) # y_train, not y_train_5

در اینجا هدف اصلی ۰ تا ۹ به مدل داده شده است، نه هدف دودویی «۵ در برابر بقیه». چون ۱۰ کلاس داریم، Scikit-Learn از OvO استفاده کرده و ۴۵ طبقه‌بند ساخته است:

>>> svm_clf.predict([some_digit])
array(['5'], dtype=object)

این پیش‌بینی درست است. در پشت صحنه، ۴۵ پیش‌بینی انجام شده و کلاسی که بیشترین دوئل را برده انتخاب شده است. decision_function() برای هر نمونه ۱۰ امتیاز برمی‌گرداند، یکی برای هر کلاس. امتیاز هر کلاس تعداد دوئل‌های برده‌شده به‌اضافه یا منهای اصلاح کوچکی - حداکثر حدود ۰٫۳۳ - برای شکستن تساوی است:

>>> some_digit_scores = svm_clf.decision_function([some_digit])
>>> some_digit_scores.round(2)
array([[ 3.79,  0.73,  6.06,  8.3 , -0.29,  9.3 ,  1.75,  2.77,  7.21,
         4.82]])
>>> class_id = some_digit_scores.argmax()
>>> class_id
5

بیشترین امتیاز ۹٫۳ است و به کلاس ۵ مربوط می‌شود. پس از آموزش، فهرست کلاس‌های هدف در classes_ ذخیره می‌شود. در MNIST به‌طور اتفاقی Index هر کلاس با مقدار خودش برابر است، اما در حالت عمومی باید برچسب را از آرایه پیدا کنید:

>>> svm_clf.classes_
array(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], dtype=object)
>>> svm_clf.classes_[class_id]
'5'

اگر بخواهید راهبرد را صریحاً تحمیل کنید می‌توانید از OneVsOneClassifier یا OneVsRestClassifier استفاده کنید. نمونهٔ OvR با SVC:

from sklearn.multiclass import OneVsRestClassifier

ovr_clf = OneVsRestClassifier(SVC(random_state=42))
ovr_clf.fit(X_train[:2000], y_train[:2000])

>>> ovr_clf.predict([some_digit])
array(['5'], dtype='<U1')
>>> len(ovr_clf.estimators_)
10

SGDClassifier در مسئلهٔ چندکلاسه

آموزش SGDClassifier روی برچسب‌های ۰ تا ۹ نیز مستقیم است:

>>> sgd_clf = SGDClassifier(random_state=42)
>>> sgd_clf.fit(X_train, y_train)
>>> sgd_clf.predict([some_digit])
array(['3'], dtype='<U1')

این بار پیش‌بینی اشتباه است؛ خطا طبیعی است. Scikit-Learn در این حالت OvR اجرا کرده و ۱۰ طبقه‌بند دودویی ساخته است. امتیازهای کلاس‌ها:

>>> sgd_clf.decision_function([some_digit]).round()
array([[-31893., -34420.,  -9531.,   1824., -22320.,  -1386., -26189.,
        -16148.,  -4604., -12051.]])

مدل به پیش‌بینی خود اطمینان زیادی ندارد: تقریباً همهٔ امتیازها بسیار منفی‌اند، کلاس ۳ امتیاز مثبت ۱۸۲۴ دارد و کلاس ۵ با منفی ۱۳۸۶ چندان دور نیست. ارزیابی روی Cross-Validation سه‌تایی:

>>> cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring="accuracy")
array([0.87365, 0.85835, 0.8689 ])

در همهٔ Foldها Accuracy بیش از ۸۵٫۸ درصد است؛ درحالی‌که طبقه‌بند تصادفی برای ۱۰ کلاس حدود ۱۰ درصد می‌گیرد. فقط با Scale کردن ورودی‌ها، Accuracy به بیش از ۸۹٫۱ درصد می‌رسد:

>>> from sklearn.preprocessing import StandardScaler
>>> scaler = StandardScaler()
>>> X_train_scaled = scaler.fit_transform(X_train.astype("float64"))
>>> cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring="accuracy")
array([0.8983, 0.891 , 0.9018])

تحلیل خطا

در پروژهٔ واقعی، در این مرحله گزینه‌های آماده‌سازی داده را بررسی می‌کردید، مدل‌های متعدد را می‌آزمودید، بهترین‌ها را در فهرست کوتاه قرار می‌دادید، فراپارامترها را با GridSearchCV تنظیم می‌کردید و تا حد امکان فرایند را خودکار می‌ساختید. فرض می‌کنیم مدل امیدوارکننده‌ای پیدا شده و اکنون می‌خواهیم علت خطاهایش را بشناسیم.

ابتدا ماتریس درهم‌ریختگی را بررسی می‌کنیم. با cross_val_predict() پیش‌بینی‌ها را می‌سازیم و سپس ConfusionMatrixDisplay.from_predictions() را به کار می‌بریم:

from sklearn.metrics import ConfusionMatrixDisplay

y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)
ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred)
plt.show()

ماتریس سمت چپ شکل ۳-۹ عمدتاً قطر روشنی دارد که نشان‌دهندهٔ طبقه‌بندی درست بسیاری از تصاویر است. خانهٔ ۵ روی قطر کمی متفاوت دیده می‌شود؛ این می‌تواند به‌علت خطای بیشتر روی رقم ۵ یا کمتر بودن تعداد ۵ها باشد. برای رفع ابهام، ماتریس را با تقسیم هر مقدار بر تعداد تصاویر کلاس واقعی همان سطر نرمال می‌کنیم:

ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred,
                                        normalize="true", values_format=".0%")
plt.show()
ماتریس درهم‌ریختگی و نسخه نرمال شده سطری
شکل ۳-۹. ماتریس درهم‌ریختگی خام در سمت چپ و همان ماتریس نرمال‌شده بر اساس سطر در سمت راست

اکنون مشخص است که فقط ۸۲ درصد تصاویر ۵ درست طبقه‌بندی شده‌اند. رایج‌ترین خطا برای ۵ها، تشخیص آن‌ها به‌عنوان ۸ است و این برای ۱۰ درصد همهٔ ۵ها رخ می‌دهد. در مقابل فقط ۲ درصد ۸ها به‌عنوان ۵ اشتباه شده‌اند؛ ماتریس درهم‌ریختگی لزوماً متقارن نیست.

برای برجسته‌کردن خطاها می‌توان وزن پیش‌بینی‌های درست را صفر کرد:

sample_weight = (y_train_pred != y_train)
ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred,
                                        sample_weight=sample_weight,
                                        normalize="true", values_format=".0%")
plt.show()

و می‌توان به‌جای نرمال‌سازی بر اساس سطر، با normalize="pred" بر اساس ستون نرمال کرد.

ماتریس خطاهای نرمال شده بر اساس سطر و ستون
شکل ۳-۱۰. فقط خطاها؛ نرمال‌شده بر اساس سطر در سمت چپ و بر اساس ستون در سمت راست

ستون کلاس ۸ در ماتریس خطاها بسیار روشن است؛ یعنی بسیاری از ارقام به‌اشتباه ۸ تشخیص داده می‌شوند. دقت کنید درصدها در ماتریسی که فقط خطاها را نشان می‌دهد نسبت به کل نمونه‌ها نیستند. برای مثال ۳۶ درصد در سطر ۷ و ستون ۹ یعنی ۳۶ درصد «خطاهای مربوط به ۷» به شکل ۹ بوده‌اند، نه اینکه ۳۶ درصد همهٔ ۷ها اشتباه شده باشند. در ماتریس کامل می‌بینیم فقط حدود ۳ درصد ۷ها به‌عنوان ۹ اشتباه شده‌اند. در نرمال‌سازی ستونی نیز می‌توان دید چه سهمی از پیش‌بینی‌های اشتباه یک کلاس واقعاً متعلق به کلاس دیگر بوده‌اند.

تحلیل ماتریس راه‌های بهبود را نشان می‌دهد. اینجا باید روی کاهش «۸های کاذب» تمرکز کرد؛ مثلاً دادهٔ آموزشی بیشتری از ارقامی جمع کرد که شبیه ۸ هستند اما ۸ نیستند، ویژگی‌هایی مانند تعداد حلقه‌های بسته ساخت - ۸ دو حلقه دارد، ۶ یک حلقه و ۵ هیچ حلقه - یا با ابزارهایی مانند Scikit-Image، Pillow یا OpenCV تصاویر را پیش‌پردازش کرد تا الگوهای مهم برجسته شوند.

تحلیل خطاهای منفرد

بررسی نمونه‌های خطا نیز برای فهم رفتار مدل مفید است. نمونه‌هایی از ۳ و ۵ را در قالب ماتریس درهم‌ریختگی دسته‌بندی می‌کنیم:

cl_a, cl_b = '3', '5'
X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]
X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]
X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]
X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]
[...] # plot all images in X_aa, X_ab, X_ba, X_bb in a confusion matrix style
نمونه‌هایی از ارقام ۳ و ۵ به شکل ماتریس درهم‌ریختگی
شکل ۳-۱۱. برخی تصاویر ۳ و ۵، سازمان‌دهی‌شده مانند ماتریس درهم‌ریختگی

برخی نمونه‌های اشتباه آن‌قدر بد نوشته شده‌اند که انسان نیز به‌سختی آن‌ها را تشخیص می‌دهد، اما بسیاری از اشتباه‌ها برای انسان واضح‌اند. علت این تفاوت آن است که مغز انسان سامانهٔ بسیار پیچیده‌ای برای تشخیص الگو و پیش‌پردازش بینایی دارد. SGDClassifier استفاده‌شده یک مدل خطی ساده است: برای هر کلاس به هر پیکسل وزنی می‌دهد و هنگام دیدن تصویر تازه، شدت پیکسل‌ها را با وزن‌ها جمع می‌کند تا امتیاز هر کلاس را بسازد. چون ۳ و ۵ فقط در چند پیکسل تفاوت دارند، مدل به‌راحتی آن‌ها را اشتباه می‌کند.

تفاوت مهم ۳ و ۵ موقعیت خط کوچکی است که خط بالایی را به قوس پایینی وصل می‌کند. جابه‌جایی یا چرخش اندک تصویر می‌تواند پیش‌بینی را عوض کند. یک راه، مرکزکردن و تصحیح چرخش تصاویر در پیش‌پردازش است؛ راه ساده‌تر این است که نسخه‌های کمی جابه‌جا یا چرخانده‌شده به مجموعهٔ آموزشی اضافه شوند تا مدل نسبت به این تغییرات مقاوم‌تر شود. این روش Data Augmentation نام دارد.

طبقه‌بندی چندبرچسبی

تا اینجا هر نمونه فقط یک کلاس داشت، اما گاهی یک نمونه باید چند کلاس خروجی داشته باشد. مثلاً سامانهٔ تشخیص چهره اگر چند نفر را در یک عکس ببیند باید برای هر فردی که می‌شناسد برچسب جدا بدهد. اگر مدل سه چهرهٔ Alice، Bob و Charlie را بشناسد، تصویر Alice و Charlie باید خروجی [True, False, True] تولید کند. چنین سامانه‌ای «طبقه‌بندی چندبرچسبی» است.

یک مثال ساده با MNIST می‌سازیم: برچسب نخست می‌گوید رقم بزرگ است - ۷، ۸ یا ۹ - و برچسب دوم می‌گوید رقم فرد است:

import numpy as np
from sklearn.neighbors import KNeighborsClassifier

y_train_large = (y_train >= '7')
y_train_odd = (y_train.astype('int8') % 2 == 1)
y_multilabel = np.c_[y_train_large, y_train_odd]

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_multilabel)

اکنون پیش‌بینی دو برچسب می‌دهد:

>>> knn_clf.predict([some_digit])
array([[False,  True]])

برای رقم ۵ درست است: بزرگ نیست و فرد است. ارزیابی طبقه‌بند چندبرچسبی به نیاز پروژه وابسته است. یک روش محاسبهٔ F1 برای هر برچسب و سپس میانگین آن‌هاست:

>>> y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)
>>> f1_score(y_multilabel, y_train_knn_pred, average="macro")
0.976410265560605

این روش فرض می‌کند همهٔ برچسب‌ها اهمیت برابر دارند. اگر بعضی برچسب‌ها نمونهٔ بیشتری دارند، می‌توان با average="weighted" به هر برچسب متناسب با Support آن وزن داد.

اگر طبقه‌بندی مانند SVC چندبرچسبی را بومی پشتیبانی نکند، می‌توان یک مدل مستقل برای هر برچسب آموزش داد، اما این کار وابستگی میان برچسب‌ها را نادیده می‌گیرد. برای ثبت این وابستگی‌ها می‌توان مدل‌ها را زنجیره کرد؛ هر مدل علاوه بر ویژگی‌های ورودی، پیش‌بینی مدل‌های قبلی را نیز دریافت می‌کند. Scikit-Learn این کار را با ClassifierChain انجام می‌دهد. اگر cv تنظیم شود، پیش‌بینی‌های Out-of-Sample حاصل از Cross-Validation برای آموزش مدل‌های بعدی زنجیره استفاده می‌شوند:

from sklearn.multioutput import ClassifierChain

chain_clf = ClassifierChain(SVC(), cv=3, random_state=42)
chain_clf.fit(X_train[:2000], y_multilabel[:2000])

>>> chain_clf.predict([some_digit])
array([[0., 1.]])

طبقه‌بندی چندخروجی

آخرین نوع طبقه‌بندی این فصل «چندخروجی-چندکلاسه» یا به‌اختصار Multioutput Classification است؛ تعمیم طبقه‌بندی چندبرچسبی که در آن هر برچسب خودش می‌تواند چندکلاسه باشد.

برای نمونه سامانه‌ای می‌سازیم که نویز تصویر را حذف کند. ورودی یک تصویر نویزی از رقم است و خروجی باید تصویر تمیز باشد؛ یعنی آرایه‌ای از شدت پیکسل‌ها. خروجی چندبرچسبی است چون برای هر پیکسل یک برچسب داریم، و هر برچسب چند مقدار ممکن - ۰ تا ۲۵۵ - دارد. بنابراین این یک مسئلهٔ چندخروجی است.

با افزودن نویز تصادفی به پیکسل‌های تصاویر MNIST، مجموعه‌های آموزشی و آزمون را می‌سازیم؛ هدف‌ها همان تصاویر اصلی‌اند:

np.random.seed(42) # to make this code example reproducible
noise = np.random.randint(0, 100, (len(X_train), 784))
X_train_mod = X_train + noise
noise = np.random.randint(0, 100, (len(X_test), 784))
X_test_mod = X_test + noise
y_train_mod = X_train
y_test_mod = X_test
تصویر نویزی و تصویر تمیز هدف از رقم ۷
شکل ۳-۱۲. تصویر نویزی در سمت چپ و تصویر تمیز هدف در سمت راست

حالا KNN را آموزش می‌دهیم و از آن می‌خواهیم تصویر نویزی را پاک کند:

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_mod, y_train_mod)
clean_digit = knn_clf.predict([X_test_mod[0]])
plot_digit(clean_digit)
plt.show()
تصویر تمیزشده رقم ۷ توسط طبقه‌بند KNN
شکل ۳-۱۳. تصویر پاک‌سازی‌شدهٔ خروجی مدل

نتیجه به تصویر هدف بسیار نزدیک است. با این مثال، مرور طبقه‌بندی پایان می‌یابد: اکنون انتخاب معیار مناسب برای طبقه‌بندی، تعیین موازنهٔ Precision/Recall، مقایسهٔ طبقه‌بندها و ساخت سامانه‌های دودویی، چندکلاسه، چندبرچسبی و چندخروجی را دیده‌اید. فصل‌های بعد سازوکار داخلی مدل‌هایی را که تاکنون استفاده شده‌اند باز می‌کنند.

تمرین‌های فصل ۳

  1. برای MNIST طبقه‌بندی بسازید که Accuracy آن روی مجموعهٔ آزمون بیش از ۹۷ درصد باشد. KNeighborsClassifier برای این کار مناسب است؛ مقادیر خوب weights و n_neighbors را با Grid Search پیدا کنید.
  2. تابعی بنویسید که تصویر MNIST را یک پیکسل به چپ، راست، بالا یا پایین جابه‌جا کند. سپس برای هر تصویر آموزشی چهار نسخهٔ جابه‌جا‌شده بسازید و به مجموعهٔ آموزشی اضافه کنید. بهترین مدل را روی مجموعهٔ گسترش‌یافته آموزش دهید و Accuracy را روی آزمون بسنجید. این روش رشد مصنوعی دادهٔ آموزشی همان Data Augmentation یا Training Set Expansion است.
  3. روی مجموعه‌دادهٔ Titanic کار کنید. می‌توانید از Kaggle شروع کنید یا فایل معرفی‌شده در منبع را دریافت و مانند دادهٔ مسکن فصل ۲ باز کنید. دو فایل train.csv و test.csv در اختیار دارید و هدف این است که بر اساس ستون‌های دیگر، ستون Survived را پیش‌بینی کنید.
  4. یک طبقه‌بند Spam بسازید: نمونه‌های Spam و Ham را از مجموعه‌داده‌های عمومی Apache SpamAssassin دریافت کنید؛ قالب داده را بررسی کنید؛ داده را به آموزش و آزمون تقسیم کنید؛ Pipeline آماده‌سازی بنویسید که هر ایمیل را به بردار ویژگی Sparse تبدیل کند و حضور یا تعداد وقوع واژه‌ها را نشان دهد. فراپارامترهایی برای حذف Headerها، کوچک‌کردن حروف، حذف نشانه‌گذاری، جایگزینی URLها با URL، جایگزینی اعداد با NUMBER و حتی Stemming در نظر بگیرید. سپس چند طبقه‌بند را امتحان کنید تا هم Recall و هم Precision بالا به دست آورید.

راه‌حل تمرین‌ها در انتهای Notebook این فصل در منبع تکمیلی کتاب ارائه شده است.

پاورقی‌ها

  1. طبقه‌بندهای Scikit-Learn همیشه دست‌کم یکی از دو متد decision_function() یا predict_proba() را دارند و برخی هر دو را ارائه می‌کنند.
  2. Scikit-Learn گزینه‌های دیگری برای Average و معیارهای طبقه‌بندی چندبرچسبی نیز دارد.
  3. برای جابه‌جایی تصویر می‌توان از تابع shift() در SciPy استفاده کرد؛ مثلاً shift(image, [2, 1], cval=0) تصویر را دو پیکسل پایین و یک پیکسل راست می‌برد.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

0 / 500

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620