Machine Learning: آلات المتجهات الداعمة
آخر تحديث: 2026-08-26
تجد SVM "أوسع طريق" — تدفع حدود القرار لأبعد ما يمكن من كلتا الفئتين، مما يجعلها أكثر قوة بشكل طبيعي.
1. ما ستتعلمه
- المصنف بأقصى هامش: متجهات الدعم، حدود الهامش، الهامش الصلب مقابل الهامش المرن (معامل C)
- حيلة النواة: بديهة واستراتيجيات اختيار لنوى linear/RBF/polynomial
- انحدار SVM (SVR): دالة الخسارة غير الحساسة ε
- لماذا يهم التوحيد القياسي: حساسية SVM لمقاييس الميزات
- تجزئة عملاء Charlie: تصنيف عملاء السوق الأوروبي إلى فئات قيمة باستخدام SVM
2. قصة حقيقية من محلل سوق
(1) نقطة الألم: حدود ضبابية في فئات قيمة العملاء
Charlie مسؤول عن تجزئة العملاء في السوق الأوروبي، ويقسم العملاء إلى فئات قيمة عالية/متوسطة/منخفضة لتخصيص موارد الخدمة. لكن حدود الفئتين العالية والمتوسطة صعبة الرسم — استخدام مقياس واحد (مثل مبلغ الإنفاق) للتصنيف يتسبب في تصنيف خاطئ لـ 20% من العملاء القريبين من الحدود. لا يمكن للحد الخطي التقاط العلاقات المعقدة عبر أبعاد متعددة للعميل.
(2) حل حيلة النواة في SVM
تستخدم SVM حيلة النواة لرسم خرائط للبيانات إلى فضاء ذي أبعاد أعلى، لتجد حدودًا واضحة حيث كانت البيانات غير قابلة للفصل سابقًا.
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# نواة RBF ترسم خريطة للفضاء عالي الأبعاد
pipe = Pipeline([
("scaler", StandardScaler()),
("svm", SVC(kernel="rbf", C=1.0, gamma="scale")),
])
pipe.fit(X_train, y_train)
print(f"Accuracy: {pipe.score(X_test, y_test):.4f}")
(3) النتيجة: تحسنت دقة عملاء الحدود من 65% إلى 89%
بعد استبدال التصنيف الخطي بـ SVM-RBF، قفزت دقة التصنيف لعملاء الحدود لدى Charlie من 65% إلى 89%، مما قلل سوء تخصيص موارد الخدمة بنسبة 40%.
3. المصنف بأقصى هامش
(1) الفكرة الأساسية لـ SVM
تجد SVM المستوى الفائق الفاصل الذي يعظم الهامش. فقط العينات الواقعة على حدود الهامش (متجهات الدعم) تحدد نتيجة التصنيف.
graph TB
INPUT[بيانات الإدخال] --> MAP[رسم خريطة النواة<br/>أبعاد منخفضة → عالية]
MAP --> HYPER[البحث عن المستوى الفائق<br/>بأقصى هامش]
HYPER --> SV[متجهات الدعم<br/>تحدد الحدود]
SV --> MARGIN[عرض الهامش<br/>أكبر = أكثر قوة]
MARGIN --> CLASSIFY[التصنيف<br/>دالة القرار]
▶ مثال: تصور SVM الخطي
from sklearn.svm import SVC
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np
X, y = make_blobs(n_samples=100, centers=2, random_state=42, cluster_std=1.5)
# تدريب SVM بنواة خطية
svm = SVC(kernel="linear", C=1.0)
svm.fit(X, y)
fig, ax = plt.subplots(figsize=(8, 6))
# رسم نقاط البيانات
ax.scatter(X[:, 0], X[:, 1], c=y, cmap="bwr", s=30, edgecolors="black")
# رسم حدود القرار والهوامش
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
Z = svm.decision_function(xy).reshape(XX.shape)
ax.contour(XX, YY, Z, colors="k", levels=[-1, 0, 1], alpha=0.5, linestyles=["--", "-", "--"])
# إبراز متجهات الدعم
ax.scatter(svm.support_vectors_[:, 0], svm.support_vectors_[:, 1],
s=100, facecolors="none", edgecolors="k", linewidths=2)
ax.set_title(f"Linear SVM (C={svm.C})\nSupport vectors: {len(svm.support_vectors_)}")
plt.tight_layout()
plt.savefig("svm_linear.png", dpi=150)
Output:
# Executed successfully
(2) الهامش الصلب مقابل الهامش المرن (معامل C)
| قيمة C | الهامش | تحمل سوء التصنيف | مخاطرة فرط التجهيز | حالة الاستخدام |
|---|---|---|---|---|
| كبيرة (100+) | ضيق | شبه معدوم | عالية | بيانات قابلة للفصل الخطي تقريبًا |
| متوسطة (1) | معتدل | بعض التحمل | منخفضة | الحالات العامة |
| صغيرة (0.01) | عريض | تحمل عالٍ | منخفضة | بيانات ضوضائية/متداخلة |
▶ مثال: مقارنة تأثير معامل C
from sklearn.svm import SVC
from sklearn.datasets import make_blobs
from sklearn.model_selection import cross_val_score
import numpy as np
X, y = make_blobs(n_samples=200, centers=2, random_state=42, cluster_std=2.5)
for C in [0.01, 0.1, 1.0, 10.0, 100.0]:
svm = SVC(kernel="rbf", C=C, gamma="scale")
scores = cross_val_score(svm, X, y, cv=5, scoring="accuracy")
svm.fit(X, y)
print(f"C={C:6.2f}: Accuracy={scores.mean():.3f} +/- {scores.std():.3f}, "
f"Support vectors={len(svm.support_vectors_)}")
Output:
# Executed successfully
4. حيلة النواة
(1) اختيار دالة النواة
▶ مثال: مقارنة دوال النواة المختلفة
from sklearn.svm import SVC
from sklearn.datasets import make_moons, make_circles
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import numpy as np
# بيانات غير خطية (أهلة)
X_moons, y_moons = make_moons(n_samples=500, noise=0.2, random_state=42)
kernels = {
"Linear": SVC(kernel="linear", C=1),
"Polynomial (deg=3)": SVC(kernel="poly", degree=3, C=1),
"RBF": SVC(kernel="rbf", C=1, gamma="scale"),
}
for name, svm in kernels.items():
pipe = Pipeline([("scaler", StandardScaler()), ("svm", svm)])
scores = cross_val_score(pipe, X_moons, y_moons, cv=5, scoring="accuracy")
print(f"{name:20s}: Accuracy={scores.mean():.3f}")
Output:
# Executed successfully
| النواة | الصيغة | حالة الاستخدام | المعاملات الرئيسية |
|---|---|---|---|
| خطية | $\langle x, x' \rangle$ | عالية الأبعاد، قابلة للفصل الخطي | C |
| RBF | $e^{-\gamma|x-x'|^2}$ | للأغراض العامة، غير خطية | C, gamma |
| متعددة الحدود | $(\langle x, x' \rangle + c)^d$ | تفاعلات الميزات | C, degree, coef0 |
| Sigmoid | $\tanh(\gamma\langle x, x' \rangle + c)$ | شبيهة بالشبكة العصبية | C, gamma, coef0 |
(2) معامل Gamma
▶ مثال: تأثير Gamma على نواة RBF
from sklearn.svm import SVC
from sklearn.datasets import make_moons
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
X, y = make_moons(n_samples=500, noise=0.15, random_state=42)
for gamma in [0.01, 0.1, 1.0, 10.0, "scale", "auto"]:
pipe = Pipeline([
("scaler", StandardScaler()),
("svm", SVC(kernel="rbf", C=1, gamma=gamma)),
])
scores = cross_val_score(pipe, X, y, cv=5, scoring="accuracy")
print(f"gamma={str(gamma):6s}: Accuracy={scores.mean():.3f}")
Output:
# Executed successfully
| Gamma | حدود القرار | التأثير |
|---|---|---|
| صغير جدًا (0.01) | ناعم | فرط التجهيز المنخفض |
| معتدل (1) | منحني بشكل معتدل | عادةً الأمثل |
| كبير جدًا (10+) | غير منتظم للغاية | فرط التجهيز |
| "scale" | 1/(n_features * X.var()) | افتراضي sklearn |
| "auto" | 1/n_features | افتراضي قديم |
5. لماذا يهم التوحيد و SVR
(1) حساسية SVM لمقاييس الميزات
▶ مثال: تأثير التوحيد على SVM
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
# بدون توحيد
svm_raw = SVC(kernel="rbf", C=1, gamma="scale")
scores_raw = cross_val_score(svm_raw, X, y, cv=5, scoring="accuracy")
# مع توحيد
pipe = Pipeline([("scaler", StandardScaler()), ("svm", SVC(kernel="rbf", C=1, gamma="scale"))])
scores_scaled = cross_val_score(pipe, X, y, cv=5, scoring="accuracy")
print(f"Without scaling: {scores_raw.mean():.4f}")
print(f"With scaling: {scores_scaled.mean():.4f}")
Output:
# Executed successfully
(2) انحدار SVR
▶ مثال: التنبؤ بالمبيعات بـ SVR
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, r2_score
import numpy as np
rng = np.random.default_rng(42)
X = rng.uniform(0, 100, (200, 3))
y = 50 + 0.8 * X[:, 0] + rng.normal(0, 5, 200)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# SVR بنواة RBF
pipe = Pipeline([
("scaler", StandardScaler()),
("svr", SVR(kernel="rbf", C=100, epsilon=5)),
])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
print(f"SVR R²: {r2_score(y_test, y_pred):.4f}")
print(f"SVR MAE: {mean_absolute_error(y_test, y_pred):.2f}")
Output:
# Executed successfully
| المعامل | المعنى | التأثير |
|---|---|---|
| C | قوة التنظيم | C كبير → تحمل أقل للخطأ → فرط التجهيز محتمل |
| epsilon (ε) | عرض النطاق غير الحساس | ε كبير → تجاهل المزيد من النقاط → ملاءمة أكثر نعومة |
| kernel | نوع دالة النواة | نفس تصنيف SVM |
6. تجزئة قيمة عملاء Charlie الأوروبية
▶ مثال: مشروع تصنيف SVM كامل
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import classification_report
import pandas as pd
import numpy as np
rng = np.random.default_rng(42)
n = 2000
df = pd.DataFrame({
"annual_spending_eur": rng.exponential(5000, n),
"purchase_frequency": rng.poisson(8, n),
"avg_order_value_eur": rng.exponential(150, n),
"tenure_months": rng.integers(1, 60, n),
"support_tickets": rng.poisson(3, n),
})
# منطق فئة القيمة (بالـ EUR)
score = (df["annual_spending_eur"] / 5000 * 0.3
+ df["purchase_frequency"] / 20 * 0.25
+ df["avg_order_value_eur"] / 200 * 0.2
+ df["tenure_months"] / 60 * 0.15
+ rng.normal(0, 0.1, n))
df["tier"] = pd.cut(score, bins=[0, 0.3, 0.6, 1.5], labels=["Low", "Medium", "High"])
X = df.drop(columns=["tier"])
y = df["tier"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# بحث شبكي عن أفضل معاملات SVM
pipe = Pipeline([("scaler", StandardScaler()), ("svm", SVC())])
param_grid = {
"svm__kernel": ["linear", "rbf"],
"svm__C": [0.1, 1, 10],
"svm__gamma": ["scale", 0.1, 1],
}
grid = GridSearchCV(pipe, param_grid, cv=3, scoring="accuracy", n_jobs=-1)
grid.fit(X_train, y_train)
print(f"Best params: {grid.best_params_}")
print(f"Best CV accuracy: {grid.best_score_:.4f}")
print(f"\nTest report:\n{classification_report(y_test, grid.predict(X_test))}")
Output:
# Executed successfully
❓ أسئلة شائعة
📖 ملخص
- تجد SVM المستوى الفائق بأقصى هامش؛ فقط متجهات الدعم تحدد الحدود — جميع العينات الأخرى ليس لها تأثير
- يتحكم معامل C في المقايضة بين عرض الهامش وسوء التصنيف: C كبير → هامش ضيق، سوء تصنيف أقل؛ C صغير → هامش عريض، تحمل أكثر
- تحل حيلة النواة التصنيف غير الخطي عبر رسم خرائط للبيانات إلى فضاء ذي أبعاد أعلى؛ نواة RBF هي الخيار الأول الافتراضي
- يتحكم Gamma في نطاق تأثير نواة RBF: gamma صغير → حدود ناعمة، gamma كبير → فرط التجهيز
- يتطلب SVM توحيد الميزات — مقاييس المسافة حساسة للغاية لمقاييس الميزات
- يستخدم SVR الخسارة غير الحساسة ε للانحدار؛ أخطاء التنبؤ الأصغر من ε لا تُعاقب
📝 تمارين
- أساسي (الصعوبة ⭐): استخدم SVC(kernel="rbf") لتصنيف مجموعة بيانات make_moons. قارن الدقة مع وبدون StandardScaler. تلميح: Pipeline مقابل fit المباشر.
- متوسط (الصعوبة ⭐⭐): استخدم GridSearchCV للبحث عن معاملات SVM المثلى (kernel, C, gamma) على مجموعة بيانات Iris وإيجاد أفضل توليفة. تلميح: SVC داخل Pipeline + param_grid.
- تحدي (الصعوبة ⭐⭐⭐): أعد إنتاج تجزئة عملاء Charlie — ولّد بيانات عملاء من 3 فئات، وقارن تقارير التصنيف لـ SVM/LogisticRegression/RandomForest، وحلل النموذج الأفضل لسيناريوهات متعددة الفئات ذات حدود ضبابية. تلميح: استخدم classification_report لمقارنة precision/recall/f1.
← الدرس السابق: أشجار القرار والغابات العشوائية | الدرس التالي: KNN والتجميع →