المزيد من مقالات تعلم الآلة.....مقالات تعلم الآلة

نموذج التصنيف الثنائي في التعلم الآلي

التصنيف الثنائي Binary Classification هو نوع من نماذج التصنيف يحتوي على تصنيفين two label من الفئات classes. على سبيل المثال، يحتوي نموذج اكتشاف البريد الإلكتروني العشوائي على تصنيفين من الفئات كبريد عشوائي (spam) فيها أو ليست بريدًا عشوائيًا (not spam). تتضمن مهام التصنيف الثنائي في معظم الأحيان تسمية واحدة في حالة طبيعية ، وتسمية أخرى في حالة غير طبيعية. في هذه المقالة سوف آخذك من خلال التصنيف الثنائي في التعلم الآلي باستخدام بايثون.

مجموعة بيانات MNIST

سأستخدم مجموعة بيانات MNIST، وهي مجموعة من 70000 صورة صغيرة من الأرقام المكتوبة بخط اليد من قبل طلاب المدارس الثانوية وموظفي مكتب الإحصاء الأمريكي. يتم تسمية كل صورة بالرقم الذي تمثله. تمت دراسة هذه المجموعة كثيرًا لدرجة أنها غالبًا ما يطلق عليها “hello world” لتعلم الآلة.

عندما يبتكر الأشخاص خوارزمية تصنيف جديدة، فإنهم يشعرون بالفضول لمعرفة كيفية أدائها على MNIST، وأي شخص يتعلم التعلم الآلي يتعامل مع مجموعة البيانات هذه عاجلاً أم آجلاً. لذلك دعونا نستورد بعض المكتبات لتبدأ بنموذج التصنيف الثنائي الخاص بنا:

# Python ≥3.5 is required
import sys
assert sys.version_info >= (3, 5)

# Scikit-Learn ≥0.20 is required
import sklearn
assert sklearn.__version__ >= "0.20"

# Common imports
import numpy as np
import os

# to make this notebook's output stable across runs
np.random.seed(42)

# To plot pretty figures
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)

يوفر Scikit-Learn العديد من الوظائف المساعدة لتنزيل مجموعات البيانات الشائعة. MNIST هو واحد منهم. يجلب الكود التالي مجموعة بيانات MNIST:

from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784', version=1)
mnist.keys()

الآن دعونا نلقي نظرة على البيانات:

X, y = mnist["data"], mnist["target"]
X.shape

(70000, 784)
y.shape
(70000, 784)
y.shape
(70000,)
28 * 28
784

هناك 70000 صورة، ولكل صورة 784 ميزة. هذا لأن كل صورة 28 × 28 بكسل، وكل ميزة تمثل ببساطة كثافة بكسل واحد، من 0 (أبيض) إلى 255 (أسود). لنأخذ ذروة في رقم واحد من مجموعة البيانات. كل ما عليك فعله هو الحصول على متجه خاصية المثيل، وإعادة تشكيله إلى مصفوفة 28 × 28، وعرضه باستخدام دالة imshow () الخاصة بـ Matplotlib :

لاحظ أن التسمية عبارة عن سلسلة نصية. تتوقع معظم خوارزميات التعلم الآلي أرقامًا، لذلك دعونا نحول y إلى عدد صحيح:

y = y.astype(np.uint8)

الآن قبل تدريب نموذج التصنيف الثنائي، دعنا نلقي نظرة على الأرقام:

def plot_digit(data):
    image = data.reshape(28, 28)
    plt.imshow(image, cmap = mpl.cm.binary,
               interpolation="nearest")
    plt.axis("off")
def plot_digits(instances, images_per_row=10, **options):
    size = 28
    images_per_row = min(len(instances), images_per_row)
    images = [instance.reshape(size,size) for instance in instances]
    n_rows = (len(instances) - 1) // images_per_row + 1
    row_images = []
    n_empty = n_rows * images_per_row - len(instances)
    images.append(np.zeros((size, size * n_empty)))
    for row in range(n_rows):
        rimages = images[row * images_per_row : (row + 1) * images_per_row]
        row_images.append(np.concatenate(rimages, axis=1))
    image = np.concatenate(row_images, axis=0)
    plt.imshow(image, cmap = mpl.cm.binary, **options)
    plt.axis("off")
plt.figure(figsize=(9,9))
example_images = X[:100]
plot_digits(example_images, images_per_row=10)
save_fig("more_digits_plot")
plt.show()

يجب عليك دائمًا إنشاء مجموعة اختبار test set ووضعها جانبًا قبل فحص البيانات عن كثب. تم بالفعل تقسيم مجموعة بيانات MNIST إلى مجموعة تدريب training set ومجموعة اختبار test set:

X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]

تدريب نموذج تصنيف ثنائي

دعنا ببساطة نواجه المشكلة الآن ونحاول فقط تحديد رقم واحد. على سبيل المثال، الرقم 5. سيكون هذا “الكاشف 5” مثالاً على تصنيف ثنائي، قادر على التمييز بين فئتين فقط، 5 وليس 5. لننشئ المتجهات المستهدفة لمهمة التصنيف:

y_train_5 = (y_train == 5)
y_test_5 = (y_test == 5)

الآن دعنا نختار نموذج تصنيف ونقوم بتدريبه. أفضل مكان للبدء هو التعامل مع Stochastic Gradient Descent (SGD) الذي يتعامل مع حالات التدريب بشكل مستقل، واحدًا تلو الآخر، كما سنرى لاحقًا في نموذج التصنيف الثنائي الخاص بنا. دعونا نبني تصنيفًا ثنائيًا باستخدام SGDClassifier وندربه على مجموعة التدريب بأكملها:

from sklearn.linear_model import SGDClassifier

sgd_clf = SGDClassifier(max_iter=1000, tol=1e-3, random_state=42)
sgd_clf.fit(X_train, y_train_5)

sgd_clf.predict([some_digit])
array([ True])

يخمّن المصنف أن هذه الصورة تمثل 5 (True). يبدو أنه تم تخمينه بشكل صحيح في هذه الحالة بالذات. لنقم الآن بتقييم أداء نموذج التصنيف الثنائي الخاص بنا.

مقاييس الأداء

غالبًا ما يكون تقييم المصنف أكثر تعقيدًا من تقييم الانحدار، لذلك سننفق جزءًا أكبر من هذه المقالة لتقييم نموذج التصنيف الثنائي الخاص بنا.

تنفيذ التحقق المتبادل على نموذج التصنيف الثنائي

في بعض الأحيان، ستحتاج إلى مزيد من التحكم في عملية التحقق المتبادل Cross-Validation مما يوفره scikit-Learn خارج الرف. في هذه الحالات، يمكنك تنفيذ التحقق المتبادل بنفسك. يقوم الكود التالي تقريبًا بنفس الشيء الذي تفعله دالة cross_val_score() في Scikit-Learn ، وتطبع نفس النتيجة:

from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone

skfolds = StratifiedKFold(n_splits=3, random_state=42)

for train_index, test_index in skfolds.split(X_train, y_train_5):
    clone_clf = clone(sgd_clf)
    X_train_folds = X_train[train_index]
    y_train_folds = y_train_5[train_index]
    X_test_fold = X_train[test_index]
    y_test_fold = y_train_5[test_index]

    clone_clf.fit(X_train_folds, y_train_folds)
    y_pred = clone_clf.predict(X_test_fold)
    n_correct = sum(y_pred == y_test_fold)
    print(n_correct / len(y_pred))

0.95035
0.96035
0.9604

تقوم فئة StratifiedKFold بأخذ عينات طبقية لإنتاج طيات folds تحتوي على نسبة تمثيلية لكل فئة. في كل تكرار، يُنشئ الكود نسخة من نموذج التصنيف، ويدرب النسخة في طيات التدريب training folds، وتقوم بالتنبؤات على طية الاختبار test fold. ثم يحسب عدد التنبؤات الصحيحة ويخرج نسبة التنبؤات الصحيحة.

دعنا نستخدم الدالة cross_val_score () لتقييم نموذج SGDClassifier الخاص بنا، باستخدام التحقق المتبادل K-fold مع ثلاث طيات. تذكر أن التحقق من صحة K-fold يعني تقسيم مجموعة التدريب إلى طيات K ، ثم عمل تنبؤات وتقييمها في كل طية باستخدام نموذج تم تدريبه على الطيات المتبقية:

from sklearn.model_selection import cross_val_score
cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring="accuracy")

array([0.95035, 0.96035, 0.9604 ])

رائع! دقة أعلى من 93٪ في جميع طيات التحقق المتبادل. حسنًا، قبل أن تشعر بالحماس الشديد، دعنا نلقي نظرة على المصنف الغبي جدًا الذي يصنف فقط كل صورة في فئة “ليس 5”:

from sklearn.base import BaseEstimator
class Never5Classifier(BaseEstimator):
    def fit(self, X, y=None):
        pass
    def predict(self, X):
        return np.zeros((len(X), 1), dtype=bool)
      
never_5_clf = Never5Classifier()
cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring="accuracy")

array([0.91125, 0.90855, 0.90915])

هذا صحيح، حيث تبلغ دقته أكثر من 90٪. هذا ببساطة لأن حوالي 10٪ فقط من الصور هي 5، لذلك إذا كنت تخمن دائمًا أن الصورة ليست 5، فستكون على حق في 90٪ من الوقت. لذلك آمل أن تكون قد أحببت هذه المقالة حول نموذج التصنيف الثنائي في التعلم الآلي.

بواسطة
THECLEVERPROGRAMMER
المصدر
Binary Classification Algorithms in Machine Learning

د. علاء طعيمة

كلية علوم الحاسوب وتكنولوجيا المعلومات / جامعة القادسية / العراق

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى