You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/he/7-TimeSeries/3-SVR/README.md

17 KiB

חיזוי סדרות זמן עם Support Vector Regressor

בשיעור הקודם, למדת כיצד להשתמש במודל ARIMA כדי לבצע תחזיות של סדרות זמן. עכשיו תכיר את מודל Support Vector Regressor, שהוא מודל רגרסיה המשמש לחיזוי נתונים רציפים.

מבחן מקדים

מבוא

בשיעור זה, תגלו דרך ספציפית לבנות מודלים עם SVM: Support Vector Machine עבור רגרסיה, או SVR: Support Vector Regressor.

SVR בהקשר של סדרות זמן 1

לפני שנבין את החשיבות של SVR בחיזוי סדרות זמן, הנה כמה מושגים חשובים שעליכם להכיר:

  • רגרסיה: טכניקת למידה מונחית לחיזוי ערכים רציפים מתוך קבוצת נתונים נתונה. הרעיון הוא להתאים עקומה (או קו) במרחב התכונות שיש לה את המספר המרבי של נקודות נתונים. לחצו כאן למידע נוסף.
  • Support Vector Machine (SVM): סוג של מודל למידת מכונה מונחית המשמש לסיווג, רגרסיה וזיהוי חריגות. המודל הוא היפר-מישור במרחב התכונות, שבמקרה של סיווג משמש כגבול, ובמקרה של רגרסיה משמש כקו ההתאמה הטוב ביותר. ב-SVM, פונקציית Kernel משמשת בדרך כלל כדי להפוך את קבוצת הנתונים למרחב בעל מספר ממדים גבוה יותר, כך שניתן להפריד אותם בקלות. לחצו כאן למידע נוסף על SVMs.
  • Support Vector Regressor (SVR): סוג של SVM, שמטרתו למצוא את קו ההתאמה הטוב ביותר (שבמקרה של SVM הוא היפר-מישור) שיש לו את המספר המרבי של נקודות נתונים.

למה SVR? 1

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

תרגיל - בניית מודל SVR

השלבים הראשונים להכנת הנתונים זהים לאלה של השיעור הקודם על ARIMA.

פתחו את /working בתיקייה של שיעור זה ומצאו את הקובץ notebook.ipynb.2

  1. הריצו את המחברת וייבאו את הספריות הנדרשות: 2

    import sys
    sys.path.append('../../')
    
    import os
    import warnings
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import datetime as dt
    import math
    
    from sklearn.svm import SVR
    from sklearn.preprocessing import MinMaxScaler
    from common.utils import load_data, mape
    
  2. טענו את הנתונים מתוך הקובץ /data/energy.csv לתוך DataFrame של Pandas והסתכלו עליהם: 2

    energy = load_data('../../data')[['load']]
    
  3. צרו גרף של כל נתוני האנרגיה הזמינים מינואר 2012 עד דצמבר 2014: 2

    energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    נתונים מלאים

    עכשיו, בואו נבנה את מודל ה-SVR שלנו.

יצירת קבוצות אימון ובדיקה

עכשיו הנתונים שלכם טעונים, כך שתוכלו להפריד אותם לקבוצות אימון ובדיקה. לאחר מכן תעצבו מחדש את הנתונים כדי ליצור קבוצת נתונים מבוססת צעדי זמן, שתידרש עבור SVR. תאמנו את המודל שלכם על קבוצת האימון. לאחר שהמודל סיים את האימון, תעריכו את דיוקו על קבוצת האימון, קבוצת הבדיקה ולאחר מכן על כל קבוצת הנתונים כדי לראות את הביצועים הכוללים. עליכם לוודא שקבוצת הבדיקה מכסה תקופה מאוחרת יותר בזמן מקבוצת האימון כדי להבטיח שהמודל לא יקבל מידע מתקופות זמן עתידיות 2 (מצב המכונה Overfitting).

  1. הקצו תקופה של חודשיים מה-1 בספטמבר עד ה-31 באוקטובר 2014 לקבוצת האימון. קבוצת הבדיקה תכלול את התקופה של חודשיים מה-1 בנובמבר עד ה-31 בדצמבר 2014: 2

    train_start_dt = '2014-11-01 00:00:00'
    test_start_dt = '2014-12-30 00:00:00'
    
  2. הציגו את ההבדלים: 2

    energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
        .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
        .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    נתוני אימון ובדיקה

הכנת הנתונים לאימון

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

  1. סננו את קבוצת הנתונים המקורית כך שתכלול רק את התקופות שהוזכרו לכל קבוצה ותכלול רק את העמודה הדרושה 'load' בנוסף לתאריך: 2

    train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
    test = energy.copy()[energy.index >= test_start_dt][['load']]
    
    print('Training data shape: ', train.shape)
    print('Test data shape: ', test.shape)
    
    Training data shape:  (1416, 1)
    Test data shape:  (48, 1)
    
  2. בצעו סקיילינג לנתוני האימון כך שיהיו בטווח (0, 1): 2

    scaler = MinMaxScaler()
    train['load'] = scaler.fit_transform(train)
    
  3. עכשיו, בצעו סקיילינג לנתוני הבדיקה: 2

    test['load'] = scaler.transform(test)
    

יצירת נתונים עם צעדי זמן 1

עבור SVR, אתם ממירים את נתוני הקלט לצורה [batch, timesteps]. לכן, תעצבו מחדש את train_data ו-test_data כך שתהיה ממד חדש שמתייחס לצעדי הזמן.

# Converting to numpy arrays
train_data = train.values
test_data = test.values

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

timesteps=5

המרת נתוני האימון לטנסור דו-ממדי באמצעות list comprehension מקונן:

train_data_timesteps=np.array([[j for j in train_data[i:i+timesteps]] for i in range(0,len(train_data)-timesteps+1)])[:,:,0]
train_data_timesteps.shape
(1412, 5)

המרת נתוני הבדיקה לטנסור דו-ממדי:

test_data_timesteps=np.array([[j for j in test_data[i:i+timesteps]] for i in range(0,len(test_data)-timesteps+1)])[:,:,0]
test_data_timesteps.shape
(44, 5)

בחירת קלטים ופלטים מנתוני האימון והבדיקה:

x_train, y_train = train_data_timesteps[:,:timesteps-1],train_data_timesteps[:,[timesteps-1]]
x_test, y_test = test_data_timesteps[:,:timesteps-1],test_data_timesteps[:,[timesteps-1]]

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
(1412, 4) (1412, 1)
(44, 4) (44, 1)

יישום SVR 1

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

  1. הגדירו את המודל על ידי קריאה ל-SVR() והעברת היפר-פרמטרים של המודל: kernel, gamma, c ו-epsilon
  2. הכינו את המודל לנתוני האימון על ידי קריאה לפונקציה fit()
  3. בצעו תחזיות על ידי קריאה לפונקציה predict()

עכשיו ניצור מודל SVR. כאן נשתמש ב-RBF kernel, ונגדיר את היפר-פרמטרים gamma, C ו-epsilon כ-0.5, 10 ו-0.05 בהתאמה.

model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)

התאמת המודל לנתוני האימון 1

model.fit(x_train, y_train[:,0])
SVR(C=10, cache_size=200, coef0=0.0, degree=3, epsilon=0.05, gamma=0.5,
    kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)

ביצוע תחזיות עם המודל 1

y_train_pred = model.predict(x_train).reshape(-1,1)
y_test_pred = model.predict(x_test).reshape(-1,1)

print(y_train_pred.shape, y_test_pred.shape)
(1412, 1) (44, 1)

יצרתם את ה-SVR שלכם! עכשיו נצטרך להעריך אותו.

הערכת המודל שלכם 1

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

החזירו את הפלטים המנובאים והמקוריים לסקייל המקורי:

# Scaling the predictions
y_train_pred = scaler.inverse_transform(y_train_pred)
y_test_pred = scaler.inverse_transform(y_test_pred)

print(len(y_train_pred), len(y_test_pred))
# Scaling the original values
y_train = scaler.inverse_transform(y_train)
y_test = scaler.inverse_transform(y_test)

print(len(y_train), len(y_test))

בדיקת ביצועי המודל על נתוני האימון והבדיקה 1

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

train_timestamps = energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)].index[timesteps-1:]
test_timestamps = energy[test_start_dt:].index[timesteps-1:]

print(len(train_timestamps), len(test_timestamps))
1412 44

צרו גרף של התחזיות עבור נתוני האימון:

plt.figure(figsize=(25,6))
plt.plot(train_timestamps, y_train, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(train_timestamps, y_train_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.title("Training data prediction")
plt.show()

תחזית נתוני אימון

הדפיסו את MAPE עבור נתוני האימון

print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
MAPE for training data: 1.7195710200875551 %

צרו גרף של התחזיות עבור נתוני הבדיקה

plt.figure(figsize=(10,3))
plt.plot(test_timestamps, y_test, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(test_timestamps, y_test_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.show()

תחזית נתוני בדיקה

הדפיסו את MAPE עבור נתוני הבדיקה

print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
MAPE for testing data:  1.2623790187854018 %

🏆 קיבלתם תוצאה טובה מאוד על קבוצת הבדיקה!

בדיקת ביצועי המודל על כל קבוצת הנתונים 1

# Extracting load values as numpy array
data = energy.copy().values

# Scaling
data = scaler.transform(data)

# Transforming to 2D tensor as per model input requirement
data_timesteps=np.array([[j for j in data[i:i+timesteps]] for i in range(0,len(data)-timesteps+1)])[:,:,0]
print("Tensor shape: ", data_timesteps.shape)

# Selecting inputs and outputs from data
X, Y = data_timesteps[:,:timesteps-1],data_timesteps[:,[timesteps-1]]
print("X shape: ", X.shape,"\nY shape: ", Y.shape)
Tensor shape:  (26300, 5)
X shape:  (26300, 4) 
Y shape:  (26300, 1)
# Make model predictions
Y_pred = model.predict(X).reshape(-1,1)

# Inverse scale and reshape
Y_pred = scaler.inverse_transform(Y_pred)
Y = scaler.inverse_transform(Y)
plt.figure(figsize=(30,8))
plt.plot(Y, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(Y_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.show()

תחזית נתונים מלאים

print('MAPE: ', mape(Y_pred, Y)*100, '%')
MAPE:  2.0572089029888656 %

🏆 גרפים מרשימים מאוד, שמראים מודל עם דיוק טוב. כל הכבוד!


🚀אתגר

  • נסו לשנות את היפר-פרמטרים (gamma, C, epsilon) בזמן יצירת המודל והעריכו את הנתונים כדי לראות איזה סט של היפר-פרמטרים נותן את התוצאות הטובות ביותר על נתוני הבדיקה. למידע נוסף על היפר-פרמטרים אלה, תוכלו לעיין בתיעוד כאן.
  • נסו להשתמש בפונקציות kernel שונות עבור המודל ונתחו את ביצועיהן על קבוצת הנתונים. מסמך מועיל ניתן למצוא כאן.
  • נסו להשתמש בערכים שונים עבור timesteps כדי שהמודל יוכל להסתכל אחורה ולבצע תחזית.

מבחן מסכם

סקירה ולימוד עצמי

שיעור זה נועד להציג את השימוש ב-SVR לחיזוי סדרות זמן. לקריאה נוספת על SVR, תוכלו לעיין ב-בלוג הזה. תיעוד זה ב-scikit-learn מספק הסבר מקיף יותר על SVMs באופן כללי, SVRs וגם פרטי יישום אחרים כמו פונקציות kernel שונות שניתן להשתמש בהן, והפרמטרים שלהן.

משימה

מודל SVR חדש

קרדיטים


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


  1. הטקסט, הקוד והתוצאות בסעיף זה נתרמו על ידי @AnirbanMukherjeeXD ↩︎

  2. הטקסט, הקוד והתוצאות בסעיף זה נלקחו מ-ARIMA ↩︎