يعد Support Vector Machine أو SVM أحد أكثر خوارزميات التعلم الخاضع للإشراف شيوعًا، والذي يُستخدم في مشاكل التصنيف والانحدار. ومع ذلك، يتم استخدامه بشكل أساسي لحل مشكلات التصنيف في التعلم الآلي.
الهدف من خوارزمية SVM هو إنشاء أفضل خط أو حد قرار يمكنه فصل الفضاء ذي الأبعاد n إلى فئات حتى نتمكن بسهولة من وضع نقطة البيانات الجديدة في الفئة الصحيحة في المستقبل. تسمى حدود القرار الأفضل هذه بالطائرة الفائقة.
يختار SVM النقاط/المتجهات المتطرفة التي تساعد في إنشاء المستوى الفائق. تسمى هذه الحالات القصوى باسم متجهات الدعم، ومن ثم تسمى الخوارزمية باسم آلة ناقل الدعم. خذ بعين الاعتبار الرسم البياني أدناه الذي يوجد فيه فئتان مختلفتان تم تصنيفهما باستخدام حدود القرار أو المستوى الزائد:
مثال: يمكن فهم SVM من خلال المثال الذي استخدمناه في مصنف KNN. لنفترض أننا نرى قطة غريبة لديها أيضًا بعض سمات الكلاب، لذلك إذا أردنا نموذجًا يمكنه التعرف بدقة على ما إذا كانت قطة أم كلبًا، فيمكن إنشاء مثل هذا النموذج باستخدام خوارزمية SVM. سنقوم أولاً بتدريب نموذجنا باستخدام الكثير من صور القطط والكلاب حتى يتمكن من التعرف على السمات المختلفة للقطط والكلاب، ثم نختبره مع هذا المخلوق الغريب. لذا، نظرًا لأن متجه الدعم ينشئ حدًا للقرار بين هاتين البيانات (القط والكلب) ويختار الحالات المتطرفة (متجهات الدعم)، فسوف يرى الحالة القصوى للقط والكلب. على أساس ناقلات الدعم، سيتم تصنيفها على أنها قطة. النظر في الرسم البياني أدناه:
يمكن استخدام خوارزمية SVM لـ كشف الوجه، تصنيف الصور، تصنيف النص، إلخ.
عفوا المفاهيم في جافا
أنواع SVM
يمكن أن يكون SVM من نوعين:
الطائرة الفائقة ومتجهات الدعم في خوارزمية SVM:
الطائرة الفائقة: يمكن أن يكون هناك عدة خطوط/حدود قرار لفصل الفئات في الفضاء ذي الأبعاد n، ولكننا بحاجة إلى اكتشاف أفضل حدود القرار التي تساعد في تصنيف نقاط البيانات. تُعرف هذه الحدود الأفضل باسم المستوى الزائد لـ SVM.
تعتمد أبعاد المستوى الزائد على الميزات الموجودة في مجموعة البيانات، مما يعني أنه إذا كان هناك ميزتان (كما هو موضح في الصورة)، فسيكون المستوى الزائد خطًا مستقيمًا. وإذا كان هناك 3 ميزات، فإن المستوى الفائق سيكون مستوى ثنائي الأبعاد.
نقوم دائمًا بإنشاء مستوى فائق السرعة له هامش أقصى، وهو ما يعني الحد الأقصى للمسافة بين نقاط البيانات.
ناقلات الدعم:
يُطلق على نقاط البيانات أو المتجهات الأقرب إلى المستوى الفائق والتي تؤثر على موضع المستوى الفائق اسم ناقل الدعم. وبما أن هذه المتجهات تدعم المستوى الزائد، فإنها تسمى بالتالي متجه الدعم.
كيف يعمل SVM؟
SVM الخطي:
يمكن فهم عمل خوارزمية SVM باستخدام مثال. لنفترض أن لدينا مجموعة بيانات تحتوي على علامتين (الأخضر والأزرق)، وتحتوي مجموعة البيانات على ميزتين x1 وx2. نريد مصنفًا يمكنه تصنيف زوج الإحداثيات (x1، x2) باللون الأخضر أو الأزرق. النظر في الصورة أدناه:
وبما أنها مساحة ثنائية الأبعاد، فباستخدام خط مستقيم فقط، يمكننا بسهولة فصل هاتين الفئتين. ولكن يمكن أن يكون هناك خطوط متعددة يمكنها فصل هذه الفئات. النظر في الصورة أدناه:
وبالتالي، تساعد خوارزمية SVM في العثور على أفضل خط أو حدود قرار؛ يُطلق على هذه الحدود أو المنطقة الأفضل اسم a طائرة مفرطة . تعثر خوارزمية SVM على أقرب نقطة للخطوط من كلا الفئتين. تسمى هذه النقاط ناقلات الدعم. تسمى المسافة بين المتجهات والمستوى الزائد بـ هامِش . والهدف من SVM هو تعظيم هذا الهامش. ال طائرة مفرطة مع الحد الأقصى للهامش يسمى الطائرة الفائقة الأمثل .
SVM غير الخطية:
إذا كانت البيانات مرتبة خطيًا، فيمكننا فصلها باستخدام خط مستقيم، أما بالنسبة للبيانات غير الخطية، فلا يمكننا رسم خط مستقيم واحد. النظر في الصورة أدناه:
لذا، لفصل نقاط البيانات هذه، علينا إضافة بُعد آخر. بالنسبة للبيانات الخطية، استخدمنا بعدين x وy، أما بالنسبة للبيانات غير الخطية، فسنضيف بُعدًا ثالثًا z. ويمكن حسابها على النحو التالي:
z=x<sup>2</sup> +y<sup>2</sup>
وبإضافة البعد الثالث يصبح فضاء العينة كما في الصورة التالية:
والآن، سيقوم SVM بتقسيم مجموعات البيانات إلى فئات بالطريقة التالية. النظر في الصورة أدناه:
وبما أننا في الفضاء ثلاثي الأبعاد، فهو يبدو وكأنه مستوى موازٍ للمحور السيني. وإذا حولناها إلى فضاء ثنائي الأبعاد حيث z=1 ستصبح على النحو التالي:
ومن ثم نحصل على محيط نصف قطره 1 في حالة البيانات غير الخطية.
تنفيذ بايثون لآلة ناقل الدعم
الآن سوف نقوم بتنفيذ خوارزمية SVM باستخدام بايثون. هنا سوف نستخدم نفس مجموعة البيانات بيانات المستخدم والتي استخدمناها في الانحدار اللوجستي وتصنيف KNN.
حتى خطوة المعالجة المسبقة للبيانات، سيظل الرمز كما هو. أدناه هو الرمز:
#Data Pre-processing Step # importing libraries import numpy as nm import matplotlib.pyplot as mtp import pandas as pd #importing datasets data_set= pd.read_csv('user_data.csv') #Extracting Independent and dependent Variable x= data_set.iloc[:, [2,3]].values y= data_set.iloc[:, 4].values # Splitting the dataset into training and test set. from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.25, random_state=0) #feature Scaling from sklearn.preprocessing import StandardScaler st_x= StandardScaler() x_train= st_x.fit_transform(x_train) x_test= st_x.transform(x_test)
بعد تنفيذ التعليمات البرمجية أعلاه، سنقوم بمعالجة البيانات مسبقًا. سيعطي الكود مجموعة البيانات على النحو التالي:
غلاف فني مقابل غلاف ورقي
سيكون الناتج المقاس لمجموعة الاختبار:
تركيب مصنف SVM على مجموعة التدريب:
سيتم الآن تركيب مجموعة التدريب على مصنف SVM. لإنشاء مصنف SVM، سوف نقوم باستيراد SVC فئة من Sklearn.svm مكتبة. أدناه هو رمز لذلك:
from sklearn.svm import SVC # 'Support vector classifier' classifier = SVC(kernel='linear', random_state=0) classifier.fit(x_train, y_train)
في الكود أعلاه استخدمنا النواة = 'خطي' حيث أننا هنا نقوم بإنشاء SVM للبيانات القابلة للفصل خطيًا. ومع ذلك، يمكننا تغييره للبيانات غير الخطية. ثم قمنا بتركيب المصنف على مجموعة بيانات التدريب (x_train، y_train)
كيفية تحويل السلسلة إلى عدد صحيح
انتاج:
Out[8]: SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma='auto_deprecated', kernel='linear', max_iter=-1, probability=False, random_state=0, shrinking=True, tol=0.001, verbose=False)
يمكن تغيير أداء النموذج عن طريق تغيير قيمة C (عامل التنظيم)، جاما، والنواة .
الآن، سوف نتنبأ بمخرجات مجموعة الاختبار. لهذا، سوف نقوم بإنشاء متجه جديد y_pred. أدناه هو رمز لذلك:
#Predicting the test set result y_pred= classifier.predict(x_test)
بعد الحصول على المتجه y_pred، يمكننا مقارنة نتيجة y_pred و y_test للتحقق من الفرق بين القيمة الفعلية والقيمة المتوقعة.
انتاج: فيما يلي إخراج التنبؤ بمجموعة الاختبار:
سنرى الآن أداء مصنف SVM وعدد التنبؤات غير الصحيحة الموجودة مقارنة بمصنف الانحدار اللوجستي. لإنشاء مصفوفة الارتباك، نحتاج إلى استيراد ملف الارتباك مصفوفة وظيفة مكتبة sklearn بعد استيراد الدالة، سوف نستدعيها باستخدام متغير جديد سم . تأخذ الدالة معلمتين بشكل أساسي y_true (القيم الفعلية) و y_pred (إرجاع القيمة المستهدفة بواسطة المصنف). أدناه هو رمز لذلك:
#Creating the Confusion matrix from sklearn.metrics import confusion_matrix cm= confusion_matrix(y_test, y_pred)
انتاج:
كما نرى في الصورة الناتجة أعلاه، هناك 66+24= 90 تنبؤًا صحيحًا و8+2= 10 تنبؤات صحيحة. لذلك يمكننا القول أن نموذج SVM الخاص بنا قد تحسن مقارنةً بنموذج الانحدار اللوجستي.
الآن سنقوم بتصور نتيجة مجموعة التدريب، وفيما يلي الكود الخاص بها:
from matplotlib.colors import ListedColormap x_set, y_set = x_train, y_train x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red', 'green'))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('SVM classifier (Training set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
انتاج:
بتنفيذ الكود أعلاه، سنحصل على الإخراج على النحو التالي:
كما نرى، فإن الناتج أعلاه يظهر مشابهًا لمخرج الانحدار اللوجستي. في الناتج، حصلنا على خط مستقيم كطائرة مفرطة لأننا حصلنا عليها استخدم نواة خطية في المصنف . وقد ناقشنا أيضًا أعلاه أنه بالنسبة للمساحة ثنائية الأبعاد، فإن المستوى الزائد في SVM هو خط مستقيم.
#Visulaizing the test set result from matplotlib.colors import ListedColormap x_set, y_set = x_test, y_test x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red','green' ))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('SVM classifier (Test set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
انتاج:
بتنفيذ الكود أعلاه، سنحصل على الإخراج على النحو التالي:
كما نرى في صورة الإخراج أعلاه، قام مصنف SVM بتقسيم المستخدمين إلى منطقتين (تم شراؤه أو لم يتم شراؤه). المستخدمون الذين اشتروا السيارة الرياضية متعددة الاستخدامات موجودون في المنطقة الحمراء مع نقاط حمراء متناثرة. والمستخدمون الذين لم يشتروا السيارة الرياضية متعددة الاستخدامات موجودون في المنطقة الخضراء مع نقاط متناثرة خضراء. قامت الطائرة الفائقة بتقسيم الفئتين إلى متغير تم شراؤه ولم يتم شراؤه.