|
3 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
working | 3 weeks ago | |
README.md | 3 weeks ago | |
assignment.md | 3 weeks ago |
README.md
پیشبینی سریهای زمانی با استفاده از مدل Support Vector Regressor
در درس قبلی، یاد گرفتید که چگونه از مدل ARIMA برای پیشبینی سریهای زمانی استفاده کنید. اکنون به مدل Support Vector Regressor میپردازیم که یک مدل رگرسیون برای پیشبینی دادههای پیوسته است.
پیشزمینه درس
مقدمه
در این درس، با روش خاصی برای ساخت مدلها با SVM: ماشین بردار پشتیبان برای رگرسیون، یا SVR: Support Vector Regressor آشنا خواهید شد.
SVR در زمینه سریهای زمانی 1
قبل از درک اهمیت SVR در پیشبینی سریهای زمانی، برخی از مفاهیم مهمی که باید بدانید عبارتند از:
- رگرسیون: تکنیک یادگیری نظارتشده برای پیشبینی مقادیر پیوسته از مجموعهای از ورودیها. ایده این است که یک منحنی (یا خط) در فضای ویژگیها پیدا شود که بیشترین تعداد نقاط داده را پوشش دهد. اینجا کلیک کنید برای اطلاعات بیشتر.
- ماشین بردار پشتیبان (SVM): نوعی مدل یادگیری ماشین نظارتشده که برای طبقهبندی، رگرسیون و شناسایی نقاط پرت استفاده میشود. این مدل یک ابرصفحه در فضای ویژگیها است که در حالت طبقهبندی به عنوان مرز عمل میکند و در حالت رگرسیون به عنوان خط بهترین برازش. در SVM، معمولاً از یک تابع کرنل برای تبدیل مجموعه داده به فضایی با ابعاد بالاتر استفاده میشود تا بتوانند به راحتی جدا شوند. اینجا کلیک کنید برای اطلاعات بیشتر درباره SVM.
- Support Vector Regressor (SVR): نوعی SVM که برای یافتن خط بهترین برازش (که در حالت SVM یک ابرصفحه است) با بیشترین تعداد نقاط داده استفاده میشود.
چرا SVR؟ 1
در درس قبلی درباره ARIMA یاد گرفتید، که یک روش آماری خطی بسیار موفق برای پیشبینی دادههای سریهای زمانی است. با این حال، در بسیاری از موارد، دادههای سریهای زمانی دارای غیرخطی بودن هستند که نمیتوانند توسط مدلهای خطی نقشهبرداری شوند. در چنین مواردی، توانایی SVM در در نظر گرفتن غیرخطی بودن دادهها برای وظایف رگرسیون، SVR را در پیشبینی سریهای زمانی موفق میکند.
تمرین - ساخت مدل SVR
مراحل اولیه آمادهسازی دادهها مشابه درس قبلی درباره ARIMA است.
پوشه /working را در این درس باز کنید و فایل notebook.ipynb را پیدا کنید.2
-
نوتبوک را اجرا کنید و کتابخانههای لازم را وارد کنید: 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
-
دادهها را از فایل
/data/energy.csv
به یک دیتافریم Pandas بارگذاری کنید و نگاهی بیندازید: 2energy = load_data('../../data')[['load']]
-
تمام دادههای انرژی موجود از ژانویه 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 سپتامبر تا 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
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 قرار گیرند.
-
مجموعه داده اصلی را فیلتر کنید تا فقط دورههای زمانی ذکر شده برای هر مجموعه و فقط ستون مورد نیاز '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)
-
دادههای آموزشی را مقیاسبندی کنید تا در بازه (0, 1) قرار گیرند: 2
scaler = MinMaxScaler() train['load'] = scaler.fit_transform(train)
-
اکنون دادههای آزمایشی را مقیاسبندی کنید: 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
تبدیل دادههای آموزشی به تنسور دوبعدی با استفاده از لیستهای تو در تو:
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 است. برای اطلاعات بیشتر درباره این پیادهسازی، میتوانید به این مستندات مراجعه کنید. برای پیادهسازی ما، مراحل زیر را دنبال میکنیم:
- مدل را با فراخوانی
SVR()
و ارسال هایپرپارامترهای مدل تعریف کنید: kernel، gamma، c و epsilon - مدل را برای دادههای آموزشی با فراخوانی تابع
fit()
آماده کنید - پیشبینیها را با فراخوانی تابع
predict()
انجام دهید
اکنون یک مدل SVR ایجاد میکنیم. در اینجا از کرنل RBF استفاده میکنیم و هایپرپارامترهای 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) را هنگام ایجاد مدل تغییر دهید و روی دادهها ارزیابی کنید تا ببینید کدام مجموعه هایپرپارامترها بهترین نتایج را روی دادههای آزمایشی میدهند. برای اطلاعات بیشتر درباره این هایپرپارامترها، میتوانید به این مستندات مراجعه کنید.
- سعی کنید از توابع کرنل مختلف برای مدل استفاده کنید و عملکرد آنها را روی مجموعه داده تحلیل کنید. یک مستند مفید را میتوانید اینجا پیدا کنید.
- سعی کنید از مقادیر مختلف برای
timesteps
استفاده کنید تا مدل بتواند برای پیشبینی نگاه به عقب داشته باشد.
آزمون پس از درس
مرور و مطالعه خودآموز
این درس برای معرفی کاربرد SVR در پیشبینی سریهای زمانی بود. برای مطالعه بیشتر درباره SVR، میتوانید به این بلاگ مراجعه کنید. این مستندات در scikit-learn توضیحات جامعتری درباره SVMها به طور کلی، SVRها و همچنین جزئیات دیگر پیادهسازی مانند توابع کرنل مختلف که میتوان استفاده کرد و پارامترهای آنها ارائه میدهد.
تکلیف
منابع
سلب مسئولیت:
این سند با استفاده از سرویس ترجمه هوش مصنوعی Co-op Translator ترجمه شده است. در حالی که ما تلاش میکنیم دقت را حفظ کنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، توصیه میشود از ترجمه حرفهای انسانی استفاده کنید. ما مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.
-
متن، کد و خروجی در این بخش توسط @AnirbanMukherjeeXD ارائه شده است. ↩︎