הבנת הפרמטרים היפרפרמטרים של SVM

הבנת הפרמטרים היפרפרמטרים של SVM

מבוא

מדריך זה הוא החלק השני מתוך שלושה מדריכים על Support Vector Machines (SVMs). במדריך זה, נמשיך לעבוד על מקרה השימוש בשטרות מזויפים, נבין אילו פרמטרים של SVM כבר מוגדרים על ידי Scikit-learn, מהם הפרמטרים היפרפרמטרים של C ו-Gamma, וכיצד לכוון אותם באמצעות אימות צולב וחיפוש רשת.

בסדרה המלאה של מדריכי SVM, מלבד היפרפרמטרים של SVM, תלמדו גם על SVM פשוט, מושג הנקרא טריק גרעין, ולחקור סוגים אחרים של SVMs.

אם ברצונך לקרוא את כל המדריכים, עיין במדריך הראשון, או ראה אילו מהם מעניינים אותך ביותר, להלן טבלת הנושאים המכוסים בכל מדריך:

  1. הטמעת SVM ו-Kernel SVM עם Scikit-Learn של Python
  • מקרה שימוש: שכח שטרות
  • רקע של SVMs
  • דגם SVM פשוט (ליניארי).
    • לגבי מערך הנתונים
    • ייבוא ​​מערך הנתונים
    • חקר מערך הנתונים
  • הטמעת SVM עם Scikit-Learn
    • חלוקת נתונים לקבוצות רכבת/בדיקות
    • הכשרת המודל
    • להכין תחזיות
    • הערכת המודל
    • פירוש תוצאות

2. הבנת היפרפרמטרים של SVM

  • היפרפרמטר C
  • היפרפרמטר גמא

3. הטמעת טעמי SVM אחרים עם Scikit-Learn של Python (בקרוב!)

  • הרעיון הכללי של SVMs (תקציר)
  • ליבה (טריק) SVM
  • הטמעת SVM ליבה לא ליניארית עם Scikit-Learn
  • ייבוא ​​ספריות
    • ייבוא ​​מערך הנתונים
    • חלוקת נתונים לתכונות (X) ויעד (y)
    • חלוקת נתונים לקבוצות רכבת/בדיקות
    • אימון האלגוריתם
  • גרעין פולינומי
    • להכין תחזיות
    • הערכת האלגוריתם
  • גרעין גאוסי
    • חיזוי והערכה
  • קרנל סיגמואיד
    • חיזוי והערכה
  • השוואה בין ביצועי ליבה לא לינאריים

בואו ללמוד כיצד ליישם אימות צולב ולבצע כוונון היפרפרמטר.

היפרפרמטרים של SVM

כדי לראות את כל פרמטרי המודל שכבר הוגדרו על ידי Scikit-learn ואת ערכי ברירת המחדל שלו, נוכל להשתמש ב- get_params() שיטה:

svc.get_params()

שיטה זו מציגה:

{'C': 1.0, 'break_ties': False, 'cache_size': 200, 'class_weight': None, 'coef0': 0.0, 'decision_function_shape': 'ovr', 'degree': 3, 'gamma': 'scale', 'kernel': 'linear', 'max_iter': -1, 'probability': False, 'random_state': None, 'shrinking': True, 'tol': 0.001, 'verbose': False}

שימו לב שכבר מוגדרים בסך הכל 15 היפרפרמטרים, זה קורה כי לאלגוריתם SVM יש הרבה וריאציות. השתמשנו בלינה הליניארית כדי להשיג פונקציה ליניארית, אבל יש גם גרעינים שמתארים סוגים אחרים של פונקציות והגרעינים האלה מותאמים בדרכים שונות.

וריאציות אלו הופכות את המודל לגמיש יותר ומתאים למציאת הפרדה בין צורות שונות של נתונים. אם נוכל למתוח קו כדי להפריד בין הכיתות שלנו, אז א גרעין ליניארי תהיה אפשרות טובה, אם אנחנו צריכים עקומה, אז א פולינום הקרנל עשוי להיות הבחירה הטובה ביותר, אם לנתונים שלנו יש צורות מעגליות, אז א פונקציית בסיס רדיאלי or RBF הקרנל יתאים יותר לנתונים, אם יש ערכים מעל ומתחת לסף, א סיגמואיד הקרנל עשוי להפריד בין המחלקות טוב יותר. לפי מה שחקרנו בנתונים שלנו, נראה שגם RBF או גרעין פולינומי יתאימו יותר מליבה ליניארית.

עכשיו כשיש לנו רעיון שיש 4 סוגים של פונקציות קרנל שונות, אנחנו יכולים לחזור לפרמטרים. כאשר אלגוריתם ה-SVM מנסה למצוא הפרדה בין מחלקות, כבר הבנו שהוא משרטט סיווג שולים בין וקטורי התמיכה לקו ההפרדה (או העקומה).

מרווח זה הוא, במובן מסוים, כמו חיץ בין קו ההפרדה לנקודות. גודל השוליים יכול להשתנות, כאשר השוליים הם קטן יותר, יש פחות מקום לנקודות שנופלות מחוץ לשוליים, מה שהופך את ההפרדה בין המחלקות לברורה יותר, כך שמוצגות יותר דוגמאות מסווג נכון, לעומת זאת, כאשר השוליים הוא גדול יותר, ההפרדה בין מחלקות פחות ברורה, ויכולות להיות יותר דוגמאות סיווג שגוי. במילים אחרות, מרווח קטן יותר פירושו דגימות מסווגות נכון יותר, וגם יותר נוקשה מסווג, בעוד ששוליים גדולים יותר, מציינים יותר דגימות שסווגות בצורה שגויה, אבל יותר גמיש מסווג.

כאשר שוליים אלה נבחרים, הפרמטר שקובע אותם הוא ה- C פָּרָמֶטֶר.

היפרפרמטר C

השמיים C הפרמטר עומד ביחס הפוך לגודל השוליים, זה אומר שה גדול יותר את הערך של C, ה קטן יותר השוליים, ולהפך, ה- קטן יותר את הערך של C, ה גדול יותר השוליים. ה C ניתן להשתמש בפרמטר יחד עם כל גרעין, הוא אומר לאלגוריתם כמה להימנע מסיווג שגוי של כל דגימת אימון, בשל כך, הוא ידוע גם בשם סדירה. הגרעין הליניארי SVM שלנו השתמש ב- a C של 1.0, שהוא א גָדוֹל ערך ונותן א שוליים קטנים יותר.

הבנת הפרמטרים היפרפרמטרים של SVM PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

אנחנו יכולים להתנסות עם א קטן יותר ערך 'C' ולהבין בפועל מה קורה עם a מרווח גדול יותר. לשם כך, ניצור מסווג חדש, svc_c, ושנה רק את הערך של C ל 0.0001. בואו נחזור גם על fit ו predict צעדים:

svc_c = SVC(kernel='linear', C=0.0001)
svc_c.fit(X_train, y_train)
y_pred_c = svc_c.predict(X_test)

כעת נוכל להסתכל על התוצאות עבור נתוני הבדיקה:

print(classification_report(y_test, y_pred_c)) cm_c = confusion_matrix(y_test, y_pred_c)
sns.heatmap(cm_c, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001')

תפוקות אלה:

 precision recall f1-score support 0 0.82 0.96 0.88 148 1 0.94 0.76 0.84 127 accuracy 0.87 275 macro avg 0.88 0.86 0.86 275
weighted avg 0.88 0.87 0.86 275

הבנת הפרמטרים היפרפרמטרים של SVM PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

על ידי שימוש קטן יותר C ובהשגת מרווח גדול יותר, הסיווג הפך גמיש יותר ועם יותר טעויות סיווג. בדוח הסיווג, אנו יכולים לראות כי f1-score, בעבר 0.99 עבור שתי המחלקות, ירד ל-0.88 עבור מחלקה 0, ול-0.84 עבור מחלקה 1. במטריצת הבלבול, המודל עבר מ-2 ל-6 תוצאות חיוביות שגויות, ומ-2 ל-31 שליליות שגויות.

אנחנו יכולים גם לחזור על predict שלב והסתכל בתוצאות כדי לבדוק אם עדיין יש התאמה יתר בעת שימוש בנתוני רכבת:

y_pred_ct = svc_c.predict(X_train) cm_ct = confusion_matrix(y_train, y_pred_ct)
sns.heatmap(cm_ct, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001 and train data') print(classification_report(y_train, y_pred_ct))

זו התוצאה:

 precision recall f1-score support 0 0.88 0.96 0.92 614 1 0.94 0.84 0.88 483 accuracy 0.90 1097 macro avg 0.91 0.90 0.90 1097
weighted avg 0.91 0.90 0.90 1097

הבנת הפרמטרים היפרפרמטרים של SVM PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

על ידי הסתכלות על התוצאות עם קטן יותר C ונתוני רכבות, אנו יכולים לראות שהיה שיפור בהתאמה יתרה, אך ברגע שרוב המדדים עדיין גבוהים יותר עבור נתוני רכבת, נראה שההתאמות המופרזת לא נפתרה. אז, רק לשנות את C פרמטר לא הספיק כדי להפוך את המודל לגמיש יותר ולשפר את ההכללה שלו.

הערות: מנסה למצוא איזון בין פונקציה שמתרחקת מדי מהנתונים, מקובעת מדי או שיש לה הטיה גבוהה או שזה הפוך, פונקציה שמתאימה לסגור את הנתונים, גמישה מדי או שיש שונות גבוהה מכונה בדרך כלל ה פשרה בשונות הטיה. מציאת האיזון הזה אינה טריוויאלית, אך כאשר הוא מושג, אין התאמה או התאמה יתר של המודל לנתונים. כדרך להפחתת השונות ולמניעת התאמת יתר, ניתן לכווץ את הנתונים באופן שווה כדי להפוך אותם לסדירים יותר ולפשט אותם בעת קבלת פונקציה המתארת ​​אותם. זה מה הפרמטר C עושה כאשר נעשה בו שימוש ב-SVM, מסיבה זו, הוא נקרא גם ויסות L2 or רגרסיה של רידג '.

עד לנקודה זו, הבנו לגבי השוליים ב-SVM וכיצד הם משפיעים על התוצאה הכוללת של האלגוריתם, אבל מה לגבי הקו (או העקומה) שמפרידה בין המחלקות? הקו הזה הוא גבול החלטה. אז, אנחנו כבר יודעים שלשוליים יש השפעה על גמישות גבול ההחלטה כלפי טעויות, כעת נוכל להסתכל על פרמטר נוסף שמשפיע גם על גבול ההחלטה.

עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!

הערות: גבול ההחלטה יכול להיקרא גם א היפר-מטוס. היפר-מישור הוא מושג גיאומטרי המתייחס למספר הממדים של חלל מינוס אחד (עמומות-1). אם המרחב הוא דו-ממדי, כמו מישור עם קואורדינטות x ו-y, הקווים (או העקומות) חד-ממדיים הם מישורי ההיפר. בהקשר של למידת מכונה, מכיוון שמספר העמודות בשימוש במודל הוא ממדי המישור שלו, כאשר אנו עובדים עם 2 עמודות ומסווג SVM, אנו מוצאים היפר-מישור תלת מימדי המפריד בין מחלקות.

היפרפרמטר גמא

ניתן לבחור גבולות החלטה אינסופיים, חלק מהגבולות הללו יפרידו בין המעמדות ואחרים לא. האם בבחירת גבול החלטה אפקטיבי יש לקחת בחשבון את 10 הנקודות הראשונות הקרובות ביותר של כל מחלקה? או שצריך להתייחס לנקודות נוספות, כולל הנקודות הרחוקות? ב-SVM, בחירת הטווח מוגדרת על ידי היפרפרמטר אחר, gamma.

כמו C, gamma הוא ביחס הפוך במקצת למרחק שלו. ה גבוה יותר ערכו, ה הכי קרוב הן הנקודות שנחשבות לגבול ההחלטה, והן הנמוך ביותר מה היא gamma, ה רחוק יותר נקודות נחשבות גם לבחירת גבול ההחלטה.

הבנת הפרמטרים היפרפרמטרים של SVM PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

השפעה נוספת של גמא היא שככל שהערך שלו גבוה יותר, כך היקף גבול ההחלטה מתקרב יותר לנקודות שמסביבו, מה שהופך אותו למשונן יותר ונוטה להתאים יתר על המידה - וככל שהערך שלו נמוך יותר, כך גבול ההחלטה חלק וקבוע יותר. המשטח גם נוטה פחות לכושר יתר. זה נכון עבור כל היפר-מישור, אך ניתן לראות אותו בקלות יותר כאשר מפרידים נתונים בממדים גבוהים יותר. בתיעוד מסוימים, gamma ניתן לכנות גם sigma.

הבנת הפרמטרים היפרפרמטרים של SVM PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

במקרה של המודל שלנו, ערך ברירת המחדל של gamma היה scale. כפי שניתן לראות ב- Scikit-Learn תיעוד SVC, זה אומר שהערך שלו הוא:

$$
gamma = (1/ text{n_features} * X.var())
$$

or

$$
גמא = (1/ טקסט{number_of_features} * טקסט{features_variance})
$$

במקרה שלנו, אנחנו צריכים לחשב את השונות של X_train, הכפילו אותו ב-4 וחלקו את התוצאה ב-1. נוכל לעשות זאת באמצעות הקוד הבא:

number_of_features = X_train.shape[1] features_variance = X_train.values.var()
gamma = 1/(number_of_features * features_variance)
print('gamma:', gamma)

תפוקות אלה:

gamma: 0.013924748072859962

יש גם דרך אחרת להסתכל על הערך של gamma, על ידי גישה לאובייקט של המסווג gamma פרמטר עם ._gamma:

svc._gamma 

אנו יכולים לראות כי gamma בשימוש במסווג שלנו היה נמוך, אז הוא נחשב גם לנקודות רחוקות יותר.

הערות: כפי שראינו, C ו gamma חשובים לכמה הגדרות של המודל. היפרפרמטר נוסף, random_state, משמש לעתים קרובות ב-Scikit Learn כדי להבטיח ערבוב נתונים או זריעה אקראית עבור מודלים, כך שתמיד יש לנו את אותן התוצאות, אבל זה קצת שונה עבור SVM. במיוחד, ה random_state יש השלכות רק אם היפרפרמטר אחר, probability, מוגדר כאמת. הסיבה לכך היא שהיא תערבב את הנתונים לקבלת הערכות הסתברות. אם איננו רוצים הערכות הסתברות עבור המחלקות שלנו וההסתברות מוגדרת כ-false, SVM's random_state לפרמטר אין השלכות על תוצאות המודל.

אין כלל כיצד לבחור ערכים עבור היפרפרמטרים, כגון C וגמא - זה יהיה תלוי בכמה זמן ובאילו משאבים זמינים להתנסות עם ערכי היפרפרמטר שונים, אילו טרנספורמציות ניתן לבצע בנתונים, ואילו תוצאות צפויות . הדרך הרגילה לחפש את ערכי ההיפרפרמטר היא על ידי שילוב של כל אחד מהערכים המוצעים דרך a חיפוש ברשת יחד עם הליך שמחיל את ערכי ההיפרפרמטרים האלה ומשיג מדדים עבור חלקים שונים של הנתונים הנקראים אימות צולב. ב-Scikit-learn, זה כבר מיושם בתור GridSearchCV (קורות חיים מאימות צולב).

כדי להפעיל חיפוש רשת עם אימות צולב, עלינו לייבא את GridSearchCV, הגדירו מילון עם ערכי היפרפרמטרים שיתנסו בהם, כגון סוג kernel, הטווח עבור C, ועבור gamma, צור מופע של ה SVC, תגדיר את score או מדד ישמש להערכה (כאן נבחר לבצע אופטימיזציה הן לדיוק והן לזיכרון, אז נשתמש f1-score), מספר החלוקים שיבוצעו בנתונים להפעלת החיפוש cv - ברירת המחדל היא 5, אבל זה נוהג טוב להשתמש ב-10 לפחות - כאן, נשתמש ב-5 קיפולי נתונים כדי להבהיר את זה בהשוואת תוצאות.

השמיים GridSearchCV יש fit שיטה שמקבלת את נתוני הרכבת שלנו ומפצלת אותם עוד יותר בערכות רכבת ובדיקות לצורך אימות צולב. אנחנו יכולים להגדיר return_train_score נכון כדי להשוות את התוצאות ולהבטיח שאין כושר יתר.

זה הקוד לחיפוש הרשת עם אימות צולב:

from sklearn.model_selection import GridSearchCV parameters_dictionary = {'kernel':['linear', 'rbf'], 'C':[0.0001, 1, 10], 'gamma':[1, 10, 100]}
svc = SVC() grid_search = GridSearchCV(svc, parameters_dictionary, scoring = 'f1', return_train_score=True, cv = 5, verbose = 1) grid_search.fit(X_train, y_train)

פלט קוד זה:

Fitting 5 folds for each of 18 candidates, totalling 90 fits
# and a clickable GridSeachCV object schema

לאחר ביצוע חיפוש ההיפרפרמטר, נוכל להשתמש ב- best_estimator_, best_params_ ו best_score_ מאפיינים להשגת המודל הטוב ביותר, ערכי פרמטרים וציון f1 הגבוה ביותר:

best_model = grid_search.best_estimator_
best_parameters = grid_search.best_params_
best_f1 = grid_search.best_score_ print('The best model was:', best_model)
print('The best parameter values were:', best_parameters)
print('The best f1-score was:', best_f1)

זו התוצאה:

The best model was: SVC(C=1, gamma=1)
The best parameter values were: {'C': 1, 'gamma': 1, 'kernel': 'rbf'}
The best f1-score was: 0.9979166666666666

מה שמאשר את הניחוש הראשוני שלנו מהתבוננות בנתונים, למודל הטוב ביותר אין גרעין ליניארי, אלא לא ליניארי, RBF.

עֵצָה: בעת חקירה נוספת, מעניין שתכלול יותר גרעינים לא ליניאריים בחיפוש הרשת.

שניהם C ו gamma יש את הערך של 1, ואת f1-score הוא גבוה מאוד, 0.99. מכיוון שהערך גבוה, בוא נראה אם ​​הייתה התאמה יתרה על ידי הצצה לממוצע במבחן וציוני הרכבת שהחזרנו, בתוך cv_results_ אובייקט:

gs_mean_test_scores = grid_search.cv_results_['mean_test_score']
gs_mean_train_scores = grid_search.cv_results_['mean_train_score'] print("The mean test f1-scores were:", gs_mean_test_scores)
print("The mean train f1-scores were:", gs_mean_train_scores)

הציונים הממוצעים היו:

The mean test f1-scores were: [0.78017291 0. 0.78017291 0. 0.78017291 0. 0.98865407 0.99791667 0.98865407 0.76553515 0.98865407 0.040291 0.98656 0.99791667 0.98656 0.79182565 0.98656 0.09443985] The mean train f1-scores were: [0.78443424 0. 0.78443424 0. 0.78443424 0. 0.98762683 1. 0.98762683 1. 0.98762683 1. 0.98942923 1. 0.98942923 1. 0.98942923 1. ]

בהסתכלות על הציונים הממוצעים, אנו יכולים לראות שהציון הגבוה ביותר, 0.99791667 מופיע פעמיים, ובשני המקרים, הציון בנתוני הרכבת היה 1. זה מצביע על כושר היתר נמשך. מכאן, יהיה מעניין לחזור להכנת הנתונים ולהבין אם יש טעם לנרמל את הנתונים, לבצע סוג אחר של טרנספורמציה של נתונים, וגם ליצור תכונות חדשות עם הנדסת תכונות.

זה עתה ראינו טכניקה למציאת הפרמטרים ההיפר-פרמטרים של המודל, וכבר הזכרנו משהו על הפרדה ליניארית, וקטורי תמיכה, גבול החלטה, מקסום שוליים וטריק ליבה. SVM הוא אלגוריתם מורכב, בדרך כלל עם הרבה מושגים מתמטיים מעורבים וחלקים קטנים שניתנים לשינוי שצריך להתאים כדי להתאחד כמכלול.

בואו נשלב את מה שראינו עד כה, נסקור איך כל החלקים של SVM עובדים, ואז נסתכל על כמה מיישומי הליבה האחרים יחד עם התוצאות שלהם.

סיכום

במאמר זה הבנו על פרמטרי ברירת המחדל מאחורי הטמעת SVM של Scikit-Learn. הבנו מהם פרמטרי C ו-Gamma, וכיצד שינוי כל אחד מהם יכול להשפיע על מודל ה-SVM.

למדנו גם על חיפוש רשת כדי לחפש את ערכי ה-C וה-Gamma הטובים ביותר, ולהשתמש באימות צולב כדי להכליל טוב יותר את התוצאות שלנו ולהבטיח שאין צורה כלשהי של דליפת נתונים.

ביצוע כוונון היפרפרמטרים עם חיפוש רשת ואימות צולב הוא נוהג נפוץ במדעי הנתונים, לכן אני ממליץ בחום ליישם את הטכניקות, להפעיל את הקוד ולראות את הקישורים בין ערכי ההיפרפרמטרים והשינויים בחיזוי SVM.

בול זמן:

עוד מ Stackabuse