فهم خوارزمية انحدار المتجة الداعم (SVٌR) من خلال أمثلة (مع الكود بايثون)

قبل الشبكات العصبية Neural Networks، كانت ألات المتجهات الداعمة SVMs شائعة جدًا في عمليات التصنيف. انحدار المتجة الداعم (Support Vector Regression (SVR هو ما يعادل الانحدار. في هذه المقالة ، سنتناول SVR بشيء من التفصيل.

كيف يعمل SVR؟

يحافظ SVR على جميع الخصائص المثيرة للاهتمام من ألة المتجهات الداعمة SVM. بحيث يستخدم انحدار نفس المبادئ التي يستخدمها SVM للتصنيف، مع بعض الاختلافات الطفيفة فقط. استنادا إلى البيانات المدرجة، فإن هذه الطريقة تحاول إيجاد منحنى. ومع ذلك ، فبدلاً من أن يكون المنحنى بمثابة حدود للقرار في مسألة التصنيف، في SVR ، يتم ايجاد تطابق بين بعض المتجهات والموضع على المنحنى. ومع ذلك ، فإن الفكرة الرئيسية هي نفسها دائمًا: تقليل نسبة الخطأ في النتائج، وتخصيص المستوى الفائق Hyperplane الذي يزيد من قيمة الهامش إلى أقصى حد ، مع مراعاة أن جزءًا من الخطأ مسموح به.

وتشارك المتجهات الدعمة Support Vectors في إيجاد أقرب تطابق بين نقاط البيانات والوظيفة الفعلية التي تمثلها. بشكل تلقائي، عندما نزيد المسافة بين المتجهات الداعمة إلى المنحنى المتراجع ، فإننا نقترب من المنحنى الفعلي (نظرًا لوجود بعض الاخطاء دائمًا في العينات الإحصائية). ويترتب على ذلك أيضًا أنه يمكننا التخلص من جميع المتجهات التي ليست متجهات داعمة، لسبب بسيط هو أنها من المحتمل أن تكون قيم إحصائية شاذة statistical outliers.

ال Kernal و SVR
يمكنناتطبيق طريقة Kernels في SVR أيضا. وبالتالي، من الممكن ان معالجة انحدار أي دالة غير خطية، أو منحنى  باستخدام SVR. و بالمثل، يتم تعيين البيانات غير الخطية على مساحة تجعل البيانات خطية. في حالة SVR، لا يلزم أن تكون خطية من أجل فصل مجموعتين ، بل لتمثيل خط مستقيم وبالتالي حساب مساهمة متجهات الدعم في مشكلة الانحدار.

أنواع ال SVR

مع SVM ، رأينا أن هناك نوعين : C-SVM و nu-SVM. في هذه الحالة ، يكمن الاختلاف في دالة الفقد Loss function التي يجب تحسينها، خاصة في المعامل الفائق Hyperparameter الذي يقوم بتحديد الفقد المطلوب حسابه.

يحدث الشيء نفسه في SVR: لأنه يأتي مع انحدار epsilon-SVM و nu-SVM ، أو epsilon-SVR و nu-SVR. يكمن الاختلاف في ما ترغب في التحكم به أثناء عملية التدريب.

في حالة epsilon-SVR ، أو ep-SVR ، فإنك ترغب في التحكم في الحد الأقصى المسموح به من الخطأ لإعداد الانحدار. هذا أمر رائع إذا كنت ترغب في العثور على أفضل نموذج ممكن دون الاهتمام كثيرًا بالموارد الحسابية. ونتيجة لذلك ، لا تتحكم في عدد متجهات الدعم المستخدمة أثناء التحسين: يمكن أن تكون قليلة ، وقد تكون كثيرة. ومع الكثير ، قد تحتاج إلى موارد كثيرة.

من ناحية أخرى ، باستخدام nu-SVR ، ستتحكم في عدد متجهات الدعم بدلاً من ذلك. نتيجة لذلك ، لا يمكنك التحكم في الحد الأقصى لمقدار الخطأ المسموح به في النموذج – فهو مقدر لك. نتيجة لذلك ، من المحتمل أنك تحتاج إلى موارد أقل أو أبسط من ep-SVR ، ولكن من المرجح أن تجد خطأ أكبر قليلاً.

بناءً على احتياجاتك ، يجب عليك اختيار نوع SVR الذي يناسب مشكلة التعلم الآلي التي تحاول إيجاد حل لها.

 

SVR خطي (Linear SVR)

SVR غير خطي (Non-linear SVR)
تقوم دوال ال kernel بتحويل البيانات إلى مساحة ميزات ذات أبعاد أعلى لجعل من الممكن إجراء الفصل الخطي.

دوال ال Kernel 

مثال عملي في لغة البرمجة بايثون

في معظم نماذج الانحدار الخطي البسيط ، يكون الهدف الرئيسي هو تقليل نسبة الخطاء. اذا أخذنا المربعات الصغرى الخطية ordinary least squares (ols) regression على سبيل المثال. إن دالة الهدف لـ OLS مع ميزة واحدة (Predictor (feature يمكن وصفها كالتالي:

OLS Equation

حيث yᵢ هو الهدف ، و w هو المعامل (الوزن) ، و xᵢ هو المتنبئ (الميزة).

يمنحنا SVR المرونة لتحديد مقدار الخطأ المقبول في النموذج الذي نعمل عليه وسيجد خطًا مناسبًا (أو سطحًا فائقًا بأبعاد أعلى) لملاءمة البيانات.

على عكس OLS ، فإن الهدف الرئيسي من SVR هو تقليل المعاملات – وبشكل أكثر تحديدًا ، معيار-L2 (L2-norm) لمتجه المعامل )يحسب المعيار L2 مسافة إحداثيات المتجه من أصل مساحة المتجه. على هذا النحو ، يُعرف أيضًا باسم المعيار الإقليدي حيث يتم حسابه على أنه المسافة الإقليدية من الأصل. تكون النتيجة قيمة مسافة موجبة (- وليس للخطأ التربيعي. بدلاً من ذلك ، يتم التعامل مع الخطأ بصرامة و بقيود، حيث نقوم بتعيين الخطأ المطلق أقل من أو يساوي هامش محدد ، يسمى الحد الأقصى للخطأ، .ϵ (epsilon)  يمكننا ضبط إبسيلون للحصول على الدقة المطلوبة لنموذجنا. الدالة و القيود الموضوعية الجديدة هي كما يلي:

التخفيض Minimize

الحدود Constraints

رسم توضيحي لل SVR البسيط

دعنا نجرب طريقة SVR البسيط في مجموعة بياناتنا. يوضح المخطط أدناه نتائج نموذج SVR مدرب على بيانات أسعار الإسكان في مدينة بوسطن. الخط الأحمر يمثل الخط الأكثر ملاءمة والخطوط السوداء تمثل هامش الخطأ ، ϵ ، الذي قمنا بتعيينه إلى 5 (5000 دولار).

توقع SVR لأسعار المساكن في بوسطن مع قيمة ϵ تساوي 5

قد تدرك بسرعة أن هذه الخوارزمية لا تعمل مع جميع نقاط البيانات. حلت الخوارزمية دالة الهدف بأفضل طريقة ممكنة ولكن بعض النقاط لا تزال تقع خارج الهوامش. على هذا النحو ، نحتاج إلى حساب احتمال أخطاء أكبر من ϵ. يمكننا القيام بذلك مع متغيرات الركود

إعطاء أنفسنا بعض الركود Slack (و مستويات فائقة أخرى)

مفهوم متغيرات الركود Slack بسيط: بالنسبة لأي قيمة تقع خارج ϵ ، يمكننا أن نشير إلى انحرافها عن الهامش كـ ξ.

نحن نعلم أن هذه الانحرافات وجودها معقول ، ولكننا ما زلنا نرغب في تقليلها قدر الإمكان. وبالتالي ، يمكننا إضافة هذه الانحرافات إلى الوظيفة الموضوعية.

التخفيض Minimize

SVR Equation

الحدود Constraints

مثال توضيحي لـ SVR مع متغيرات الركود Slack

لدينا الآن مستوى فائق إضافي C ، يمكننا ضبطه. وكلما زاد C ، زادت احتمالية وجود النقاط خارج ϵ أيضًا. مع اقتراب C من 0 ، يقترب الاحتمال من 0 وتنهار المعادلة إلى المعادلة المبسطة (على الرغم من أنها غير ممكنة في بعض الأحيان).

دعونا نضع C = 1.0 ونعيد تدريب نموذجنا أعلاه. تم رسم النتائج أدناه:

توقع SVR لأسعار المساكن في بوسطن مع ϵ = 5 ، C = 1.0

إيجاد أفضل قيمة لـ C

يبدو أن النموذج أعلاه قلل نسبة الخطأ نسبيا و أعطى نتائج أفضل من سابقه. يمكننا أن نخطو خطوة أخرى ونبحث على قيمة اخرى ل C للحصول على حل أفضل. لنفترض أن مقياس التقييم سيكون  Within Epsilon%.

يقيس هذا التقييم عدد النقاط الإجمالية ضمن مجموعة الاختبار التي تقع ضمن هامش الخطأ. يمكننا أيضًا مراقبة كيفية اختلاف متوسط الخطأ المطلق (MAE) مع C أيضًا.

يوجد أدناه مخطط لنتائج بحث الشبكة ، مع قيم C على المحور س و within Epsilon% ومتوسط الخطأ المطلق  MAE على المحورين y الأيمن والأيسر ، على التوالي.

Hyperparameter Tuning of SVR

ايجاد قيمة C

 كما نرى ، تقل نسبة الخطأ MAE بشكل عام مع زيادة قيمة C . ومع ذلك ، نرى الحد الأقصى يحدث في تقييم within Epsilon% . و نظرًا لأن هدفنا الأصلي من هذا النموذج كان زيادة التنبؤ ضمن هامش الخطأ الذي حددناه (5000 دولار أمريكي) ، فإننا نريد ايجاد قيمة C التي تكون عندها قيمة within Epsilon% قصوى. وبالتالي قيمة C  في هذه الحالة تساوي 6.13.

دعونا نبني نموذجًا أخيرًا باستخدام العوامل الفائقة النهائية ، ϵ = 5 ، C = 6.13.

يظهر الرسم البياني أعلاه أن هذا النموذج قد تحسن كثيرا مقارنة بالنماذج السابقة ، كما هو متوقع.

توقع SVR لأسعار المساكن في بوسطن مع ϵ = 5 ، C = 6.13

الكود المستخدم في لغة البرمجة بايثون

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv("data/Boston Housing Prices.csv")
df.describe()
len(df)
df.corr()
abs(df.corr())['cmedv'].sort_values(ascending=False)
plt.figure(figsize=(15,10))
plt.scatter(x=df['rooms'], y=df['cmedv'])
plt.xlabel('# of Rooms')
plt.ylabel('House Price (Thousands of Dollars)')
plt.title('Boston Housing Prices')
plt.show()

Linear Regression الانحدار الخطي

from sklearn.model_selection import train_test_split
X = np.array(df['rooms']).reshape(-1,1) 
y = np.array(df['cmedv']).reshape(-1,1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=12)
y_train = y_train.reshape(len(y_train),)
y_test = y_test.reshape(len(y_test),)
from sklearn.linear_model import LinearRegression
lm = LinearRegression()
lm.fit(X_train, y_train)
from sklearn.metrics import mean_absolute_error 
print("Intercept: {:,.3f}".format(lm.intercept_))
print("Coefficient: {:,.3f}".format(lm.coef_[0])) 
mae = mean_absolute_error(y_test, lm.predict(X_test))
print("MAE = ${:,.2f}".format(1000*mae))
# Plot outputs
plt.figure(figsize=(10,7))
plt.scatter(x=df['rooms'], y=df['cmedv'])
plt.plot(X_test, lm.predict(X_test), color='red')
plt.xlabel('# of Rooms')
plt.ylabel('House Price (Thousands of Dollars)')
plt.title('Linear Regression Prediction')
plt.show()

SVR نموذج ال

تحديد دالة النمذجة

def svr_results(y_test, X_test, fitted_svr_model):
    print("C: {}".format(fitted_svr_model.C))
    print("Epsilon: {}".format(fitted_svr_model.epsilon))
    print("Intercept: {:,.3f}".format(fitted_svr_model.intercept_[0]))
    print("Coefficient: {:,.3f}".format(fitted_svr_model.coef_[0]))
    mae = mean_absolute_error(y_test, fitted_svr_model.predict(X_test))
    print("MAE = ${:,.2f}".format(1000*mae))
    perc_within_eps = 100*np.sum(y_test - fitted_svr_model.predict(X_test) < eps) / len(y_test)
    print("Percentage within Epsilon = {:,.2f}%".format(perc_within_eps))
    # Plot outputs
    plt.figure(figsize=(10,7))
    plt.scatter(x=df['rooms'], y=df['cmedv'])
    plt.plot(X_test, fitted_svr_model.predict(X_test), color='red')
    plt.plot(X_test, fitted_svr_model.predict(X_test)+eps, color='black')
    plt.plot(X_test, fitted_svr_model.predict(X_test)-eps, color='black')
    plt.xlabel('# of Rooms')
    plt.ylabel('House Price (Thousands of Dollars)')
    plt.title('SVR Prediction')
    plt.show()

نموذج ال سي في ار الخطي البسيط

from sklearn.svm import LinearSVR
eps = 5
svr = LinearSVR(epsilon=eps, C=0.01, fit_intercept=True)
svr.fit(X_train, y_train)
svr_results(y_test, x_test, svr)


Cمع قيمة كبيرة ل

eps = 5
svr_high_C = LinearSVR(epsilon=eps, C=1.0, fit_intercept=True)
svr_high_C.fit(X_train, y_train)
svr_results(y_test, X_test, svr_high_C)

Cمع قيمةمختلفه ل

from sklearn.metrics import mean_absolute_error
test_mae_list = []
perc_within_eps_list = []
eps = 5
c_space = np.linspace(0.01, 10)
for c in c_space:
    varied_svr = LinearSVR(epsilon=eps, C=c, fit_intercept=True, max_iter=10000)
    varied_svr.fit(X_train, y_train) 
    test_mae = mean_absolute_error(y_test, varied_svr.predict(X_test))
    test_mae_list.append(test_mae)
    perc_within_eps = 100*np.sum(abs(y_test-varied_svr.predict(X_test)) <= eps) / len(y_test)
    perc_within_eps_list.append(perc_within_eps)
fig, ax1 = plt.subplots(figsize=(12,7))
color='green'
ax1.set_xlabel('C')
ax1.set_ylabel('% within Epsilon', color=color)
ax1.scatter(c_space, perc_within_eps_list, color=color)
ax1.tick_params(axis='y', labelcolor=color)
color='blue'
ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('Test MAE', color=color)  # we already handled the x-label with ax1
ax2.scatter(c_space, test_mae_list, color=color)
ax2.tick_params(axis='y', labelcolor=color)
plt.show()
m = max(perc_within_eps_list)
inds = [i for i, j in enumerate(perc_within_eps_list) if j == m]
C = c_space[inds[0]]
print("best C =", C)

Cالقيمة المثالية ل

eps = 5
svr_best_C = LinearSVR(epsilon=eps, C=C, fit_intercept=True)
svr_best_C.fit(X_train, y_train)
svr_results(y_test, X_test, svr_best_C)

Grid Search over C and Epsilon
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_absolute_error

grid = {
    'C': np.linspace(0.01, 10),
    'epsilon': np.linspace(0.01, 10)
}   
svr_gridsearch =  LinearSVR(fit_intercept=True, max_iter=10000)

MAE معايير التقييم

grid_svr = GridSearchCV(svr_gridsearch, grid, scoring='neg_mean_absolute_error', cv=5)
grid_svr.fit(X_train, y_train)
best_grid_svr_mae = grid_svr.best_estimator_
best_grid_svr_mae.fit(X_train, y_train)
svr_results(y_test, X_test, best_grid_svr_mae)

% within Epsilon معايير التقييم

grid = {
    'C': np.linspace(0.01, 10),
    'epsilon': np.linspace(0.01, 10)
}   
svr_gridsearch =  LinearSVR(fit_intercept=True, max_iter=10000)
from sklearn.metrics import make_scorer
def frac_within_eps(y_true, y_pred):
    return np.sum(abs(y_true-y_pred) <= eps) / len(y_true)
my_scorer = make_scorer(frac_within_eps, greater_is_better=True)
grid_svr_eps = GridSearchCV(svr_gridsearch, grid, scoring=my_scorer, cv=5)
grid_svr_eps.fit(X_train, y_train)
best_grid_svr_eps = grid_svr_eps.best_estimator_
best_grid_svr_eps.fit(X_train, y_train)
svr_results(y_test, X_test, best_grid_svr_eps)

 

Share on facebook
فاسبوك
Share on twitter
تويتر
Share on linkedin
لينكد إن
Share on whatsapp
واتساب

اترك تعليقاً

المشاركات الاخيرة

أحدث التعليقات

أفحص بحثك بالمجان

رفع الملف