SVM غیرخطی
همانطور که در پست قبلی در مورد SVM خطی توضیح دادیم، اصول کار SVM مبتنی بر بهینه سازی پارامتر های ضریب لاگرانژ بوده است. در این قسمت قصد داریم مساله بهینه سازی را در حالتی بررسی کنیم که داده ها به صورت خطی قابل تفکیک نیستند.
در این مواقع از نگاشت فضای داده با استفاده توابع کرنل استفاده می شود.

مسلما اعمال کرنل بر روی داده ها در معادلات بهینه سازی تغییر ایجاد می کند. برای حالت حاشیه نرم معادلات بازنویسی شده است.
کرنل SVM دو کلاسه
برای این حالت مساله لاگرانژ به صورت زیر تعریف می شود.

حال مساله به يک مساله بهينه سازي درجه دوم تبديل شده و مي شود آن را با quadprog آن را محاسبه نمود. و مقادير ضرايب لاگرانژ را با آن محاسبه کرد. مقدار ضرايب لاگرانژ براي اعضاي عضو بردار هاي پشتيبان داراي مقدار و براي باقي اعضا معادل صفر خواهد بود.
تفاوتی که در اینجا با حالت خطی مشاهده می شود، وجود تابع K است که ضرب داخلی داده ها در فضای نگاشت شده است. یعنی ما اول داده ها را با تابع کرنل نگاشت داده و پس از آن ضرب داخلی آن را محاسبه می کنیم.
مساله اصلی در این حالت تعیین معیاری برای تشخیص کلاس داده ها است. رابطه زیر تعیین کننده کلاس داده ها خواهد بود.

همانطور که در رابطه فوق می بینید دیگر خبری از w نیست. فقط کافیست b و مقدار نهایی را با استفاده از ضرب داخلی داده ها در فضای نگاشت شده بدست آوریم.
انواع کرنل
یکی ازمحبوب ترین کرنل ها کرنل گوسی می باشد که به فرم زیر تابع k یا همان ضرب داخلی کرنل تعریف شده است:
کرنل خطی که همان فرم SVM خطی را ایجاد می کند:
کرنل چند جمله ای نیز می تواند دسته بندی مناسبی از داده ها ایجاد کند تنها کافیست درجه چند جمله ای به درستی تعریف شود:
کرنل MLP نیز نمایی از مدل عصبی چند لایه ایجاد می کند اما حقیقتا تنظیم پارامتر های آن سخت است.
K(x, y) = tan(β0(x, y) + β1)
نمای شبکه عصبی SVM
با اینکه SVM جز شبکه های عصبی محسوب نمی شود اما از دید دیگر می توان آن را یک شبکه عصبی به صورت زیر متصور شد.

در این شکل به خوبی نحوه تصمیم گیری در مورد کلاس داده را با تابع SIGN نشان داده است.
کرنل SVM در متلب
مشابه مثال قبل که در پست قبل بررسي شد، داده هاي ورودي توليد مي شود. تنها تفاوت با مثال قبل در استفاده از يک تابع قديمي است. (چرا که درک آن ساده تر مي باشد!)
%% Load Data
load fisheriris
X = meas(inds,1:2);
n = size(X,1)/2;
y1 = ones(1,n);
y2 = -ones(1,n);
y = [y1,y2]';
%% SVM Train
svmstruct=svmtrain(TrainInputs,TrainTargets,...
'kernel_function','rbf',...
'rbf_sigma',0.4,...
'showplot',true);

اما توجه داشتبه باشيد تابع svmtrain در نسخه هاي بالا حذف شده است به جاي آن بايد از تابع fitcsvm استفاده کنيد. همانطور که ميبينيد در اين تابع مقدار سيگما هم قابل تنظيم مي باشد. و وظيفه رسم خطوط نيز به عهده اين تابع است (در حالت دو بعدي).
چالش اصلي (SVM چند کلاسه)
همانطور ک در دو پست آموزشی مطرح شد، تئوری گفته شده فقط برای دسته بندی دو کلاس داده مطرح شده است. اگر تعداد دسته های داده بیشتر از دو کلاس باشد چه ؟
در این حالت روش های مختلفی مطرح شده است
- one by all در این حالت هر کلاس را با سایر کلاس ها را دو کلاس متفاوت در نظر می گیریم و روش svm را اجرا می کنیم.
- one by one گاهی روش بالا عملکرد خوبی نشان نمی دهد. بنابراین الگوی (مقادیر الفا) هر کلاس با یک کلاس دیگر ذخیره می شود و برای داده های تست چک می شود.
به عنوان مثال ما سه دسته داده داریم
در روش اول سه حالت مختلف بررسی می شود (گروه یک با دو گروه دیگر گروه دو با دو گروه دیگر و گروه سه با دو گروه دیگر.)
اما در روش یک به یک سه حالت مجزا جزیی تری خواهیم داشت (یک با دو یک با سه و دو با سه ) و هر بار الگوریی خروجی SVM ذخیره شده و برای داده های تست چک می شود.
2 نظر برای “کرنل SVM در متلب”