آموزش ماشین بردار پشتیبان در یادگیری ماشین با پایتون (SVM)

ماشین بردار پشتیبان در یادگیری ماشین (Support Vector Machines یا SVMs) الگوریتمی قدرتمند و در عین حال انعطاف‌پذیر در یادگیری ماشین نظارت‌شده هستند که برای هر دو مسئله طبقه‌بندی (classification) و رگرسیون (regression) به‌کار می‌روند. با این حال، معمولاً در مسائل طبقه‌بندی استفاده می‌شوند.

نخستین بار در دهه ۱۹۶۰، الگوریتم SVM معرفی شد، اما در دهه ۱۹۹۰ توسعه و بهبود یافت. ماشین‌های بردار پشتیبان نسبت به سایر الگوریتم‌های یادگیری ماشین، شیوه‌ای منحصربه‌فرد در پیاده‌سازی دارند.

امروزه، SVMها به‌دلیل توانایی بالا در مدیریت متغیرهای پیوسته و دسته‌ای (categorical)، بسیار محبوب و پرکاربرد هستند.

نحوه عملکرد ماشین بردار پشتیبان (SVM)

هدف اصلی SVM یافتن یک ابرصفحه (Hyperplane) است که بتواند نقاط داده را به درستی به کلاس‌های مختلف تقسیم کند. ابرصفحه در فضای دوبعدی یک خط، در فضای سه‌بعدی یک صفحه، و در فضاهای با ابعاد بالاتر، یک سطح چندبُعدی است.

این ابرصفحه به‌گونه‌ای انتخاب می‌شود که حاشیه (Margin) را بیشینه کند؛ یعنی فاصله‌ای که بین ابرصفحه و نزدیک‌ترین نقاط از هر کلاس وجود دارد. این نزدیک‌ترین نقاط، بردارهای پشتیبان (Support Vectors) نامیده می‌شوند.

فاصله بین ابرصفحه و یک نقطه داده‌ای xx با استفاده از فرمول زیر محاسبه می‌شود:

در این رابطه:

  • بردار وزن (Weight vector) است؛

  • جمله بایاس (Bias term) است؛

  • ||w|| نورم اقلیدسی (Euclidean norm) بردار وزن است.

بردار وزن w عمود بر ابرصفحه است و جهت آن را مشخص می‌کند، در حالی که جمله بایاس b موقعیت قرارگیری ابرصفحه را تعیین می‌کند.

یافتن ابرصفحه بهینه از طریق حل یک مسئله بهینه‌سازی انجام می‌شود. هدف، بیشینه‌سازی حاشیه با این شرط است که تمام نقاط داده‌ای به‌درستی طبقه‌بندی شوند. به عبارت دیگر، می‌خواهیم ابرصفحه‌ای پیدا کنیم که فاصله بین کلاس‌ها را بیشینه کند و هیچ نقطه‌ای به‌اشتباه در کلاس نادرست قرار نگیرد. این مسئله، یک مسئله بهینه‌سازی محدب (Convex Optimization Problem) است که با روش برنامه‌ریزی درجه دوم (Quadratic Programming) قابل حل است.

اگر داده‌ها به‌صورت خطی قابل تفکیک نباشند، از تکنیکی به نام ترفند هسته‌ای (Kernel Trick) استفاده می‌کنیم. در این روش، داده‌ها به یک فضای با ابعاد بالاتر نگاشت می‌شوند، جایی که در آن قابل تفکیک شوند. تابع هسته‌ای (Kernel Function) ضرب داخلی بین نگاشت داده‌ها را محاسبه می‌کند، بدون اینکه خود نگاشت را انجام دهد. این کار باعث می‌شود بتوانیم با داده‌ها در فضای با ابعاد بالاتر کار کنیم، بدون آنکه هزینه محاسباتی بالای نگاشت را بپردازیم.

بیایید مفاهیم اصلی SVM را با کمک نمودار زیر بهتر درک کنیم:

نحوه کار SVM

مفاهیم کلیدی در SVM

  • بردارهای پشتیبان (Support Vectors): نقاطی از داده‌ها که نزدیک‌ترین فاصله را به ابرصفحه دارند. ابرصفحه تفکیک‌کننده با توجه به همین نقاط تعیین می‌شود.

  • ابرصفحه (Hyperplane): همان‌طور که در نمودار دیده می‌شود، یک صفحه تصمیم‌گیری است که فضای داده‌ها را به بخش‌هایی تقسیم می‌کند که هرکدام به یک کلاس تعلق دارند.

  • حاشیه (Margin): فاصله بین دو خطی که نزدیک‌ترین نقاط از دو کلاس مختلف را در بر می‌گیرند. این فاصله به‌صورت عمودی از ابرصفحه تا بردارهای پشتیبان اندازه‌گیری می‌شود.

    • حاشیه بزرگ، حاشیه مطلوب و نشانه طبقه‌بندی خوب است.

    • حاشیه کوچک، کیفیت پایین مدل را نشان می‌دهد.

پیاده سازی SVM با استفاده از پایتون

برای پیاده سازی ماشین بردار پشتیبان (SVM) در زبان پایتون، ابتدا باید کتابخانه‌های استاندارد مورد نیاز را وارد کنیم:

در ادامه، یک مجموعه‌داده نمونه با داده‌های خطی قابل تفکیک تولید می‌کنیم. از تابع make_blobs در ماژول sklearn.datasets برای ساخت داده‌ها استفاده می‌کنیم:
خروجی این بخش، نموداری از ۱۰۰ نقطه داده‌ای است که در قالب دو خوشه (کلاس) مختلف نمایش داده می‌شوند:

رسم نمودار از نقاط داده با SVM

می‌دانیم که SVM نوعی طبقه‌بند تبعیض‌گر (Discriminative Classifier) است؛ یعنی با یافتن یک خط (در فضای دوبعدی) یا یک منیفولد (در فضاهای چندبُعدی)، کلاس‌ها را از یکدیگر جدا می‌کند.

در ادامه، پیاده‌سازی آن بر روی داده‌های فوق به این صورت خواهد بود:

خروجی به صورت زیر خواهد بود:

رسم خط/ابرصفحه توسط SVM

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

همان‌طور که پیش‌تر گفته شد، هدف اصلی SVM یافتن ابرصفحه‌ای با بیشترین حاشیه (Maximum Marginal Hyperplane – MMH) است. به جای صرفاً رسم یک خط بین دو کلاس، می‌توان برای هر خط، یک حاشیه (margin) با عرض مشخص تا نزدیک‌ترین نقطه رسم کرد. این کار به شکل زیر انجام می‌شود:

رسم ابرصفحه با حداکثر حاشیه

این نمودار به‌وضوح نشان می‌دهد که حاشیه (Margin) در هر مورد چقدر است. اینجا SVM، خطی را انتخاب می‌کند که بیشترین حاشیه ممکن را داشته باشد؛ به‌عبارت دیگر، فاصله بین خط و نزدیک‌ترین نقاط هر کلاس بیشینه باشد.

در مرحله بعد، از کلاس Support Vector Classifier (SVC) در کتابخانه Scikit-Learn برای آموزش مدل SVM روی همین داده‌ها استفاده می‌کنیم. در این مثال، ما از کرنل خطی (Linear Kernel) استفاده می‌کنیم:

خروجی ساختار مدل چیزی شبیه به زیر خواهد بود:

ترسیم توابع تصمیم برای مدل SVC دوبُعدی

برای درک بهتر عملکرد مدل آموزش‌دیده، در ادامه تابعی را تعریف می‌کنیم که توابع تصمیم (Decision Functions) مدل را روی نمودار رسم می‌کند:

ارزیابی مدل SVM و ترسیم ابرصفحه بهینه

برای ارزیابی مدل و ترسیم خطوط تصمیم (decision boundaries) و حاشیه‌ها (margins)، ابتدا باید یک شبکه دوبُعدی از نقاط مختصات (grid) در فضای داده ایجاد کنیم. این کار به‌صورت زیر انجام می‌شود:

اکنون می‌توان مرز تصمیم و خطوط حاشیه‌ای را روی نمودار رسم کرد:

در ادامه، بردارهای پشتیبان را نیز با نقاط توخالی روی نمودار مشخص می‌کنیم:

اکنون می‌توانیم کل مدل را به‌همراه مرز تصمیم، حاشیه‌ها و بردارهای پشتیبان، به‌صورت کامل ترسیم کنیم:

ابرصفحه بهترین برازش SVM

می‌توانیم از خروجی بالا ببینیم که طبقه بندی کننده SVM روی داده برازش می‌شود و حاشیه‌ها را نشان می‌دهد. خطوط حاشیه با خط‌چین نمایش داده می‌شوند و بردارهای پشتیبان عنصرهای کلیدی این برازش هستند. این نقاط خط‌چین را لمس می‌کنند.

این نقاطِ بردار پشتیبان در ویژگی (attribute) support_vectors_ طبقه‌بندی کننده ذخیره می‌شوند، به‌شکل زیر:

خروجی به صورت زیر خواهد بود:

هسته‌ها در SVM

در عمل، الگوریتم SVM معمولاً با استفاده از هسته (Kernel) پیاده‌سازی می‌شود. هسته داده‌های ورودی را از یک فضای اولیه به شکلی تبدیل می‌کند که برای طبقه‌بندی مناسب باشد.

SVM از تکنیکی به نام ترفند هسته‌ای (Kernel Trick) استفاده می‌کند. در این روش، هسته یک فضای ورودی با ابعاد پایین را به یک فضای با ابعاد بالاتر نگاشت می‌کند. به زبان ساده، هسته مسائل غیرقابل‌تفکیک (Non-separable) را با افزودن بُعدهای بیشتر به مسائل قابل‌تفکیک (Separable) تبدیل می‌کند.

این ویژگی باعث می‌شود SVM قدرتمندتر، انعطاف‌پذیرتر و دقیق‌تر عمل کند. انواع مختلفی از هسته‌ها در SVM مورد استفاده قرار می‌گیرند که مهم‌ترین آن‌ها عبارت‌اند از:

هسته خطی (Linear Kernel)

از این هسته می‌توان به‌عنوان ضرب داخلی (Dot Product) بین هر دو مشاهده استفاده کرد. فرمول هسته خطی به صورت زیر است:

k(x,xi) = sum(x*xi)

از فرمول بالا می‌توانیم ببینیم که حاصل‌ضرب بین دو بردار برابر است با مجموع حاصل‌ضرب هر جفت مقدار ورودی.

هسته چندجمله‌ای (Polynomial Kernel)

این هسته شکل عمومی‌تر هسته خطی است و می‌تواند فضاهای ورودی منحنی یا غیرخطی را متمایز کند. فرمول هسته چندجمله‌ای به صورت زیر است:

K(x, xi) = 1 + sum(x * xi)^d

در اینجا، d درجه چندجمله‌ای است که باید به‌صورت دستی در الگوریتم یادگیری مشخص کنیم.

هسته تابع پایه شعاعی (Radial Basis Function – RBF Kernel)

هسته RBF که بیشتر در طبقه‌بندی‌های SVM استفاده می‌شود، فضای ورودی را به یک فضای با ابعاد نامحدود نگاشت می‌کند. فرمول ریاضی آن به صورت زیر است:

K(x,xi) = exp(-gamma * sum((x xi^2))

در اینجا، مقدار γ بین 0 و 1 است. ما باید آن را به‌صورت دستی در الگوریتم مشخص کنیم. مقدار پیش‌فرض مناسب برای γ، عدد 0.1 در نظر گرفته می‌شود.

همان‌طور که SVM را برای داده‌های خطی قابل تفکیک پیاده‌سازی کردیم، می‌توانیم آن را در Python برای داده‌هایی که به‌صورت خطی قابل تفکیک نیستند نیز پیاده‌سازی کنیم. این کار با استفاده از هسته‌ها (Kernels) انجام می‌شود.

مثال

در این مثال، یک دسته‌بند SVM با استفاده از هسته‌ها (Kernels) ایجاد می‌کنیم. برای این کار از مجموعه داده Iris موجود در کتابخانه scikit-learn استفاده خواهیم کرد.

ابتدا بسته های مورد نیاز را وارد میکنیم:

حالا باید داده‌های ورودی را بارگذاری کنیم:
از این مجموعه داده، دو ویژگی اول را به‌عنوان ورودی انتخاب می‌کنیم:
در مرحله بعد، مرزهای SVM را با داده‌های اصلی به صورت زیر رسم خواهیم کرد:
اکنون، باید مقدار پارامتر تنظیم را به صورت زیر ارائه دهیم:
در گام بعد، می‌توان شیء دسته‌بند SVM را بصورت زیر ایجاد کرد:

Svc_classifier = svm.SVC(kernel=’linear’, C=C).fit(X, y)

خروجی

نمودار منحنی

برای ایجاد یک دسته‌بند SVM با هسته RBF، کافی است مقدار پارامتر kernel را از linear به rbf تغییر دهیم:

خروجی

طبقه بندی کننده

ما مقدار گاما (gamma) را برابر 'auto' قرار دادیم، اما شما می‌توانید به‌صورت دستی نیز برای آن مقداری بین ۰ تا ۱ تعیین کنید.

تنظیم پارامترهای SVM

در عمل، الگوریتم‌های SVM معمولاً نیاز به تنظیم پارامترها دارند تا بهترین عملکرد را ارائه دهند. مهم‌ترین پارامترهایی که باید تنظیم شوند شامل کرنل (Kernel)، پارامتر منظم‌سازی C و پارامترهای خاص هر کرنل هستند.

پارامتر کرنل (Kernel) نوع کرنل مورد استفاده را مشخص می‌کند. رایج‌ترین انواع کرنل شامل خطی (Linear)، چندجمله‌ای (Polynomial)، تابع پایه شعاعی (RBF) و سیگموید (Sigmoid) هستند. کرنل خطی برای داده‌های خطی تفکیک‌پذیر استفاده می‌شود، در حالی که سایر کرنل‌ها برای داده‌های غیرخطی تفکیک‌ناپذیر به‌کار می‌روند.

پارامتر C یا همان پارامتر منظم‌سازی، میزان موازنه بین بیشینه‌سازی حاشیه (Margin) و کاهش خطای طبقه‌بندی را کنترل می‌کند:

  • اگر مقدار C بزرگ باشد، طبقه‌بند تلاش می‌کند خطای طبقه‌بندی را به حداقل برساند، حتی اگر به قیمت کوچک‌تر شدن حاشیه باشد.

  • اگر مقدار C کوچک باشد، طبقه‌بند ترجیح می‌دهد حاشیه را بزرگ‌تر کند، حتی اگر به معنای خطاهای طبقه‌بندی بیشتر باشد.

پارامترهای ویژه هر کرنل به نوع کرنل بستگی دارند. به‌طور مثال:

  • در کرنل چندجمله‌ای (Polynomial) باید درجه چندجمله‌ای (degree) و ضریب چندجمله‌ای مشخص شوند.

  • در کرنل RBF باید پهنای تابع گاوسی (gamma) تعیین شود.

برای انتخاب بهترین مقادیر این پارامترها، می‌توان از روش اعتبارسنجی متقابل (Cross-Validation) استفاده کرد. در این روش، داده‌ها به چند زیرمجموعه تقسیم می‌شوند و طبقه‌بند روی بخشی از داده‌ها آموزش می‌بیند و روی بخش باقی‌مانده آزمایش می‌شود. این فرآیند کمک می‌کند عملکرد مدل روی بخش‌های مختلف داده ارزیابی شود و در نهایت بهترین مجموعه پارامترها انتخاب گردد.

مثال

ما با وارد کردن ماژول GridSearchCV از کتابخانه‌ Scikit-learn شروع می‌کنیم. این ابزار برای انجام جستجوی شبکه‌ای (Grid Search) روی مجموعه‌ای از پارامترها به‌کار می‌رود.

ابتدا یک شبکه پارامتر (parameter grid) تعریف می‌کنیم که شامل مقادیر مختلف هر پارامتری است که می‌خواهیم آن را تنظیم (tune) کنیم.

سپس یک طبقه‌بند SVM با استفاده از SVC() ایجاد کرده و آن را به همراه شبکه پارامتر و تعداد foldهای اعتبارسنجی متقابل (cv=5) به GridSearchCV می‌دهیم. بعد از آن با فراخوانی grid_search.fit(X_train, y_train)، جستجوی شبکه‌ای آغاز می‌شود.

پس از تکمیل جستجو، می‌توانیم بهترین مجموعه پارامترها و همچنین بهترین دقت مدل را با استفاده از ویژگی‌های زیر چاپ کنیم:

  • grid_search.best_params_ → بهترین مجموعه پارامترها

  • grid_search.best_score_ → بهترین دقت حاصل‌شده

خروجی

پس از اجرای برنامه، خروجی به صورت زیر خواهد بود:

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

  • C = 0.1

  • coef0 = 0.5

  • degree = 3

  • gamma = ‘scale’

  • kernel = ‘poly’

و دقت به‌دست‌آمده روی داده‌های آموزشی برابر با ۹۷.۵٪ بوده است.

اکنون می‌توانیم از این مجموعه پارامترها برای ایجاد یک طبقه‌بند جدید SVM استفاده کرده و عملکرد آن را روی داده‌های تست ارزیابی کنیم.

مزایا و معایب طبقه‌بندهای SVM

مزایای طبقه‌بندهای SVM

  • طبقه‌بندهای SVM دقت بالایی دارند و عملکرد خوبی در فضای با ابعاد بالا ارائه می‌کنند.

  • این طبقه‌بندها عمدتاً از زیرمجموعه‌ای از نقاط آموزشی (support vectors) استفاده می‌کنند، بنابراین در نتیجه حافظه بسیار کمی مصرف می‌کنند.

معایب طبقه‌بندهای SVM

  • زمان آموزش آنها بالا است، بنابراین در عمل برای داده‌های بزرگ مناسب نیستند.

  • یکی دیگر از معایب این است که طبقه‌بندهای SVM با کلاس‌های همپوشان به خوبی عمل نمی‌کنند.

اگر هنوز با مفاهیم اولیه برنامه نویسی آشنا نیستید و می‌خواهید به‌طور اصولی یادگیری پایتون را شروع کنید، بهترین راه شروع، شرکت در آموزش پایتون از صفر است. این دوره به شما کمک می‌کند تا با اصول اولیه پایتون آشنا شوید و به تدریج مهارت‌های لازم برای پیاده‌سازی الگوریتم‌های یادگیری ماشین و پروژه‌های پیچیده را کسب کنید.

5/5 - (1 امتیاز)

راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.

دوره صفر تا صد آموزش بین المللی لینوکس
  • انتشار: ۱ شهریور ۱۴۰۴

دسته بندی موضوعات

آخرین محصولات فروشگاه

مشاهده همه

نظرات

بازخوردهای خود را برای ما ارسال کنید