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.
407 lines
31 KiB
407 lines
31 KiB
<!--
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
{
|
|
"original_hash": "917dbf890db71a322f306050cb284749",
|
|
"translation_date": "2025-09-05T21:17:56+00:00",
|
|
"source_file": "7-TimeSeries/2-ARIMA/README.md",
|
|
"language_code": "th"
|
|
}
|
|
-->
|
|
# การพยากรณ์อนุกรมเวลาโดยใช้ ARIMA
|
|
|
|
ในบทเรียนก่อนหน้านี้ คุณได้เรียนรู้เกี่ยวกับการพยากรณ์อนุกรมเวลาและโหลดชุดข้อมูลที่แสดงการเปลี่ยนแปลงของโหลดไฟฟ้าในช่วงเวลาหนึ่ง
|
|
|
|
[](https://youtu.be/IUSk-YDau10 "Introduction to ARIMA")
|
|
|
|
> 🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ: บทนำสั้น ๆ เกี่ยวกับโมเดล ARIMA ตัวอย่างในวิดีโอใช้ R แต่แนวคิดสามารถนำไปใช้ได้ทั่วไป
|
|
|
|
## [แบบทดสอบก่อนเรียน](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
## บทนำ
|
|
|
|
ในบทเรียนนี้ คุณจะได้เรียนรู้วิธีเฉพาะในการสร้างโมเดลด้วย [ARIMA: *A*uto*R*egressive *I*ntegrated *M*oving *A*verage](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average) โมเดล ARIMA เหมาะอย่างยิ่งสำหรับการปรับข้อมูลที่แสดง [non-stationarity](https://wikipedia.org/wiki/Stationary_process)
|
|
|
|
## แนวคิดทั่วไป
|
|
|
|
เพื่อที่จะทำงานกับ ARIMA มีแนวคิดบางอย่างที่คุณจำเป็นต้องรู้:
|
|
|
|
- 🎓 **Stationarity**. ในบริบททางสถิติ Stationarity หมายถึงข้อมูลที่การแจกแจงไม่เปลี่ยนแปลงเมื่อเลื่อนเวลา ข้อมูลที่ไม่เป็น Stationary จะแสดงการเปลี่ยนแปลงเนื่องจากแนวโน้มที่ต้องแปลงเพื่อวิเคราะห์ ตัวอย่างเช่น Seasonality สามารถทำให้เกิดการเปลี่ยนแปลงในข้อมูลและสามารถกำจัดได้โดยกระบวนการ 'seasonal-differencing'
|
|
|
|
- 🎓 **[Differencing](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average#Differencing)**. การ Differencing ข้อมูลในบริบททางสถิติ หมายถึงกระบวนการแปลงข้อมูลที่ไม่เป็น Stationary ให้เป็น Stationary โดยการลบแนวโน้มที่ไม่คงที่ "Differencing ช่วยลบการเปลี่ยนแปลงในระดับของอนุกรมเวลา กำจัดแนวโน้มและ Seasonality และทำให้ค่าเฉลี่ยของอนุกรมเวลามีเสถียรภาพ" [บทความโดย Shixiong et al](https://arxiv.org/abs/1904.07632)
|
|
|
|
## ARIMA ในบริบทของอนุกรมเวลา
|
|
|
|
มาทำความเข้าใจส่วนต่าง ๆ ของ ARIMA เพื่อให้เข้าใจว่าโมเดลนี้ช่วยเราในการสร้างแบบจำลองอนุกรมเวลาและช่วยในการพยากรณ์ได้อย่างไร
|
|
|
|
- **AR - AutoRegressive**. โมเดล AutoRegressive ตามชื่อ หมายถึงการมองย้อนกลับไปในเวลาเพื่อวิเคราะห์ค่าก่อนหน้าในข้อมูลของคุณและทำการสันนิษฐานเกี่ยวกับค่าเหล่านั้น ค่าก่อนหน้าเหล่านี้เรียกว่า 'lags' ตัวอย่างเช่น ข้อมูลที่แสดงยอดขายดินสอรายเดือน ยอดขายรวมของแต่ละเดือนจะถือว่าเป็น 'ตัวแปรที่เปลี่ยนแปลง' ในชุดข้อมูล โมเดลนี้ถูกสร้างขึ้นโดย "ตัวแปรที่เปลี่ยนแปลงที่สนใจถูกวิเคราะห์กับค่าก่อนหน้าของตัวเอง" [wikipedia](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average)
|
|
|
|
- **I - Integrated**. แตกต่างจากโมเดล 'ARMA' ที่คล้ายกัน 'I' ใน ARIMA หมายถึงลักษณะ *[integrated](https://wikipedia.org/wiki/Order_of_integration)* ข้อมูลจะถูก 'integrated' เมื่อมีการใช้ขั้นตอน Differencing เพื่อกำจัด non-stationarity
|
|
|
|
- **MA - Moving Average**. ลักษณะ [moving-average](https://wikipedia.org/wiki/Moving-average_model) ของโมเดลนี้หมายถึงตัวแปรผลลัพธ์ที่ถูกกำหนดโดยการสังเกตค่าปัจจุบันและค่าก่อนหน้าของ lags
|
|
|
|
สรุป: ARIMA ถูกใช้เพื่อสร้างโมเดลที่ปรับให้เข้ากับรูปแบบพิเศษของข้อมูลอนุกรมเวลาให้ใกล้เคียงที่สุด
|
|
|
|
## แบบฝึกหัด - สร้างโมเดล ARIMA
|
|
|
|
เปิดโฟลเดอร์ [_/working_](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA/working) ในบทเรียนนี้และค้นหาไฟล์ [_notebook.ipynb_](https://github.com/microsoft/ML-For-Beginners/blob/main/7-TimeSeries/2-ARIMA/working/notebook.ipynb)
|
|
|
|
1. รัน notebook เพื่อโหลดไลบรารี Python `statsmodels`; คุณจะต้องใช้ไลบรารีนี้สำหรับโมเดล ARIMA
|
|
|
|
1. โหลดไลบรารีที่จำเป็น
|
|
|
|
1. ตอนนี้โหลดไลบรารีเพิ่มเติมที่มีประโยชน์สำหรับการสร้างกราฟข้อมูล:
|
|
|
|
```python
|
|
import os
|
|
import warnings
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
import pandas as pd
|
|
import datetime as dt
|
|
import math
|
|
|
|
from pandas.plotting import autocorrelation_plot
|
|
from statsmodels.tsa.statespace.sarimax import SARIMAX
|
|
from sklearn.preprocessing import MinMaxScaler
|
|
from common.utils import load_data, mape
|
|
from IPython.display import Image
|
|
|
|
%matplotlib inline
|
|
pd.options.display.float_format = '{:,.2f}'.format
|
|
np.set_printoptions(precision=2)
|
|
warnings.filterwarnings("ignore") # specify to ignore warning messages
|
|
```
|
|
|
|
1. โหลดข้อมูลจากไฟล์ `/data/energy.csv` ลงใน Pandas dataframe และดูข้อมูล:
|
|
|
|
```python
|
|
energy = load_data('./data')[['load']]
|
|
energy.head(10)
|
|
```
|
|
|
|
1. สร้างกราฟข้อมูลพลังงานทั้งหมดที่มีตั้งแต่เดือนมกราคม 2012 ถึงเดือนธันวาคม 2014 ไม่มีอะไรน่าประหลาดใจเพราะเราเห็นข้อมูลนี้ในบทเรียนที่แล้ว:
|
|
|
|
```python
|
|
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
|
|
plt.xlabel('timestamp', fontsize=12)
|
|
plt.ylabel('load', fontsize=12)
|
|
plt.show()
|
|
```
|
|
|
|
ตอนนี้มาสร้างโมเดลกัน!
|
|
|
|
### สร้างชุดข้อมูลสำหรับการฝึกและการทดสอบ
|
|
|
|
ตอนนี้ข้อมูลของคุณถูกโหลดแล้ว คุณสามารถแยกมันออกเป็นชุดข้อมูลสำหรับการฝึกและการทดสอบ คุณจะฝึกโมเดลของคุณด้วยชุดข้อมูลสำหรับการฝึก และหลังจากโมเดลฝึกเสร็จแล้ว คุณจะประเมินความแม่นยำของมันโดยใช้ชุดข้อมูลสำหรับการทดสอบ คุณต้องมั่นใจว่าชุดข้อมูลสำหรับการทดสอบครอบคลุมช่วงเวลาที่เกิดขึ้นหลังจากชุดข้อมูลสำหรับการฝึกเพื่อให้มั่นใจว่าโมเดลไม่ได้รับข้อมูลจากช่วงเวลาที่จะเกิดขึ้นในอนาคต
|
|
|
|
1. กำหนดช่วงเวลาสองเดือนตั้งแต่วันที่ 1 กันยายนถึง 31 ตุลาคม 2014 ให้เป็นชุดข้อมูลสำหรับการฝึก ชุดข้อมูลสำหรับการทดสอบจะรวมช่วงเวลาสองเดือนตั้งแต่วันที่ 1 พฤศจิกายนถึง 31 ธันวาคม 2014:
|
|
|
|
```python
|
|
train_start_dt = '2014-11-01 00:00:00'
|
|
test_start_dt = '2014-12-30 00:00:00'
|
|
```
|
|
|
|
เนื่องจากข้อมูลนี้สะท้อนการบริโภคพลังงานรายวัน มีรูปแบบตามฤดูกาลที่ชัดเจน แต่การบริโภคมีความคล้ายคลึงกับการบริโภคในวันล่าสุดมากที่สุด
|
|
|
|
1. สร้างกราฟเปรียบเทียบ:
|
|
|
|
```python
|
|
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()
|
|
```
|
|
|
|

|
|
|
|
ดังนั้น การใช้ช่วงเวลาที่ค่อนข้างเล็กสำหรับการฝึกข้อมูลควรเพียงพอ
|
|
|
|
> หมายเหตุ: เนื่องจากฟังก์ชันที่เราใช้ในการปรับโมเดล ARIMA ใช้การตรวจสอบภายในตัวอย่างระหว่างการปรับ เราจะละเว้นข้อมูลการตรวจสอบ
|
|
|
|
### เตรียมข้อมูลสำหรับการฝึก
|
|
|
|
ตอนนี้คุณต้องเตรียมข้อมูลสำหรับการฝึกโดยการกรองและปรับขนาดข้อมูล กรองชุดข้อมูลของคุณเพื่อรวมเฉพาะช่วงเวลาที่ต้องการและคอลัมน์ที่จำเป็น และปรับขนาดเพื่อให้แน่ใจว่าข้อมูลถูกฉายลงในช่วง 0,1
|
|
|
|
1. กรองชุดข้อมูลต้นฉบับเพื่อรวมเฉพาะช่วงเวลาที่กล่าวถึงต่อชุดและรวมเฉพาะคอลัมน์ 'load' และวันที่ที่จำเป็น:
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
คุณสามารถดูรูปร่างของข้อมูล:
|
|
|
|
```output
|
|
Training data shape: (1416, 1)
|
|
Test data shape: (48, 1)
|
|
```
|
|
|
|
1. ปรับขนาดข้อมูลให้อยู่ในช่วง (0, 1)
|
|
|
|
```python
|
|
scaler = MinMaxScaler()
|
|
train['load'] = scaler.fit_transform(train)
|
|
train.head(10)
|
|
```
|
|
|
|
1. สร้างกราฟเปรียบเทียบข้อมูลต้นฉบับกับข้อมูลที่ปรับขนาด:
|
|
|
|
```python
|
|
energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12)
|
|
train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12)
|
|
plt.show()
|
|
```
|
|
|
|

|
|
|
|
> ข้อมูลต้นฉบับ
|
|
|
|

|
|
|
|
> ข้อมูลที่ปรับขนาด
|
|
|
|
1. ตอนนี้คุณได้ปรับเทียบข้อมูลที่ปรับขนาดแล้ว คุณสามารถปรับขนาดข้อมูลสำหรับการทดสอบ:
|
|
|
|
```python
|
|
test['load'] = scaler.transform(test)
|
|
test.head()
|
|
```
|
|
|
|
### ใช้ ARIMA
|
|
|
|
ถึงเวลาที่จะใช้ ARIMA! ตอนนี้คุณจะใช้ไลบรารี `statsmodels` ที่คุณติดตั้งไว้ก่อนหน้านี้
|
|
|
|
ตอนนี้คุณต้องทำตามขั้นตอนหลายขั้นตอน
|
|
|
|
1. กำหนดโมเดลโดยเรียก `SARIMAX()` และส่งพารามิเตอร์ของโมเดล: พารามิเตอร์ p, d, และ q และพารามิเตอร์ P, D, และ Q
|
|
2. เตรียมโมเดลสำหรับข้อมูลการฝึกโดยเรียกฟังก์ชัน fit()
|
|
3. ทำการพยากรณ์โดยเรียกฟังก์ชัน `forecast()` และระบุจำนวนขั้นตอน (หรือ `horizon`) ที่ต้องการพยากรณ์
|
|
|
|
> 🎓 พารามิเตอร์เหล่านี้มีไว้เพื่ออะไร? ในโมเดล ARIMA มี 3 พารามิเตอร์ที่ใช้ช่วยสร้างแบบจำลองลักษณะสำคัญของอนุกรมเวลา: seasonality, trend, และ noise พารามิเตอร์เหล่านี้คือ:
|
|
|
|
`p`: พารามิเตอร์ที่เกี่ยวข้องกับลักษณะ auto-regressive ของโมเดล ซึ่งรวมค่าที่ผ่านมา
|
|
`d`: พารามิเตอร์ที่เกี่ยวข้องกับส่วน integrated ของโมเดล ซึ่งมีผลต่อจำนวน *differencing* (🎓 จำ differencing ได้ไหม 👆?) ที่จะใช้กับอนุกรมเวลา
|
|
`q`: พารามิเตอร์ที่เกี่ยวข้องกับส่วน moving-average ของโมเดล
|
|
|
|
> หมายเหตุ: หากข้อมูลของคุณมีลักษณะตามฤดูกาล - ซึ่งข้อมูลนี้มี - เราใช้โมเดล ARIMA ตามฤดูกาล (SARIMA) ในกรณีนี้คุณต้องใช้ชุดพารามิเตอร์อีกชุดหนึ่ง: `P`, `D`, และ `Q` ซึ่งอธิบายความสัมพันธ์เดียวกันกับ `p`, `d`, และ `q` แต่สอดคล้องกับส่วนตามฤดูกาลของโมเดล
|
|
|
|
1. เริ่มต้นโดยตั้งค่าค่าของ horizon ที่คุณต้องการ ลองใช้ 3 ชั่วโมง:
|
|
|
|
```python
|
|
# Specify the number of steps to forecast ahead
|
|
HORIZON = 3
|
|
print('Forecasting horizon:', HORIZON, 'hours')
|
|
```
|
|
|
|
การเลือกค่าที่ดีที่สุดสำหรับพารามิเตอร์ของโมเดล ARIMA อาจเป็นเรื่องท้าทายเนื่องจากเป็นเรื่องที่ค่อนข้างอัตวิสัยและใช้เวลามาก คุณอาจพิจารณาใช้ฟังก์ชัน `auto_arima()` จากไลบรารี [`pyramid`](https://alkaline-ml.com/pmdarima/0.9.0/modules/generated/pyramid.arima.auto_arima.html)
|
|
|
|
1. สำหรับตอนนี้ลองเลือกค่าด้วยตนเองเพื่อค้นหาโมเดลที่ดี
|
|
|
|
```python
|
|
order = (4, 1, 0)
|
|
seasonal_order = (1, 1, 0, 24)
|
|
|
|
model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order)
|
|
results = model.fit()
|
|
|
|
print(results.summary())
|
|
```
|
|
|
|
ตารางผลลัพธ์จะถูกพิมพ์ออกมา
|
|
|
|
คุณได้สร้างโมเดลแรกของคุณแล้ว! ตอนนี้เราต้องหาวิธีประเมินมัน
|
|
|
|
### ประเมินโมเดลของคุณ
|
|
|
|
เพื่อประเมินโมเดลของคุณ คุณสามารถใช้การตรวจสอบที่เรียกว่า `walk forward` validation ในทางปฏิบัติ โมเดลอนุกรมเวลาจะถูกฝึกใหม่ทุกครั้งที่มีข้อมูลใหม่เข้ามา สิ่งนี้ช่วยให้โมเดลสามารถทำการพยากรณ์ที่ดีที่สุดในแต่ละขั้นตอนเวลา
|
|
|
|
เริ่มต้นที่จุดเริ่มต้นของอนุกรมเวลาโดยใช้เทคนิคนี้ ฝึกโมเดลด้วยชุดข้อมูลสำหรับการฝึก จากนั้นทำการพยากรณ์ในขั้นตอนเวลาถัดไป การพยากรณ์จะถูกประเมินเทียบกับค่าที่ทราบ ชุดข้อมูลสำหรับการฝึกจะถูกขยายเพื่อรวมค่าที่ทราบและกระบวนการจะถูกทำซ้ำ
|
|
|
|
> หมายเหตุ: คุณควรรักษาหน้าต่างชุดข้อมูลสำหรับการฝึกให้คงที่เพื่อการฝึกที่มีประสิทธิภาพมากขึ้น เพื่อให้ทุกครั้งที่คุณเพิ่มการสังเกตใหม่ลงในชุดข้อมูลสำหรับการฝึก คุณจะลบการสังเกตจากจุดเริ่มต้นของชุดข้อมูล
|
|
|
|
กระบวนการนี้ให้การประมาณที่แข็งแกร่งขึ้นเกี่ยวกับวิธีที่โมเดลจะทำงานในทางปฏิบัติ อย่างไรก็ตาม มันมาพร้อมกับต้นทุนการคำนวณในการสร้างโมเดลจำนวนมาก สิ่งนี้เป็นที่ยอมรับได้หากข้อมูลมีขนาดเล็กหรือโมเดลมีความเรียบง่าย แต่สามารถเป็นปัญหาในระดับใหญ่
|
|
|
|
การตรวจสอบแบบ walk-forward เป็นมาตรฐานทองคำของการประเมินโมเดลอนุกรมเวลาและแนะนำสำหรับโครงการของคุณเอง
|
|
|
|
1. ก่อนอื่น สร้างจุดข้อมูลการทดสอบสำหรับแต่ละขั้นตอน HORIZON
|
|
|
|
```python
|
|
test_shifted = test.copy()
|
|
|
|
for t in range(1, HORIZON+1):
|
|
test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H')
|
|
|
|
test_shifted = test_shifted.dropna(how='any')
|
|
test_shifted.head(5)
|
|
```
|
|
|
|
| | | load | load+1 | load+2 |
|
|
| ---------- | -------- | ---- | ------ | ------ |
|
|
| 2014-12-30 | 00:00:00 | 0.33 | 0.29 | 0.27 |
|
|
| 2014-12-30 | 01:00:00 | 0.29 | 0.27 | 0.27 |
|
|
| 2014-12-30 | 02:00:00 | 0.27 | 0.27 | 0.30 |
|
|
| 2014-12-30 | 03:00:00 | 0.27 | 0.30 | 0.41 |
|
|
| 2014-12-30 | 04:00:00 | 0.30 | 0.41 | 0.57 |
|
|
|
|
ข้อมูลจะถูกเลื่อนในแนวนอนตามจุด horizon
|
|
|
|
1. ทำการพยากรณ์ในข้อมูลการทดสอบของคุณโดยใช้วิธี sliding window ในลูปที่มีขนาดเท่ากับความยาวของข้อมูลการทดสอบ:
|
|
|
|
```python
|
|
%%time
|
|
training_window = 720 # dedicate 30 days (720 hours) for training
|
|
|
|
train_ts = train['load']
|
|
test_ts = test_shifted
|
|
|
|
history = [x for x in train_ts]
|
|
history = history[(-training_window):]
|
|
|
|
predictions = list()
|
|
|
|
order = (2, 1, 0)
|
|
seasonal_order = (1, 1, 0, 24)
|
|
|
|
for t in range(test_ts.shape[0]):
|
|
model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order)
|
|
model_fit = model.fit()
|
|
yhat = model_fit.forecast(steps = HORIZON)
|
|
predictions.append(yhat)
|
|
obs = list(test_ts.iloc[t])
|
|
# move the training window
|
|
history.append(obs[0])
|
|
history.pop(0)
|
|
print(test_ts.index[t])
|
|
print(t+1, ': predicted =', yhat, 'expected =', obs)
|
|
```
|
|
|
|
คุณสามารถดูการฝึกที่เกิดขึ้น:
|
|
|
|
```output
|
|
2014-12-30 00:00:00
|
|
1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323]
|
|
|
|
2014-12-30 01:00:00
|
|
2 : predicted = [0.3 0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]
|
|
|
|
2014-12-30 02:00:00
|
|
3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
|
|
```
|
|
|
|
1. เปรียบเทียบการพยากรณ์กับโหลดจริง:
|
|
|
|
```python
|
|
eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)])
|
|
eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1]
|
|
eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
|
|
eval_df['actual'] = np.array(np.transpose(test_ts)).ravel()
|
|
eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
|
|
eval_df.head()
|
|
```
|
|
|
|
ผลลัพธ์
|
|
| | | timestamp | h | prediction | actual |
|
|
| --- | ---------- | --------- | --- | ---------- | -------- |
|
|
| 0 | 2014-12-30 | 00:00:00 | t+1 | 3,008.74 | 3,023.00 |
|
|
| 1 | 2014-12-30 | 01:00:00 | t+1 | 2,955.53 | 2,935.00 |
|
|
| 2 | 2014-12-30 | 02:00:00 | t+1 | 2,900.17 | 2,899.00 |
|
|
| 3 | 2014-12-30 | 03:00:00 | t+1 | 2,917.69 | 2,886.00 |
|
|
| 4 | 2014-12-30 | 04:00:00 | t+1 | 2,946.99 | 2,963.00 |
|
|
|
|
สังเกตการพยากรณ์ข้อมูลรายชั่วโมง เทียบกับโหลดจริง ความแม่นยำเป็นอย่างไร?
|
|
|
|
### ตรวจสอบความแม่นยำของโมเดล
|
|
|
|
ตรวจสอบความแม่นยำของโมเดลของคุณโดยทดสอบค่า mean absolute percentage error (MAPE) จากการพยากรณ์ทั้งหมด
|
|
> **🧮 แสดงคณิตศาสตร์**
|
|
>
|
|
> 
|
|
>
|
|
> [MAPE](https://www.linkedin.com/pulse/what-mape-mad-msd-time-series-allameh-statistics/) ใช้เพื่อแสดงความแม่นยำของการพยากรณ์ในรูปแบบอัตราส่วนที่กำหนดโดยสูตรด้านบน ความแตกต่างระหว่างค่าจริงและค่าที่พยากรณ์
|
|
ถูกหารด้วยค่าจริง
|
|
"ค่าที่เป็นบวกในสูตรนี้จะถูกนำมารวมกันสำหรับทุกจุดที่พยากรณ์ในช่วงเวลา และหารด้วยจำนวนจุดที่พอดี n" [wikipedia](https://wikipedia.org/wiki/Mean_absolute_percentage_error)
|
|
1. แสดงสมการในโค้ด:
|
|
|
|
```python
|
|
if(HORIZON > 1):
|
|
eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual']
|
|
print(eval_df.groupby('h')['APE'].mean())
|
|
```
|
|
|
|
1. คำนวณ MAPE ของการพยากรณ์หนึ่งขั้น:
|
|
|
|
```python
|
|
print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
|
|
```
|
|
|
|
MAPE ของการพยากรณ์หนึ่งขั้น: 0.5570581332313952 %
|
|
|
|
1. แสดงผล MAPE ของการพยากรณ์หลายขั้น:
|
|
|
|
```python
|
|
print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
|
|
```
|
|
|
|
```output
|
|
Multi-step forecast MAPE: 1.1460048657704118 %
|
|
```
|
|
|
|
ตัวเลขที่ต่ำถือว่าดี: พิจารณาว่าการพยากรณ์ที่มี MAPE เท่ากับ 10 หมายถึงค่าที่พยากรณ์ผิดไป 10%
|
|
|
|
1. แต่เช่นเคย การวัดความแม่นยำแบบนี้จะเห็นได้ง่ายขึ้นเมื่อดูภาพ ดังนั้นมาลองพล็อตกราฟกัน:
|
|
|
|
```python
|
|
if(HORIZON == 1):
|
|
## Plotting single step forecast
|
|
eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8))
|
|
|
|
else:
|
|
## Plotting multi step forecast
|
|
plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']]
|
|
for t in range(1, HORIZON+1):
|
|
plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values
|
|
|
|
fig = plt.figure(figsize=(15, 8))
|
|
ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0)
|
|
ax = fig.add_subplot(111)
|
|
for t in range(1, HORIZON+1):
|
|
x = plot_df['timestamp'][(t-1):]
|
|
y = plot_df['t+'+str(t)][0:len(x)]
|
|
ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t))
|
|
|
|
ax.legend(loc='best')
|
|
|
|
plt.xlabel('timestamp', fontsize=12)
|
|
plt.ylabel('load', fontsize=12)
|
|
plt.show()
|
|
```
|
|
|
|

|
|
|
|
🏆 กราฟที่ดูดีมาก แสดงให้เห็นว่าโมเดลมีความแม่นยำสูง ยอดเยี่ยมมาก!
|
|
|
|
---
|
|
|
|
## 🚀ความท้าทาย
|
|
|
|
สำรวจวิธีการทดสอบความแม่นยำของโมเดลซีรีส์เวลา ในบทเรียนนี้เราได้พูดถึง MAPE แต่มีวิธีอื่นที่คุณสามารถใช้ได้หรือไม่? ลองค้นคว้าและอธิบายเพิ่มเติม เอกสารที่เป็นประโยชน์สามารถดูได้ [ที่นี่](https://otexts.com/fpp2/accuracy.html)
|
|
|
|
## [แบบทดสอบหลังบทเรียน](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
## ทบทวนและศึกษาด้วยตัวเอง
|
|
|
|
บทเรียนนี้ครอบคลุมเพียงพื้นฐานของการพยากรณ์ซีรีส์เวลาด้วย ARIMA ใช้เวลาเพิ่มเติมเพื่อเพิ่มพูนความรู้ของคุณโดยสำรวจ [repository นี้](https://microsoft.github.io/forecasting/) และโมเดลประเภทต่าง ๆ เพื่อเรียนรู้วิธีอื่น ๆ ในการสร้างโมเดลซีรีส์เวลา
|
|
|
|
## งานที่ได้รับมอบหมาย
|
|
|
|
[โมเดล ARIMA ใหม่](assignment.md)
|
|
|
|
---
|
|
|
|
**ข้อจำกัดความรับผิดชอบ**:
|
|
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามอย่างเต็มที่เพื่อให้การแปลมีความถูกต้อง โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาต้นทางควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษามนุษย์มืออาชีพ เราจะไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดซึ่งเกิดจากการใช้การแปลนี้ |