FA-TOOLS — Header Component

**آموزش SVM با scikit-learn و مثال کاربردی**

رفیق، اگه دنبال ابزارهای خفن برنامه‌نویسی می‌گردی، یه سر به [فروشگاه ابزارهای برنامه‌نویسی ما](https://fa-tools.ir/) بزن و کدهای آماده و ابزارهای کاربردی رو از دست نده!
برای مشاوره یا همکاری می‌تونی با این شماره تماس بگیری: **tel:09202232789**

**🗺️ نقشه راه تو برای تسلط بر SVM با scikit-learn 🗺️**

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ **✔️ گام ۱: SVM چیه؟** ┃
┃ ➤ آشنایی با مفاهیم اصلی (Hyperplane, Margin, Support Vectors) ┃
┃ ➤ کاربردها و مزایا/معایب ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۲: آماده‌سازی داده‌ها** ┃
┃ ➤ پاکسازی، پیش‌پردازش، تقسیم (Train/Test) و مقیاس‌بندی ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۳: پیاده‌سازی با scikit-learn** ┃
┃ ➤ کدنویسی گام‌به‌گام (نصب، ایمپورت، آموزش مدل) ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۴: هسته‌ها (Kernels)** ┃
┃ ➤ مفهوم Kernel Trick و انواع هسته‌ها (Linear, RBF, Poly) ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۵: تنظیم پارامترها (C, Gamma, Degree)** ┃
┃ ➤ بهینه‌سازی مدل برای بهترین عملکرد ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۶: مثال کاربردی** ┃
┃ ➤ دسته‌بندی عملی با داده‌های واقعی (Iris) ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ **✔️ گام ۷: عیب‌یابی سریع** ┃
┃ ➤ راه‌حل مشکلات رایج در پیاده‌سازی SVM ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

سلام رفیق برنامه‌نویس! اگه تا حالا اسم SVM یا Support Vector Machine رو شنیدی و خواستی بدونی چطور می‌شه از این الگوریتم قدرتمند توی پروژه‌های یادگیری ماشینت استفاده کنی، جای درستی اومدی. SVM یکی از اون الگوریتم‌های کلاسیک و در عین حال خیلی کارآمد تو دنیای ماشین لرنینگه که می‌تونه تو کارهای دسته‌بندی (Classification) و حتی رگرسیون (Regression) حرف‌های زیادی برای گفتن داشته باشه. امروز می‌خوایم با هم قدم به قدم پیش بریم، ببینیم SVM اصلاً چیه، چرا انقدر محبوبه و چطوری می‌تونیم با کمک کتابخونه فوق‌العاده scikit-learn تو پایتون، یه مدل SVM رو پیاده‌سازی کنیم. آماده‌ای یه ابزار جدید و قوی به جعبه ابزار برنامه‌نویسیت اضافه کنی؟ پس بزن بریم!

SVM چیه و چرا باید سراغش بریم؟ (مفاهیم اساسی)

تصور کن یه عالمه نقطه تو یه صفحه داری که هر کدومشون به یه گروه خاص (مثلاً سیب و پرتقال) تعلق دارن. کار SVM اینه که یه خط (یا یه صفحه تو ابعاد بالاتر که بهش می‌گیم هایپرپلین – Hyperplane) پیدا کنه که این دو تا گروه رو از هم جدا کنه. اما نه هر خطی! SVM دنبال خطی می‌گرده که بیشترین فاصله رو با نزدیک‌ترین نقاط هر دو گروه داشته باشه. این فاصله رو “مارجین” (Margin) می‌گیم و اون نقاطی که نزدیک‌ترین فاصله رو به هایپرپلین دارن، “بردارهای پشتیبان” (Support Vectors) نامیده می‌شن. در واقع، کل مدل SVM فقط با همین بردارهای پشتیبان کار می‌کنه و بقیه نقاط براش مهم نیستن. این قضیه باعث می‌شه که SVM تو شرایط خاص خیلی کارآمد باشه.

مقدمه‌ای بر SVM

SVM یه الگوریتم یادگیری نظارت شده (Supervised Learning) هست که هم برای دسته‌بندی و هم برای رگرسیون استفاده می‌شه. هدف اصلیش پیدا کردن بهترین هایپرپلین جداکننده بین کلاس‌هاست. این بهترین هایپرپلین، همونطور که گفتیم، هایپرپلینیه که بیشترین مارجین رو داره. همین خاصیت باعث میشه مدل ما تعمیم‌پذیری (Generalization) خوبی داشته باشه و روی داده‌های جدید هم خوب عمل کنه.

کاربردهای SVM

* **دسته‌بندی متون و تصاویر:** تشخیص اسپم، دسته‌بندی اخبار، تشخیص چهره.
* **بیوانفورماتیک:** دسته‌بندی پروتئین‌ها.
* **تشخیص بیماری:** تحلیل داده‌های پزشکی برای تشخیص بیماری‌ها.
* **پیش‌بینی بازار بورس:** البته با احتیاط زیاد، چون بازار بورس پیچیده است!

مزایای SVM

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

معایب SVM

* **حساسیت به نویز:** اگه داده‌های آموزشیت خیلی نویز (outliers) داشته باشن، عملکرد مدل ممکنه پایین بیاد. چون SVM روی بردارهای پشتیبان تمرکز می‌کنه که ممکنه همون نویزها باشن.
* **زمان آموزش بالا برای داده‌های بزرگ:** برای مجموعه داده‌های خیلی بزرگ، آموزش SVM می‌تونه زمان‌بر باشه.
* **سختی در انتخاب هسته و پارامترها:** انتخاب بهترین هسته و تنظیم پارامترها نیاز به تجربه و آزمایش داره.

چرا scikit-learn رفیق شفیق ماست؟

scikit-learn (یا sklearn) یه کتابخونه پایتون برای یادگیری ماشینه که ابزارهای خیلی قدرتمندی برای مدل‌سازی پیش‌بینی‌کننده فراهم می‌کنه. خوبی scikit-learn اینه که یه API (رابط برنامه‌نویسی کاربردی) یکپارچه داره. یعنی هر مدلی رو بخوای باهاش پیاده‌سازی کنی (چه SVM، چه درخت تصمیم، چه رگرسیون لجستیک)، مراحل کارش تقریباً یکسانه:
1. **تعریف مدل (Instantiate):** یه نمونه از کلاسی که مدل رو پیاده‌سازی کرده می‌سازی.
2. **آموزش مدل (Fit):** مدل رو با داده‌های آموزشیت آموزش می‌دی.
3. **پیش‌بینی (Predict):** با مدل آموزش‌دیده، روی داده‌های جدید پیش‌بینی انجام می‌دی.
4. **ارزیابی (Evaluate):** عملکرد مدل رو با معیارهای مختلف بررسی می‌کنی.

این سادگی و یکپارچگی باعث شده scikit-learn به یکی از محبوب‌ترین کتابخانه‌ها تو دنیای یادگیری ماشین تبدیل بشه. کلی از [کدهای آماده و اسنیپت‌های پایتون](https://fa-tools.ir/snippets/python/) که تو پروژه‌ها به دردت می‌خورن رو می‌تونی با همین کتابخونه بنویسی.

آماده‌سازی داده‌ها: زیربنای یک مدل موفق

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

جمع‌آوری و کاوش داده (EDA)

اولین قدم اینه که داده‌هات رو جمع‌آوری کنی و یه نگاه کلی بهشون بندازی. ببینی چه ویژگی‌هایی دارن، توزیعشون چطوره، آیا مقادیر پرت (Outliers) یا نویز دارن یا نه. این مرحله بهت کمک می‌کنه تا مشکلات احتمالی داده‌ها رو کشف کنی.

پاکسازی و پیش‌پردازش

* **مقادیر گم‌شده (Missing Values):** اگه داده‌هات جاهای خالی دارن، باید یه فکری به حالشون کنی. می‌تونی اون سطرها رو حذف کنی، یا با میانگین، میانه یا مد پرشون کنی.
* **ان کدینگ (Encoding):** اگه ویژگی‌های دسته‌ای (Categorical Features) داری (مثلاً رنگ: قرمز، آبی، سبز)، باید اون‌ها رو به فرمت عددی تبدیل کنی تا مدل بتونه باهاشون کار کنه. One-Hot Encoding و Label Encoding دو تا از روش‌های رایج هستن.

تقسیم داده (Train/Test Split)

یه اشتباه بزرگ اینه که مدل رو با همه داده‌ها آموزش بدیم و بعد با همون داده‌ها ارزیابی کنیم. مدل اینطوری همه چیز رو حفظ می‌کنه و روی داده‌های جدید عملکرد خوبی نداره. برای جلوگیری از این مشکل، داده‌هامون رو به دو بخش تقسیم می‌کنیم:
* **مجموعه آموزش (Training Set):** مدلمون با این بخش آموزش می‌بینه.
* **مجموعه تست (Test Set):** برای ارزیابی عملکرد نهایی مدل روی داده‌هایی که قبلاً ندیده استفاده می‌شه. معمولاً از نسبت 70/30 یا 80/20 استفاده می‌شه.

اهمیت مقیاس‌بندی (Scaling)

یکی از مهم‌ترین قدم‌ها برای SVM، مقیاس‌بندی داده‌هاست. SVM به مقیاس ویژگی‌ها خیلی حساسه. اگه یه ویژگی دامنه مقداری خیلی بزرگی داشته باشه (مثلاً درآمد بین 1 میلیون تا 100 میلیون) و یه ویژگی دیگه دامنه کوچیکی (مثلاً سن بین 18 تا 80)، SVM ممکنه بیشتر به ویژگی با دامنه بزرگتر اهمیت بده. مقیاس‌بندی باعث می‌شه همه ویژگی‌ها در یک محدوده قرار بگیرن و مدل عادلانه‌تر عمل کنه.
روش‌های رایج:
* **StandardScaler:** داده‌ها رو طوری تغییر می‌ده که میانگین صفر و واریانس یک داشته باشن.
* **MinMaxScaler:** داده‌ها رو به یک محدوده مشخص (معمولاً بین 0 و 1) منتقل می‌کنه.

پیاده‌سازی گام‌به‌گام SVM با scikit-learn (با مثال پایتون)

خب رفیق، حالا که فهمیدیم SVM چیه و داده‌ها رو چطور آماده کنیم، وقتشه بریم سراغ بخش هیجان‌انگیز قضیه: کدنویسی!

نصب و ایمپورت کتابخانه‌ها

اول از همه باید مطمئن بشی scikit-learn رو نصب داری. اگه نه، با این دستور می‌تونی نصبش کنی:
“`bash
pip install scikit-learn pandas numpy matplotlib
“`

حالا بیا کتابخانه‌های لازم رو ایمپورت کنیم:
“`python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report
from sklearn.datasets import make_classification # برای ساخت داده مصنوعی
“`

ساخت یک مجموعه داده مصنوعی

برای اینکه مثالمون ساده و قابل فهم باشه، یه مجموعه داده دو کلاسه مصنوعی می‌سازیم. این داده‌ها دوتا ویژگی و یه برچسب (label) دارن.
“`python
# ساخت یک مجموعه داده مصنوعی برای دسته‌بندی
X, y = make_classification(n_samples=100, n_features=2, n_informative=2,
n_redundant=0, n_clusters_per_class=1, random_state=42)

# تبدیل به DataFrame برای راحتی کار
df = pd.DataFrame(data=X, columns=[‘Feature_1’, ‘Feature_2’])
df[‘Target’] = y

print(“نمونه‌ای از داده‌های مصنوعی:”)
print(df.head())

# رسم داده‌ها
plt.figure(figsize=(8, 6))
plt.scatter(df[df[‘Target’]==0][‘Feature_1’], df[df[‘Target’]==0][‘Feature_2′], color=’red’, label=’Class 0′)
plt.scatter(df[df[‘Target’]==1][‘Feature_1’], df[df[‘Target’]==1][‘Feature_2′], color=’blue’, label=’Class 1′)
plt.title(‘داده‌های مصنوعی دسته‌بندی’)
plt.xlabel(‘ویژگی 1’)
plt.ylabel(‘ویژگی 2’)
plt.legend()
plt.grid(True)
plt.show()
“`

تقسیم و مقیاس‌بندی داده‌ها

حالا داده‌ها رو به مجموعه آموزش و تست تقسیم می‌کنیم و بعد مقیاس‌بندی رو انجام می‌دیم.
یادت باشه، StandardScaler رو روی `X_train` فیت می‌کنیم و هم `X_train` و هم `X_test` رو با همون فیت ترنسفورم می‌کنیم. این نکته خیلی مهمیه که در **پردزاش** داده‌ها همیشه رعایت کنی.
“`python
# تقسیم داده به آموزش و تست
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# مقیاس‌بندی ویژگی‌ها
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

print(“nابعاد داده‌های آموزش پس از مقیاس‌بندی:”, X_train_scaled.shape)
print(“ابعاد داده‌های تست پس از مقیاس‌بندی:”, X_test_scaled.shape)
“`

تعریف و آموزش مدل SVC (Support Vector Classifier)

برای دسته‌بندی، از کلاس `SVC` در scikit-learn استفاده می‌کنیم.
“`python
# تعریف مدل SVM (با هسته خطی)
# C پارامتری برای تنظیم میزان خطای مجاز است.
model = svm.SVC(kernel=’linear’, C=1)

# آموزش مدل با داده‌های مقیاس‌بندی شده
print(“nدر حال آموزش مدل SVM…”)
model.fit(X_train_scaled, y_train)
print(“مدل با موفقیت آموزش داده شد.”)
“`

پیش‌بینی و ارزیابی مدل

حالا که مدل آموزش دید، می‌تونیم روی داده‌های تست پیش‌بینی انجام بدیم و ببینیم چقدر خوب عمل کرده.
“`python
# پیش‌بینی روی داده‌های تست مقیاس‌بندی شده
y_pred = model.predict(X_test_scaled)

# ارزیابی عملکرد مدل
print(“n— ارزیابی عملکرد مدل —“)
print(“دقت مدل (Accuracy):”, accuracy_score(y_test, y_pred))
print(“nگزارش دسته‌بندی:n”, classification_report(y_test, y_pred))

# رسم هایپرپلین جداکننده (فقط برای داده‌های 2D)
def plot_svc_decision_boundary(model, X, y, scaler, title=”SVM Decision Boundary”):
plt.figure(figsize=(10, 7))
# داده‌ها را به مقیاس اصلی برمی‌گردانیم تا رسم راحت‌تر باشد
X_original = scaler.inverse_transform(X)
plt.scatter(X_original[:, 0], X_original[:, 1], c=y, s=30, cmap=plt.cm.Paired, edgecolors=’k’)

ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()

# ساخت شبکه‌ای از نقاط برای رسم هایپرپلین
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T

# نقاط شبکه را مقیاس‌بندی می‌کنیم تا مدل پیش‌بینی کند
xy_scaled = scaler.transform(xy)
Z = model.decision_function(xy_scaled).reshape(XX.shape)

# رسم هایپرپلین جداکننده و مارجین‌ها
ax.contour(XX, YY, Z, colors=’k’, levels=[-1, 0, 1], alpha=0.5,
linestyles=[‘–‘, ‘-‘, ‘–‘])
# رسم بردارهای پشتیبان
sv_original = scaler.inverse_transform(model.support_vectors_)
ax.scatter(sv_original[:, 0], sv_original[:, 1], s=100,
facecolors=’none’, edgecolors=’k’, marker=’o’, label=’بردارهای پشتیبان’)
plt.title(title)
plt.xlabel(‘ویژگی 1’)
plt.ylabel(‘ویژگی 2’)
plt.legend()
plt.grid(True)
plt.show()

plot_svc_decision_boundary(model, X_test_scaled, y_test, scaler, title=”مرز تصمیم SVM (هسته خطی)”)
“`
با این کدها، تونستیم یه مدل SVM ساده رو با هسته خطی آموزش بدیم و عملکردش رو ببینیم. اما SVM یه ابزار قدرتمندتر هم داره: هسته‌ها!

هسته‌ها (Kernels): موتور قدرتمند SVM

گفتیم که SVM یه هایپرپلین جداکننده پیدا می‌کنه. اما چی میشه اگه داده‌ها به صورت خطی قابل جداسازی نباشن؟ یعنی نتونیم با یه خط صاف (یا صفحه تو ابعاد بالاتر) اون‌ها رو از هم جدا کنیم؟ اینجاست که مفهوم **Kernel Trick** وارد بازی میشه!

مفهوم Kernel Trick

Kernel Trick یه ترفند ریاضیاتی هوشمندانه‌ست که به SVM اجازه می‌ده داده‌هایی رو که به صورت خطی جداشدنی نیستن، تو یه فضای با ابعاد بالاتر (High-Dimensional Space) به صورت خطی جدا کنه. بدون اینکه واقعاً نیازی به انتقال داده‌ها به اون فضای پرهزینه باشه، هسته یه تابع شباهت (Similarity Function) رو محاسبه می‌کنه. در واقع، هسته فقط به ما میگه که داده‌ها تو اون فضای بالاتر چقدر به هم شبیه هستن، بدون اینکه لازم باشه خود داده‌ها رو به اون فضا ببریم. این کار محاسبات رو خیلی سبک‌تر می‌کنه.

انواع هسته‌ها و کاربردها

scikit-learn هسته‌های مختلفی رو پشتیبانی می‌کنه:

* **Linear Kernel (هسته خطی):**
* **کاربرد:** برای داده‌هایی که به صورت خطی جداشدنی هستن. ساده‌ترین و سریع‌ترین هسته.
* **فرمول تقریبی:** `K(x, xi) = x . xi` (ضرب داخلی)

* **Polynomial Kernel (هسته چندجمله‌ای):**
* **کاربرد:** برای داده‌هایی که مرز تصمیمشون منحنیه.
* **فرمول تقریبی:** `K(x, xi) = (gamma * (x . xi) + r)^degree`
* پارامتر `degree` (درجه) و `gamma` و `coef0` (یا `r`) اینجا مهمن.

* **RBF (Radial Basis Function) / Gaussian Kernel (هسته شعاعی یا گوسی):**
* **کاربرد:** یکی از پرکاربردترین و قدرتمندترین هسته‌ها. برای داده‌هایی که مرز تصمیمشون خیلی پیچیده‌ست و به صورت کروی یا موجی جدا میشن، عالیه.
* **فرمول تقریبی:** `K(x, xi) = exp(-gamma * ||x – xi||^2)`
* پارامتر `gamma` اینجا خیلی مهمه و میزان “تاثیر” یک نمونه آموزشی رو مشخص می‌کنه.

* **Sigmoid Kernel (هسته سیگموئید):**
* **کاربرد:** کمتر از بقیه استفاده می‌شه و بیشتر برای شبکه‌های عصبی کاربرد داره، اما گاهی اوقات می‌تونه مفید باشه.
* **فرمول تقریبی:** `K(x, xi) = tanh(gamma * (x . xi) + r)`

انتخاب هسته مناسب

انتخاب هسته بستگی به ساختار داده‌های شما داره. هیچ قانون طلایی برای انتخاب بهترین هسته وجود نداره و اغلب باید با آزمایش و خطا (Grid Search یا Randomized Search) بهترینش رو پیدا کنی. اما یه جدول مقایسه‌ای سریع می‌تونه بهت کمک کنه:

جدول مقایسه هسته‌های رایج SVM
هسته (Kernel) کاربرد و ویژگی‌ها
**Linear (خطی)**
  • برای داده‌هایی که به صورت خطی جداشدنی هستند.
  • سریع‌ترین هسته، کمتر محاسباتی.
  • اگر تعداد ویژگی‌ها خیلی بیشتر از نمونه‌ها باشد، انتخاب خوبی است.
**Polynomial (چندجمله‌ای)**
  • برای مرزهای تصمیم منحنی‌شکل.
  • پارامتر `degree` مهم است؛ درجه بالاتر یعنی پیچیدگی بیشتر.
  • ممکن است درجات بالا منجر به Overfitting شود.
**RBF/Gaussian (شعاعی/گوسی)**
  • برای مرزهای تصمیم پیچیده و غیرخطی.
  • بسیار پرکاربرد و قدرتمند.
  • پارامتر `gamma` کنترل می‌کند که یک نمونه آموزشی چقدر روی مدل تاثیر دارد.
  • اگر مطمئن نیستی کدام هسته را انتخاب کنی، RBF معمولا نقطه شروع خوبی است.
**Sigmoid (سیگموئید)**
  • مشابه شبکه عصبی، کمتر استفاده می‌شود.
  • عملکردش معمولاً از RBF ضعیف‌تر است.

مثال: SVM با RBF Kernel

بیا مدل قبلی رو با هسته RBF امتحان کنیم و ببینیم چقدر تغییر می‌کنه:
“`python
# تعریف مدل SVM با هسته RBF
# C و gamma پارامترهای مهم برای هسته RBF هستند
model_rbf = svm.SVC(kernel=’rbf’, C=10, gamma=0.1, random_state=42)

# آموزش مدل با داده‌های مقیاس‌بندی شده
print(“nدر حال آموزش مدل SVM با هسته RBF…”)
model_rbf.fit(X_train_scaled, y_train)
print(“مدل با هسته RBF با موفقیت آموزش داده شد.”)

# پیش‌بینی و ارزیابی
y_pred_rbf = model_rbf.predict(X_test_scaled)
print(“n— ارزیابی عملکرد مدل با هسته RBF —“)
print(“دقت مدل (Accuracy):”, accuracy_score(y_test, y_pred_rbf))
print(“nگزارش دسته‌بندی:n”, classification_report(y_test, y_pred_rbf))

plot_svc_decision_boundary(model_rbf, X_test_scaled, y_test, scaler, title=”مرز تصمیم SVM (هسته RBF)”)
“`
همونطور که می‌بینی، مرز تصمیم‌گیری می‌تونه خیلی پیچیده‌تر و انعطاف‌پذیرتر باشه، که این یعنی مدل می‌تونه الگوهای غیرخطی تو داده‌ها رو هم یاد بگیره.

پارامترهای مهم SVM: تنظیم دقیق برای بهترین عملکرد

مدل‌های SVM مثل یه رادیو هستن که برای گرفتن بهترین سیگنال، باید فرکانسشون رو دقیق تنظیم کنی. این فرکانس‌ها همون پارامترهای مدل هستن.

* **پارامتر C (Regularization Parameter):**
* این پارامتر میزان “خطای مجاز” مدل رو کنترل می‌کنه.
* **C کوچک:** مدل خطای بیشتری رو تحمل می‌کنه، مارجین وسیع‌تر میشه و مدل ساده‌تر (Underfitting) میشه. این به “Smoothness” مدل کمک می‌کنه.
* **C بزرگ:** مدل خطای کمتری رو تحمل می‌کنه، مارجین باریک‌تر میشه و ممکنه مدل بیش از حد رو داده‌های آموزشی فیت بشه (Overfitting).
* در واقع `C` یه تعادل بین رسیدن به یه مارجین بزرگ و دسته‌بندی صحیح نمونه‌های آموزشی برقرار می‌کنه.

* **پارامتر gamma (برای هسته‌های RBF، Poly، Sigmoid):**
* `gamma` تعیین می‌کنه که یه تک نمونه آموزشی چقدر روی مدل تاثیر می‌ذاره.
* **gamma کوچک:** تاثیر یک نمونه آموزشی روی نمونه‌های دورتر هم پخش میشه، مرز تصمیم نرم‌تر و کلی‌تر میشه.
* **gamma بزرگ:** تاثیر یک نمونه آموزشی فقط روی نمونه‌های نزدیک خودش محدود میشه، مرز تصمیم خیلی پیچیده و نویزپذیر میشه (Overfitting).
* `gamma` در واقع شعاع تاثیر بردارهای پشتیبان رو مشخص می‌کنه.

* **پارامتر degree (فقط برای هسته Polynomial):**
* این پارامتر درجه چندجمله‌ای هسته پولی‌نومیال رو مشخص می‌کنه.
* درجه بالاتر به معنی مرز تصمیم پیچیده‌تره و ریسک Overfitting رو افزایش می‌ده.

چگونه بهترین پارامترها را پیدا کنیم؟

همونطور که قبلاً گفتم، انتخاب بهترین پارامترها نیاز به آزمایش و خطا داره. scikit-learn ابزارهای خوبی برای این کار داره:
* **GridSearchCV:** یه روش جامع که همه ترکیبات ممکن از پارامترهایی که بهش می‌دی رو امتحان می‌کنه و بهترینشون رو پیدا می‌کنه.
* **RandomizedSearchCV:** اگه فضای پارامترهات خیلی بزرگه و GridSearchCV زمان‌بره، این روش به صورت تصادفی تعداد مشخصی از ترکیبات رو انتخاب و تست می‌کنه که سریع‌تره.

“`python
from sklearn.model_selection import GridSearchCV

# تعریف فضای پارامترها برای جستجو
param_grid = {
‘C’: [0.1, 1, 10, 100],
‘gamma’: [0.001, 0.01, 0.1, 1],
‘kernel’: [‘rbf’] # فعلا فقط RBF را بررسی می کنیم
}

# تعریف GridSearchCV
grid_search = GridSearchCV(svm.SVC(random_state=42), param_grid, cv=5, scoring=’accuracy’, verbose=1)

# اجرای جستجو روی داده‌های آموزش
print(“nدر حال جستجوی بهترین پارامترها با GridSearchCV…”)
grid_search.fit(X_train_scaled, y_train)
print(“جستجو به پایان رسید.”)

# بهترین پارامترها و بهترین امتیاز
print(“nبهترین پارامترها:”, grid_search.best_params_)
print(“بهترین امتیاز (Accuracy):”, grid_search.best_score_)

# مدل نهایی با بهترین پارامترها
best_model = grid_search.best_estimator_
y_pred_best = best_model.predict(X_test_scaled)

print(“n— ارزیابی مدل با بهترین پارامترها —“)
print(“دقت مدل (Accuracy):”, accuracy_score(y_test, y_pred_best))
print(“nگزارش دسته‌بندی:n”, classification_report(y_test, y_pred_best))

plot_svc_decision_boundary(best_model, X_test_scaled, y_test, scaler, title=”مرز تصمیم SVM (بهینه‌سازی شده با GridSearchCV)”)
“`
GridSearchCV ممکنه کمی زمان‌بر باشه، اما بهت کمک می‌کنه تا از بهترین تنظیمات برای مدل SVM‌ت استفاده کنی.

یک مثال کاربردی‌تر: دسته‌بندی گل زنبق (Iris Dataset)

حالا بیا دانش جدیدمون رو روی یه مجموعه داده مشهور و واقعی‌تر به اسم “Iris” پیاده کنیم. این دیتاست شامل ویژگی‌های سه گونه گل زنبق هست.

بارگذاری داده Iris

scikit-learn خودش مجموعه داده Iris رو داره و می‌تونیم مستقیماً ازش استفاده کنیم.
“`python
from sklearn.datasets import load_iris

# بارگذاری مجموعه داده Iris
iris = load_iris()
X_iris = iris.data
y_iris = iris.target

# نمایش ویژگی‌ها و هدف
print(“نام ویژگی‌ها:”, iris.feature_names)
print(“نام گونه‌ها:”, iris.target_names)
print(“ابعاد داده:”, X_iris.shape)
print(“نمونه‌هایی از ویژگی‌ها:n”, X_iris[:5])
print(“نمونه‌هایی از برچسب‌ها:n”, y_iris[:5])
“`

تقسیم و مقیاس‌بندی داده‌ها

مثل قبل، داده‌ها رو تقسیم و مقیاس‌بندی می‌کنیم.
“`python
# تقسیم داده به آموزش و تست
X_train_iris, X_test_iris, y_train_iris, y_test_iris = train_test_split(
X_iris, y_iris, test_size=0.3, random_state=42, stratify=y_iris # stratify برای حفظ نسبت کلاس‌ها
)

# مقیاس‌بندی ویژگی‌ها
scaler_iris = StandardScaler()
X_train_iris_scaled = scaler_iris.fit_transform(X_train_iris)
X_test_iris_scaled = scaler_iris.transform(X_test_iris)

print(“nابعاد داده‌های آموزش Iris پس از مقیاس‌بندی:”, X_train_iris_scaled.shape)
“`

آموزش و ارزیابی SVC با تنظیم پارامترها

بیا از بهترین پارامترهایی که با GridSearchCV پیدا کردیم (یا یه سری پارامتر مناسب برای RBF) استفاده کنیم.
“`python
# تعریف مدل SVM با هسته RBF و پارامترهای مناسب
# فرض می‌کنیم با GridSearchCV این پارامترها بهینه شده‌اند
model_iris = svm.SVC(kernel=’rbf’, C=10, gamma=0.1, random_state=42)

# آموزش مدل
print(“nدر حال آموزش مدل SVM روی داده Iris…”)
model_iris.fit(X_train_iris_scaled, y_train_iris)
print(“مدل با موفقیت آموزش داده شد.”)

# پیش‌بینی و ارزیابی
y_pred_iris = model_iris.predict(X_test_iris_scaled)

print(“n— ارزیابی عملکرد مدل SVM روی داده Iris —“)
print(“دقت مدل (Accuracy):”, accuracy_score(y_test_iris, y_pred_iris))
print(“nگزارش دسته‌بندی:n”, classification_report(y_test_iris, y_pred_iris, target_names=iris.target_names))

# حالا با GridSearch برای Iris بهترین پارامتر رو پیدا کنیم
param_grid_iris = {
‘C’: [0.1, 1, 10, 100],
‘gamma’: [0.001, 0.01, 0.1, 1, ‘scale’], # ‘scale’ = 1 / (n_features * X.var())
‘kernel’: [‘rbf’]
}

grid_search_iris = GridSearchCV(svm.SVC(random_state=42), param_grid_iris, cv=5, scoring=’accuracy’, verbose=1)
print(“nدر حال جستجوی بهترین پارامترها برای Iris با GridSearchCV…”)
grid_search_iris.fit(X_train_iris_scaled, y_train_iris)
print(“جستجو به پایان رسید.”)

print(“nبهترین پارامترها برای Iris:”, grid_search_iris.best_params_)
print(“بهترین امتیاز (Accuracy) برای Iris:”, grid_search_iris.best_score_)

best_model_iris = grid_search_iris.best_estimator_
y_pred_best_iris = best_model_iris.predict(X_test_iris_scaled)

print(“n— ارزیابی مدل نهایی Iris با بهترین پارامترها —“)
print(“دقت مدل (Accuracy):”, accuracy_score(y_test_iris, y_pred_best_iris))
print(“nگزارش دسته‌بندی:n”, classification_report(y_test_iris, y_pred_best_iris, target_names=iris.target_names))
“`
دیدید چقدر راحت تونستیم یه مدل قوی برای دسته‌بندی گل زنبق بسازیم؟ اینقدر **دقییق** عمل میکنه که باورت نمیشه! با کمی تنظیم پارامترها و انتخاب هسته مناسب، می‌تونیم به دقت‌های خیلی بالایی برسیم.

عیب‌یابی سریع (Troubleshooting): وقتی کارها اونطوری که می‌خوایم پیش نمیره!

بعضی وقتا ممکنه مدل SVM‌ت اونطوری که انتظار داری عمل نکنه. نگران نباش، این طبیعیه! بیا چند تا مشکل رایج و راه حلشون رو مرور کنیم:

* **مشکل: مدل عملکرد خوبی نداره (Underfitting/Overfitting)**
* **نشانه:** دقت مدل روی داده‌های آموزش و تست هر دو پایینه (Underfitting) یا روی داده‌های آموزش خیلی بالاست ولی روی تست پایینه (Overfitting).
* **راه‌حل:**
* **برای Underfitting:**
* **پارامتر C رو افزایش بده:** اجازه می‌ده مدل خطای کمتری تحمل کنه و بیشتر روی داده‌های آموزشی فیت بشه.
* **gamma رو افزایش بده (برای هسته‌های RBF/Poly):** مرز تصمیم پیچیده‌تر میشه.
* **هسته پیچیده‌تری انتخاب کن:** مثلاً از Linear به RBF برو.
* **مهندسی ویژگی (Feature Engineering):** شاید ویژگی‌های موجود کافی نیستن و باید ویژگی‌های جدیدی بسازی.
* **برای Overfitting:**
* **پارامتر C رو کاهش بده:** اجازه می‌ده مدل خطای بیشتری رو تحمل کنه و مارجین وسیع‌تری داشته باشه (ساده‌تر بشه).
* **gamma رو کاهش بده (برای هسته‌های RBF/Poly):** مرز تصمیم نرم‌تر و کلی‌تر میشه.
* **داده‌های آموزشی بیشتری جمع کن.**
* **ویژگی‌های نامربوط رو حذف کن.**

* **مشکل: زمان آموزش خیلی زیاده**
* **نشانه:** `model.fit()` خیلی طول می‌کشه.
* **راه‌حل:**
* **از SVC با هسته Linear یا LinearSVC استفاده کن:** `LinearSVC` بهینه‌تر از `SVC(kernel=’linear’)` برای هسته خطیه.
* **نمونه‌های داده رو کاهش بده:** اگه مجموعه داده‌ات خیلی بزرگه، می‌تونی یه نمونه (Sample) ازش برداری.
* **از پارامتر `cache_size` برای `SVC` استفاده کن:** این پارامتر حافظه کش برای هسته‌ها رو تعیین می‌کنه که می‌تونه سرعت رو بالا ببره.
* **از `SGDClassifier` با `loss=’hinge’` استفاده کن:** این هم یه رویکرد SVM-like هست که برای داده‌های بزرگ خیلی سریع‌تره.
* **از `n_jobs=-1` در GridSearchCV استفاده کن:** برای استفاده از تمام هسته‌های CPU.

* **مشکل: داده‌ها خیلی نویز دارن**
* **نشانه:** مدل خیلی به داده‌های پرت (Outliers) حساسه و مرز تصمیم‌گیریش ناپایدار میشه.
* **راه‌حل:**
* **پارامتر C رو کاهش بده:** به مدل اجازه می‌ده بیشتر “نرم” باشه و نویزها رو نادیده بگیره.
* **Outlier Detection/Removal:** قبل از آموزش، نقاط پرت رو شناسایی و حذف کن.
* **از هسته‌های مقاوم‌تر استفاده کن:** اگرچه RBF معمولاً خوب عمل می‌کنه، گاهی Linear Kernel در حضور نویز بهتره.

* **مشکل: مشکل در انتخاب هسته یا پارامترها**
* **نشانه:** نمی‌دونی کدوم هسته یا پارامترها بهترین نتیجه رو میدن.
* **راه‌حل:**
* **با RBF شروع کن:** معمولاً یه نقطه شروع خوبه.
* **از GridSearchCV یا RandomizedSearchCV استفاده کن:** برای جستجوی سیستماتیک بهترین پارامترها.
* **با C=1 و gamma=’scale’ شروع کن:** این‌ها مقادیر پیش‌فرض منطقی برای بسیاری از موارد هستند.

سوالات متداول (FAQ)

* **تفاوت بین SVC و SVR چیه؟**
* **SVC (Support Vector Classifier):** برای وظایف دسته‌بندی (Classification) استفاده می‌شه، یعنی پیش‌بینی یک برچسب گسسته (مثلاً 0 یا 1، یا A، B، C).
* **SVR (Support Vector Regressor):** برای وظایف رگرسیون (Regression) استفاده می‌شه، یعنی پیش‌بینی یک مقدار پیوسته (مثلاً قیمت خانه، دما).

* **چه زمانی باید از SVM استفاده کنم؟**
* وقتی مجموعه داده‌ات متوسط یا کوچیکه (مثلاً زیر 100,000 نمونه).
* وقتی تعداد ویژگی‌ها (ابعاد) زیاد باشه.
* وقتی انتظار دقت بالایی داری.
* وقتی داده‌هات به صورت خطی جداشدنی نیستند و نیاز به Kernel Trick داری.

* **چطور با مجموعه داده‌های نامتوازن (Imbalanced Datasets) در SVM کار کنم؟**
* **تنظیم پارامتر `class_weight` در `SVC`:** این پارامتر رو روی `’balanced’` تنظیم کن تا وزن بیشتری به کلاس اقلیت داده بشه.
* **نمونه‌برداری مجدد (Resampling):** می‌تونی از روش‌هایی مثل Oversampling (مثل SMOTE) برای کلاس اقلیت یا Undersampling برای کلاس اکثریت استفاده کنی.

* **آیا SVM برای مجموعه داده‌های خیلی بزرگ مناسبه؟**
* نه همیشه. برای داده‌های خیلی بزرگ (میلیون‌ها نمونه)، SVM کلاسیک می‌تونه خیلی کند باشه. در این موارد، الگوریتم‌های مبتنی بر نزول گرادیان (مثل `SGDClassifier` با `loss=’hinge’`) یا مدل‌های درختی (مثل Random Forest یا XGBoost) معمولاً گزینه‌های بهتری هستن.

حرف آخر رفیق!

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

پس دست به کار شو، این کدها رو اجرا کن، با پارامترها بازی کن و نتایج رو ببین. یادت باشه، بهترین راه برای یادگیری، تمرینه. اگه دنبال [کدهای آماده و اسنیپت‌های](https://fa-tools.ir/snippets/) بیشتری هستی، حتماً یه سر به سایتمون بزن. مطمئنم که کلی چیز به دردت می‌خوره. موفق باشی!

Table of Contents

آخرین نوشته‌ها