فاز 2 · درس 5

ماشین‌های بردار پشتیبان (SVM)؛ از فرمول‌بندی ریاضی تا پیاده‌سازی

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
پیش‌نیاز
بخش 1 (درس‌های 08 بهینه‌سازی، 14 نُرم‌ها و فاصله‌ها، 18 بهینه‌سازی محدب)
خیابانی آسفالت‌شده و پهن با دو ردیف خط‌کشی سفید ضخیم که گوی‌های هندسی قرمز و آبی را در دو سمت جدا کرده است
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. دسته‌بند با بیشینه‌ی حاشیه
  5. بردارهای پشتیبان: اقلیت حیاتی
  6. حاشیه‌ی نرم: مهار نوفه با پارامتر C
  7. تابع زیان لولا: تابع زیان SVM
  8. آموزش SVM خطی با گرادیان کاهشی
  9. فرم دوگان و ترفند کرنل
  10. SVM برای رگرسیون (SVR)
  11. چرا یادگیری عمیق گوی سبقت را ربود؟ (و SVM هنوز کجا برنده است؟)
  12. ساخت مدل
  13. گام 1: تابع زیان لولا و گرادیان
  14. گام 2: SVM خطی با گرادیان کاهشی
  15. گام 3: توابع کرنل
  16. گام 4: شناسایی حاشیه و بردارهای پشتیبان
  17. استفاده‌ی عملی
  18. تمرین‌ها
  19. اصطلاحات کلیدی
  20. برای مطالعه‌ی بیشتر

در مسائل دسته‌بندی با بی‌نهایت خط یا ابرصفحه روبه‌رو می‌شویم که می‌توانند داده‌ها را جدا کنند؛ اما سوال اساسی این است که کدام مرز بهترین عملکرد را روی داده‌های آینده دارد؟ ماشین‌های بردار پشتیبان (Support Vector Machines یا SVM) با ایده‌ی ساده اما قدرتمند «پهن‌ترین خیابان ممکن بین دو کلاس»، این چالش را به‌صورت یک مسئله‌ی بهینه‌سازی دقیق و شفاف حل می‌کنند.

اگرچه با گسترش یادگیری عمیق تمرکز بسیاری از پروژه‌ها تغییر کرد، اما SVMها همچنان برای مجموعه‌داده‌های کوچک تا متوسط، داده‌های تنک و با ابعاد بالا (مانند متن‌های پردازش‌شده با TF-IDF) و سیستم‌هایی که نیاز به تضمین‌های ریاضی دارند، سریع‌ترین و بهینه‌ترین گزینه‌اند.

در این درس علاوه بر بررسی ریاضیات پایه‌ای نظیر بیشینه‌سازی حاشیه، زیان لولا و ترفند کرنل، یک دسته‌بند SVM خطی را با پایتون از صفر می‌سازید و نحوه‌ی استفاده‌ی اصولی از آن را در کتابخانه‌ی scikit-learn یاد می‌گیرید.

پهن‌ترین خیابان ممکن را بین دو کلاس پیدا کنید؛ کل ایده در همین خلاصه می‌شود.

اهداف یادگیری

  • پیاده‌سازی یک SVM خطی از صفر با استفاده از تابع زیان لولا (hinge loss) و گرادیان کاهشی (gradient descent) روی فرم اولیه (primal formulation)
  • توضیح اصل بیشینه‌سازی حاشیه (maximum margin) و شناسایی بردارهای پشتیبان (support vectors) در یک مدل آموزش‌دیده
  • مقایسه‌ی کرنل‌های خطی، چندجمله‌ای و RBF و توضیح این‌که ترفند کرنل (kernel trick) چطور جلوی نگاشت صریح به فضاهای با ابعاد بالا را می‌گیرد
  • ارزیابی مصالحه‌ی حاصل از پارامتر C بین عرض حاشیه و خطاهای دسته‌بندی

صورت مسئله

فرض کنید دو کلاس از نقاط داده دارید و می‌خواهید خطی (یا ابرصفحه‌ای) بکشید که آن‌ها را از هم جدا کند. بی‌نهایت خط مختلف می‌توانند این کار را انجام دهند؛ اما کدام‌یک را باید انتخاب کنید؟

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

این شهود ساده پایه و اساس ماشین‌های بردار پشتیبان (Support Vector Machines یا SVM) را می‌سازد؛ یکی از دقیق‌ترین و زیباترین الگوریتم‌های یادگیری ماشین از نظر ریاضیات. ماشین‌های بردار پشتیبان پیش از دوران یادگیری عمیق (deep learning)، روش غالب دسته‌بندی بودند. امروز هم برای مجموعه‌داده‌های کوچک، داده‌های با ابعاد بالا و مسائلی که به مدلی اصولی و شفاف با تضمین‌های نظری نیاز دارند، بهترین گزینه‌اند.

این مبحث پیوند مستقیمی با بخش 1 دوره دارد: بهینه‌سازی (optimization) در اینجا کوژ یا محدب (convex) است (درس 18)، اندازه‌گیری حاشیه با نُرم‌ها انجام می‌شود (درس 14) و ترفند کرنل با بهره‌گیری از ضرب‌های داخلی (dot products)، بدون نیاز به محاسبه در فضای چندبعدی، مرزهای غیرخطی را مدیریت می‌کند.

مفاهیم پایه

دسته‌بند با بیشینه‌ی حاشیه

فرض کنید داده‌هایی تفکیک‌پذیر به‌صورت خطی با برچسب‌های yi∈{−1,+1}y_i \in \lbrace -1, +1 \rbrace و بردارهای ویژگی xix_i داریم. هدف ما یافتن ابرصفحه‌ی wTx+b=0w^T x + b = 0 است که این دو کلاس را از هم جدا کند.

فاصله‌ی نقطه‌ی xix_i تا این ابرصفحه برابر است با:

distance=∣wTxi+b∣∥w∥\text{distance} = \frac{\lvert w^T x_i + b \rvert}{\lVert w \rVert}

برای نقطه‌ای که درست دسته‌بندی شده باشد: yi(wTxi+b)>0y_i (w^T x_i + b) > 0. عرض حاشیه، دو برابرِ فاصله‌ی ابرصفحه تا نزدیک‌ترین نقطه در هر دو طرف است:

حاشیهw^T x + b = +1w^T x + b = 0w^T x + b = -1نقاط کلاس +نقاط کلاس -مرز تصمیم‌گیری

مسئله‌ی بهینه‌سازی به‌صورت زیر تعریف می‌شود:

maximize2∥w∥(the margin width)subject toyi(wTxi+b)≥1for all i\begin{aligned} \text{maximize} \quad & \frac{2}{\lVert w \rVert} \quad \text{(the margin width)} \\ \text{subject to} \quad & y_i (w^T x_i + b) \ge 1 \quad \text{for all } i \end{aligned}

به شکلی معادل (از آنجا که کمینه‌سازی ∥w∥2\lVert w \rVert^2 از نظر بهینه‌سازی ساده‌تر است):

minimize12∥w∥2subject toyi(wTxi+b)≥1for all i\begin{aligned} \text{minimize} \quad & \frac{1}{2} \lVert w \rVert^2 \\ \text{subject to} \quad & y_i (w^T x_i + b) \ge 1 \quad \text{for all } i \end{aligned}

این مسئله یک برنامه‌ریزی درجه‌دوم محدب (convex quadratic program) است و یک پاسخ بهینه‌ی سراسری یکتا دارد. نقاط داده‌ای که دقیقاً روی مرز حاشیه‌ها قرار می‌گیرند (جایی که yi(wTxi+b)=1y_i (w^T x_i + b) = 1)، بردارهای پشتیبان نام دارند. مرز تصمیم‌گیری فقط و فقط با این نقاط تعیین می‌شود. اگر نقطه‌ای غیر از بردارهای پشتیبان را جابه‌جا یا حذف کنید، مرز تغییری نمی‌کند.

بردارهای پشتیبان: اقلیت حیاتی

دسته‌بندیبردار پشتیبان (کلاس +)y(w'x+b) = 1مرز تصمیم‌گیریw'x+b = 0بردار پشتیبان (کلاس -)y(w'x+b) = 1سایر نقاط +(بدون تاثیر بر مرز)سایر نقاط -(بدون تاثیر بر مرز)

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

علاوه بر این، تعداد بردارهای پشتیبان کرانی برای خطای تعمیم مدل فراهم می‌کند. کمتر بودن تعداد این بردارها نسبت به کل داده‌ها، نشان‌دهنده‌ی تعمیم‌پذیری بهتر است.

حاشیه‌ی نرم: مهار نوفه با پارامتر C

داده‌های دنیای واقعی به‌ندرت کاملاً تفکیک‌پذیر خطی هستند. همیشه نقاطی پیدا می‌شوند که در سمت اشتباه مرز یا درون حاشیه بیفتند. فرمول‌بندی حاشیه‌ی نرم (soft margin) با معرفی متغیرهای متغیر شل یا کمکی (slack variables)، اجازه می‌دهد تخطی‌هایی رخ دهد:

minimize12∥w∥2+C∑iξisubject toyi(wTxi+b)≥1−ξiξi≥0for all i\begin{aligned} \text{minimize} \quad & \frac{1}{2} \lVert w \rVert^2 + C \sum_i \xi_i \\ \text{subject to} \quad & y_i (w^T x_i + b) \ge 1 - \xi_i \\ & \xi_i \ge 0 \quad \text{for all } i \end{aligned}

متغیر کمکی ξi\xi_i نشان می‌دهد که نقطه‌ی ii چقدر از حاشیه تخطی کرده است. پارامتر CC تعادل بین دو هدف را تنظیم می‌کند:

مقدار CC رفتار
CC بزرگ تخطی‌ها را به‌شدت جریمه می‌کند. حاشیه باریک‌تر می‌شود و خطاهای دسته‌بندی کاهش می‌یابد. دچار بیش‌برازش (overfitting) می‌شود
CC کوچک تخطی بیشتری را مجاز می‌شمارد. حاشیه پهن‌تر می‌شود و خطاهای دسته‌بندی افزایش می‌یابد. دچار کم‌برازش (underfitting) می‌شود

در واقع CC معکوس شدت منظم‌سازی (regularization) است؛ یعنی CC بزرگ برابر با منظم‌سازی کمتر و CC کوچک برابر با منظم‌سازی بیشتر است.

تابع زیان لولا: تابع زیان SVM

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

minimize12∥w∥2+C∑imax⁡(0,1−yi(wTxi+b))\text{minimize} \quad \frac{1}{2} \lVert w \rVert^2 + C \sum_i \max(0, 1 - y_i (w^T x_i + b))

عبارت max⁡(0,1−yif(xi))\max(0, 1 - y_i f(x_i)) همان تابع زیان لولا (hinge loss) است. اگر نقطه‌ای درست دسته‌بندی شود و بیرون از حاشیه باشد، زیان آن صفر است؛ اما اگر درون حاشیه قرار بگیرد یا اشتباه دسته‌بندی شود، زیان به‌شکل خطی جریمه می‌شود.

Hinge loss for a single point:

loss
  |
  | \
  |  \
  |   \
  |    \
  |     \_______________
  |
  +-----|-----|-------->  y * f(x)
       0     1

Zero loss when y*f(x) >= 1 (correctly classified, outside margin).
Linear penalty when y*f(x) < 1.

آن را با تابع زیان لجستیک (در رگرسیون لجستیک) مقایسه کنید:

Hinge:max⁡(0,1−yf(x))Hard cutoff at marginLogistic:log⁡(1+exp⁡(−yf(x)))Smooth, never exactly zero\begin{aligned} \text{Hinge:} \quad & \max(0, 1 - y f(x)) && \text{Hard cutoff at margin} \\ \text{Logistic:} \quad & \log(1 + \exp(-y f(x))) && \text{Smooth, never exactly zero} \end{aligned}

زیان لولا جواب‌هایی تنک یا اسپارس (sparse) تولید می‌کند (تنها بردارهای پشتیبان سهمی غیرصفر دارند). در مقابل، تابع زیان لجستیک از تک‌تک نقاط داده استفاده می‌کند. این ویژگی، مصرف حافظه‌ی SVM را هنگام پیش‌بینی بسیار کم می‌کند.

آموزش SVM خطی با گرادیان کاهشی

می‌توانید یک SVM خطی را مستقیماً با استفاده از گرادیان کاهشی روی زیان لولا به‌همراه منظم‌سازی L2 آموزش دهید، بدون اینکه نیازی به حل مسئله‌ی برنامه‌ریزی درجه‌دوم قیددار باشد:

L(w,b)=λ2∥w∥2+1n∑imax⁡(0,1−yi(wTxi+b))Gradient with respect to w:If yi(wTxi+b)≥1:∂L∂w=λwIf yi(wTxi+b)<1:∂L∂w=λw−yixiGradient with respect to b:If yi(wTxi+b)≥1:∂L∂b=0If yi(wTxi+b)<1:∂L∂b=−yi\begin{aligned} & L(w, b) = \frac{\lambda}{2} \lVert w \rVert^2 + \frac{1}{n} \sum_i \max(0, 1 - y_i (w^T x_i + b)) \\[6pt] & \text{Gradient with respect to } w\text{:} \\ & \quad \text{If } y_i (w^T x_i + b) \ge 1\text{:} \quad \frac{\partial L}{\partial w} = \lambda w \\ & \quad \text{If } y_i (w^T x_i + b) < 1\text{:} \quad \frac{\partial L}{\partial w} = \lambda w - y_i x_i \\[6pt] & \text{Gradient with respect to } b\text{:} \\ & \quad \text{If } y_i (w^T x_i + b) \ge 1\text{:} \quad \frac{\partial L}{\partial b} = 0 \\ & \quad \text{If } y_i (w^T x_i + b) < 1\text{:} \quad \frac{\partial L}{\partial b} = -y_i \end{aligned}

به این ساختار فرم اولیه (primal formulation) می‌گویند. پیچیدگی زمانی آن در هر دور آموزش (epoch) برابر با O(n⋅d)O(n \cdot d) است که در آن nn تعداد نمونه‌ها و dd تعداد ویژگی‌هاست. این روش برای داده‌های بسیار بزرگ، اسپارس و با ابعاد بالا (مانند دسته‌بندی متن) بسیار سریع عمل می‌کند.

فرم دوگان و ترفند کرنل

فرم دوگان لاگرانژی (Lagrangian dual) مسئله‌ی SVM (برگرفته از شرایط KKT در درس 18 بخش 1) عبارت است از:

maximize∑iαi−12∑i,jαiαjyiyj(xi⋅xj)subject to0≤αi≤C∑iαiyi=0\begin{aligned} \text{maximize} \quad & \sum_i \alpha_i - \frac{1}{2} \sum_{i,j} \alpha_i \alpha_j y_i y_j (x_i \cdot x_j) \\ \text{subject to} \quad & 0 \le \alpha_i \le C \\ & \sum_i \alpha_i y_i = 0 \end{aligned}

فرم دوگان فقط شامل ضرب‌های داخلی xi⋅xjx_i \cdot x_j بین نقاط داده است؛ نکته‌ی کلیدی در همین نهفته است. کافی است هر ضرب داخلی را با یک تابع کرنل (kernel) به نام K(xi,xj)K(x_i, x_j) جایگزین کنید؛ با این کار، مدل مرزهای غیرخطی را یاد می‌گیرد بدون آنکه اصلاً نیازی به محاسبه‌ی صریح تبدیل داده‌ها در فضای ابعاد بالا باشد.

Linear kernel:K(x,z)=x⋅zPolynomial kernel:K(x,z)=(x⋅z+c)dRBF (Gaussian):K(x,z)=exp⁡(−γ∥x−z∥2)\begin{aligned} \text{Linear kernel:} \quad & K(x, z) = x \cdot z \\ \text{Polynomial kernel:} \quad & K(x, z) = (x \cdot z + c)^d \\ \text{RBF (Gaussian):} \quad & K(x, z) = \exp(-\gamma \lVert x - z \rVert^2) \end{aligned}

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

فضای ویژگی (تفکیک‌پذیر)فضای ورودی (تفکیک‌ناپذیر)ترفند کرنلK(x,z) = phi(x).phi(z)نقاط داده در 2Dمرز دایره‌اینقاط داده در ابعاد بالاترمرز خطی

ترفند کرنل ضرب داخلی را در فضای ابعاد بالا بدون پا گذاشتن به آن فضا محاسبه می‌کند. مثلاً در یک کرنل چندجمله‌ای با درجه‌ی dd در فضای DD بعدی، فضای ویژگی صریح عملاً O(Dd)O(D^d) بُعد دارد؛ اما K(x,z)K(x, z) در زمان O(D)O(D) محاسبه می‌شود.

SVM برای رگرسیون (SVR)

رگرسیون بردار پشتیبان (Support Vector Regression یا SVR) یک لوله با عرض ϵ\epsilon به دور داده‌ها برازش می‌دهد. نقاطی که درون این لوله قرار می‌گیرند هیچ زیانی ندارند و نقاط بیرون از لوله به‌شکل خطی جریمه می‌شوند.

minimize12∥w∥2+C∑i(ξi+ξi∗)subject toyi−(wTxi+b)≤ϵ+ξi(wTxi+b)−yi≤ϵ+ξi∗ξi,ξi∗≥0\begin{aligned} \text{minimize} \quad & \frac{1}{2} \lVert w \rVert^2 + C \sum_i (\xi_i + \xi_i^*) \\ \text{subject to} \quad & y_i - (w^T x_i + b) \le \epsilon + \xi_i \\ & (w^T x_i + b) - y_i \le \epsilon + \xi_i^* \\ & \xi_i, \xi_i^* \ge 0 \end{aligned}

پارامتر ϵ\epsilon عرض این لوله را کنترل می‌کند. لوله‌ی پهن‌تر یعنی بردارهای پشتیبان کمتر و برازش هموارتر؛ لوله‌ی باریک‌تر یعنی بردارهای پشتیبان بیشتر و برازش دقیق‌تر و محکم‌تر.

چرا یادگیری عمیق گوی سبقت را ربود؟ (و SVM هنوز کجا برنده است؟)

از اواخر دهه‌ی 1990 تا اوایل دهه‌ی 2010، SVM الگوریتم برتر یادگیری ماشین بود. اما یادگیری عمیق به چند دلیل از آن پیشی گرفت:

عامل SVM یادگیری عمیق
مهندسی ویژگی نیازمند آن است ویژگی‌ها را خودکار یاد می‌گیرد
مقیاس‌پذیری O(n2)O(n^2) تا O(n3)O(n^3) برای کرنل O(n)O(n) در هر دوره با SGD
تصویر/متن/صدا به ویژگی‌های دستی نیاز دارد از داده‌های خام یاد می‌گیرد
مجموعه‌داده‌های بزرگ (بیش از 100k) کند مقیاس‌پذیری عالی
شتاب‌دهی GPU بهره‌وری محدود جهش سرعت چشمگیر

با این حال، SVM در این موقعیت‌ها همچنان برنده است:

  • مجموعه‌داده‌های کم‌حجم (چند صد تا چند هزار نمونه)
  • داده‌های اسپارس با ابعاد بالا (مثل متن با ویژگی‌های TF-IDF)
  • مسائلی که به تضمین‌های ریاضی نیاز دارید (کران‌های حاشیه)
  • شرایطی که زمان آموزش باید در کمترین حد باشد (SVM خطی بسیار سریع است)
  • دسته‌بندی دوتایی با ساختار حاشیه‌ای شفاف
  • تشخیص ناهنجاری (One-Class SVM)
حاشیه SVMچرخاندن مرز، عریض‌تر کردن مسیر
SVM MARGINA support vector machine does not just separate the classes, it pushes the boundary as far from both as it can. The dashed lines mark the margin; the points touching them, ringed in gold, are the support vectors. Move every other point and nothing changes.
ماشین بردار پشتیبان صرفاً کلاس‌ها را جدا نمی‌کند، بلکه مرز را تا جای ممکن از هر دو دور می‌کند (push می‌کند). خطوط خط‌چین نشان‌دهنده حاشیه هستند؛ نقاطی که با آن‌ها در تماس‌اند و دورشان حلقه طلایی کشیده شده، بردارهای پشتیبان هستند. هر نقطه دیگری را جابه‌جا کنید، هیچ تغییری رخ نمی‌دهد.

ساخت مدل

گام 1: تابع زیان لولا و گرادیان

پایه‌ی کار: محاسبه‌ی تابع زیان لولا و گرادیان آن برای یک دسته (batch).

def hinge_loss(X, y, w, b):
    n = len(X)
    total_loss = 0.0
    for i in range(n):
        margin = y[i] * (dot(w, X[i]) + b)
        total_loss += max(0.0, 1.0 - margin)
    return total_loss / n

گام 2: SVM خطی با گرادیان کاهشی

آموزش از طریق کمینه‌سازی زیان لولای منظم‌شده، بدون نیاز به حل‌کننده‌ی برنامه‌ریزی درجه‌دوم.

class LinearSVM:
    def __init__(self, lr=0.001, lambda_param=0.01, n_epochs=1000):
        self.lr = lr
        self.lambda_param = lambda_param
        self.n_epochs = n_epochs
        self.w = None
        self.b = 0.0

    def fit(self, X, y):
        n_features = len(X[0])
        self.w = [0.0] * n_features
        self.b = 0.0

        for epoch in range(self.n_epochs):
            for i in range(len(X)):
                margin = y[i] * (dot(self.w, X[i]) + self.b)
                if margin >= 1:
                    self.w = [wj - self.lr * self.lambda_param * wj
                              for wj in self.w]
                else:
                    self.w = [wj - self.lr * (self.lambda_param * wj - y[i] * X[i][j])
                              for j, wj in enumerate(self.w)]
                    self.b -= self.lr * (-y[i])

    def predict(self, X):
        return [1 if dot(self.w, x) + self.b >= 0 else -1 for x in X]

گام 3: توابع کرنل

پیاده‌سازی کرنل‌های خطی، چندجمله‌ای و RBF.

def linear_kernel(x, z):
    return dot(x, z)

def polynomial_kernel(x, z, degree=3, c=1.0):
    return (dot(x, z) + c) ** degree

def rbf_kernel(x, z, gamma=0.5):
    diff = [xi - zi for xi, zi in zip(x, z)]
    return math.exp(-gamma * dot(diff, diff))

گام 4: شناسایی حاشیه و بردارهای پشتیبان

پس از آموزش، بردارهای پشتیبان را شناسایی کرده و عرض حاشیه را اندازه می‌گیریم.

def find_support_vectors(X, y, w, b, tol=1e-3):
    support_vectors = []
    for i in range(len(X)):
        margin = y[i] * (dot(w, X[i]) + b)
        if abs(margin - 1.0) < tol:
            support_vectors.append(i)
    return support_vectors

برای مشاهده‌ی پیاده‌سازی کامل به همراه همه‌ی مثال‌ها به فایل code/svm.py مراجعه کنید.

استفاده‌ی عملی

استفاده در scikit-learn:

from sklearn.svm import SVC, LinearSVC, SVR
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

clf = Pipeline([
    ("scaler", StandardScaler()),
    ("svm", SVC(kernel="rbf", C=1.0, gamma="scale")),
])
clf.fit(X_train, y_train)
print(f"Accuracy: {clf.score(X_test, y_test):.4f}")
print(f"Support vectors: {clf['svm'].n_support_}")

نکته‌ی مهم: همیشه ویژگی‌های خود را قبل از آموزش SVM مقیاس‌بندی (scale) کنید. ماشین‌های بردار پشتیبان به‌شدت به بزرگی مقیاس ویژگی‌ها حساس‌اند؛ زیرا اندازه‌ی حاشیه به ∥w∥\lVert w \rVert وابسته است و ویژگی‌های مقیاس‌بندی‌نشده هندسه‌ی فضا را به هم می‌ریزند.

برای مجموعه‌داده‌های بزرگ، به‌جای SVC (که از فرم دوگان استفاده می‌کند و پیچیدگی O(n2)O(n^2) تا O(n3)O(n^3){} دارد) از LinearSVC استفاده کنید که بر پایه‌ی فرم اولیه است و پیچیدگی خطی O(n⋅d)O(n \cdot d) در هر دوره بر حسب nn دارد:

from sklearn.svm import LinearSVC

clf = Pipeline([
    ("scaler", StandardScaler()),
    ("svm", LinearSVC(C=1.0, max_iter=10000)),
])

تمرین‌ها

  1. یک مجموعه‌داده‌ی دوبعدی با تفکیک‌پذیری خطی تولید کنید. مدل LinearSVM خودتان را روی آن آموزش داده و بردارهای پشتیبان را شناسایی کنید. بررسی کنید که آیا این بردارهای پشتیبان واقعاً نزدیک‌ترین نقاط به مرز تصمیم‌گیری هستند یا نه.

  2. روی یک مجموعه‌داده‌ی نوفه‌دار، مقدار CC را از 0.001 تا 1000 تغییر دهید. مرز تصمیم را برای هر مقدار CC رسم کنید. روند تغییر از حاشیه‌ی پهن (کم‌برازش) به حاشیه‌ی باریک (بیش‌برازش) را مشاهده و تحلیل کنید.

  3. مجموعه‌داده‌ای بسازید که مرز کلاس‌های آن دایره‌ای (غیرخطی) باشد. نشان دهید که SVM خطی در تفکیک آن شکست می‌خورد. سپس ماتریس کرنل RBF را محاسبه کنید و نشان دهید که کلاس‌ها در فضای ویژگی حاصل از کرنل تفکیک‌پذیر می‌شوند.

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

  5. الگوریتم SVR را بر پایه‌ی تابع زیان نامتعصب به اپسیلون (epsilon-insensitive loss) پیاده‌سازی کنید. آن را روی y=sin⁡(x)+noisey = \sin(x) + \text{noise} برازش دهید. لوله‌ی اپسیلون را در اطراف پیش‌بینی‌ها رسم کنید و بردارهای پشتیبان (نقاط خارج از لوله) را با رنگ مشخص نشان دهید.

اصطلاحات کلیدی

اصطلاح مفهوم واقعی
بردارهای پشتیبان (Support vectors) نقاط داده‌ی آموزشی نزدیک به مرز تصمیم‌گیری؛ تنها نقاطی که ابرصفحه را تعیین می‌کنند
حاشیه (Margin) فاصله‌ی بین مرز تصمیم‌گیری و نزدیک‌ترین بردارهای پشتیبان؛ هدف SVM بیشینه‌سازی این فاصله است
تابع زیان لولا (Hinge loss) max⁡(0,1−yf(x))\max(0, 1 - y f(x))؛ اگر نمونه درست و خارج از حاشیه دسته‌بندی شود صفر است و در غیر این صورت جریمه‌ی خطی دارد
پارامتر C مصالحه‌ی بین عرض حاشیه و خطاهای دسته‌بندی؛ CC بزرگ = حاشیه‌ی باریک، CC کوچک = حاشیه‌ی پهن
حاشیه‌ی نرم (Soft margin) فرمول‌بندی SVM که از طریق متغیرهای کمکی، تخطی از حاشیه را مجاز می‌داند و داده‌های غیرتفکیک‌پذیر را مدیریت می‌کند
ترفند کرنل (Kernel trick) محاسبه‌ی ضرب داخلی در فضای ویژگی با ابعاد بالا، بدون نگاشت صریح داده‌ها به آن فضا
کرنل خطی (Linear kernel) K(x,z)=x⋅zK(x, z) = x \cdot z؛ معادل ضرب داخلی استاندارد، مناسب برای داده‌های تفکیک‌پذیر خطی
کرنل RBF K(x,z)=exp⁡(−γ∥x−z∥2)K(x, z) = \exp(-\gamma \Vert x-z \Vert^2)؛ داده را به فضایی با ابعاد بی‌نهایت نگاشت می‌کند و توانایی یادگیری هر مرز همواری را دارد
کرنل چندجمله‌ای (Polynomial kernel) K(x,z)=(x⋅z+c)dK(x, z) = (x \cdot z + c)^d؛ داده‌ها را به فضای ویژگی از ترکیب‌های چندجمله‌ای نگاشت می‌کند
فرم دوگان (Dual formulation) بازنویسی مسئله‌ی SVM به‌طوری که فقط به ضرب داخلی بین نقاط داده وابسته باشد؛ این فرم بستر استفاده از کرنل‌ها را فراهم می‌کند
SVR رگرسیون بردار پشتیبان؛ لوله‌ای با عرض اپسیلون دور داده‌ها برازش می‌دهد و نقاط درون لوله هیچ زیانی ندارند
متغیرهای کمکی (Slack variables) ξi\xi_i؛ میزان تخطی یک نقطه از حاشیه را اندازه می‌گیرد و برای داده‌های درست دسته‌بندی‌شده‌ی بیرون حاشیه صفر است
بیشینه‌ی حاشیه (Maximum margin) اصل انتخاب ابرصفحه‌ای که فاصله‌اش تا نزدیک‌ترین نقاط هر کلاس بیشینه باشد

برای مطالعه‌ی بیشتر

سؤالات متداول

بردارهای پشتیبان در SVM دقیقاً چه هستند و چه نقشی دارند؟

بردارهای پشتیبان نزدیک‌ترین نقاط داده‌ی آموزشی به مرز تصمیم‌گیری هستند که روی لبه‌ی حاشیه قرار می‌گیرند. مرز تفکیک کلاس‌ها منحصراً توسط همین نقاط تعیین می‌شود و تغییر بقیه‌ی نقاط داده تأثیری روی مرز نهایی ندارد.

ترفند کرنل (Kernel Trick) در SVM چگونه کار می‌کند؟

ترفند کرنل امکان می‌دهد ضرب داخلی داده‌ها را در فضایی با ابعاد بسیار بالا یا نامتناهی، مستقیماً و بدون نگاشت صریح داده‌ها به آن فضا محاسبه کنید؛ در نتیجه داده‌های غیرتفکیک‌پذیر خطی با هزینه‌ی محاسباتی کم تفکیک می‌شوند.

پارامتر C در مدل SVM چه نقشی در کنترل برازش دارد؟

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

چرا باید قبل از آموزش SVM ویژگی‌ها را مقیاس‌بندی (Scale) کرد؟

حاشیه‌ی SVM مستقیماً بر اساس نُرم بردار وزن‌ها محاسبه می‌شود. اگر ویژگی‌ها مقیاس یکسانی نداشته باشند، ویژگی با دامنه‌ی بزرگ‌تر هندسه‌ی مسئله را مخدوش کرده و تصمیم‌گیری مدل را به اشتباه می‌اندازد.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.