Kodax

Support Vector Machines — تعلم الآلة

آلات المتجهات الداعمة (SVM)

من بين كل الخطوط التي تفصل فئتين، أيها الأفضل؟ SVM يختار الخط الذي يترك أوسع شارع بين الفئتين.

الهامش الأقصى

   ○  ○        |   ●  ●
 ○   ○     ·   |   ·    ●  ●
   ○       ·   |   ·  ●
           ←هامش→

- الهامش (margin): المسافة بين الخط وأقرب النقاط من الفئتين.

- المتجهات الداعمة (support vectors): هذه النقاط الأقرب. هي وحدها التي تحدد الخط؛ حذف أي نقطة أخرى لا يغيّر شيئاً.

- الهامش الأوسع = تعميم أفضل على البيانات الجديدة.

البيانات ليست مثالية: المعامل C

في الواقع تتداخل الفئات. SVM يسمح ببعض الأخطاء، و C يتحكم في التوازن:

| C | السلوك |

|---|---|

| صغير | هامش واسع ويتسامح مع الأخطاء ← تعميم أفضل، قد يصل لـ Underfitting |

| كبير | يحاول تصنيف كل نقطة تدريب صحيحاً ← هامش ضيق، خطر Overfitting |

Kernel Trick: حدود منحنية

ماذا لو كانت فئة في دائرة داخل الأخرى؟ لا خط مستقيم يفصلهما. الحيلة: تحويل البيانات إلى بعد أعلى حيث يصبح الفصل خطياً — دون حساب التحويل فعلياً.

| النواة | الشكل |

|---|---|

| linear | خط/مستوى — سريع، جيد للبيانات النصية عالية الأبعاد |

| rbf (الافتراضي) | حدود مرنة منحنية — معامل gamma يحدد مدى تأثير كل نقطة |

| poly | حدود متعددة الحدود |

from sklearn.datasets import make_circles
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC

X, y = make_circles(n_samples=300, noise=0.1, factor=0.4, random_state=0)
for kernel in ["linear", "rbf"]:
    print(kernel, round(cross_val_score(SVC(kernel=kernel), X, y, cv=5).mean(), 2))

النواة الخطية تفشل (قرابة 50%) والـ rbf تنجح — لأن الحد الحقيقي دائرة.

ملاحظات عملية

- التقييس ضروري (مسافات وهوامش).

- اضبط C و gamma معاً بـ GridSearchCV على مقياس لوغاريتمي (0.01، 0.1، 1، 10، 100).

- بطيء مع مئات الآلاف من العينات؛ هناك LinearSVC الأسرع للحالة الخطية.

- لا يعطي احتمالات افتراضياً؛ probability=True يضيفها بكلفة تدريب إضافية.

تمرين

في المثال الكامل استبدل حلقتي kernel و C بـ GridSearchCV على C و gamma، واطبع أفضل معاملات ودقتها.

from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
import numpy as np

# إنشاء بيانات
X, y = make_classification(n_samples=100, n_features=2, 
                           n_redundant=0, n_clusters_per_class=1, random_state=42)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Scaling
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# تجربة Kernels مختلفة
kernels = ['linear', 'rbf', 'poly']
for kernel in kernels:
    model = SVC(kernel=kernel)
    model.fit(X_train, y_train)
    acc = model.score(X_test, y_test)
    print(f"{kernel}: {acc:.2%}")

# RBF مع C مختلفة
for c in [0.1, 1, 10]:
    model = SVC(kernel='rbf', C=c)
    model.fit(X_train, y_train)
    acc = model.score(X_test, y_test)
    print(f"C={c}: {acc:.2%}")

# النموذج النهائي
final_model = SVC(kernel='rbf', C=1, probability=True)
final_model.fit(X_train, y_train)

# التنبؤ مع الاحتمالية
proba = final_model.predict_proba(X_test[:1])
print(f"احتمالية الفئات: {proba}")
اختبر فهمك