หากเรามีข้อมูลที่เก็บซ้ำๆ ต่อเนื่องกันเป็นเวลานาน แล้วต้องการคาดเดาว่าในอนาคตจะมีแนวโน้มเป็นอย่างไร สิ่งที่สามารถทำนายได้คือ SARIMA
SARIMA คืออะไร
SARIMA นั้นเป็นส่วนขยายมาจาก ARIMA
- AR - Autoregressive : จำนวนครั้งที่ข้อมูลในช่วงเวลาก่อนหน้าถูกใช้เป็นตัวแปรอิสระในการคำนวณค่าในช่วงเวลาปัจจุบัน
- I - Integrated : ทำให้ข้อมูลมีลักษณะคงที่
- MA - Moving Average : จำนวนครั้งที่ค่าเฉลี่ยของข้อมูลในช่วงเวลาก่อนหน้าถูกใช้ในการคำนวณค่าในช่วงเวลาปัจจุบัน
โดยมีการใช้พารามิเตอร์ p, d, และ q เพื่อกำหนดโครงสร้างของโมเดล ARIMA ที่เหมาะสมกับชุดข้อมูลที่กำลังวิเคราะห์
เหมาะสำหรับการจัดการกับข้อมูลชุดเวลาที่มีแนวโน้มหรือลักษณะซ้ำซาก
การทำ ARIMA มักนิยมใช้ในงานทางการเงิน การวิเคราะห์ภาวะเศรษฐกิจ หรือการทำนายภัยพิบัติทางธรรมชาติ ที่มีข้อมูลบันทึกไว้ซ้ำๆ ตลอดก่อนหน้า
ส่วนที่เพิ่มเข้ามา คือ
- S - Seasonal : ช่วงฤดูกาล มีการใช้พารามิเตอร์ s เพิ่มเข้าไป
นั่นคือการคำนึงถึงช่วงเวลาฤดูกาลเข้าไปใน ARIMA กลายเป็น SARIMA นั่นเอง
ขั้นตอน
อธิบายคร่าวๆ ถึงการทำ SARIMA
นำเข้า Libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from sklearn.metrics import mean_absolute_error, mean_squared_error
นำเข้าชุดข้อมูล (Dataset)
โดยชุดข้อมูลที่ใช้คือ Egg Sales of a local shop for 30 years
df = pd.read_csv('/content/train_egg_sales.csv', sep=';')
เนื่องจากชุดข้อมูลที่นำมาใช้นั้นมีข้อมูลรวมกันอยู่ จำเป็นต้องใช้ sep=';'
หากชุดข้อมูลอื่นแยกมาอยู่แล้ว ก็ไม่จำเป็น
sales_data=df[['Date','Egg Sales']]
sales_data=pd.DataFrame(sales_data)
sales_data['Date'] = pd.to_datetime(sales_data['Date'], errors='coerce')
df.head()
ในขั้นตอนนี้ สามารถดูข้อมูลที่นำเข้ามาเพื่อตรวจสอบความถูกต้องของจำนวนข้อมูล
ด้วยdf.info()
รวมช่วงเวลา
จากข้อมูลที่เป็นต่อวัน รวมกันให้เป็นต่อเดือน
df1 = sales_data.set_index('Date')
monthly_sales = df1.resample('M').mean()
monthly_sales.head()
แสดงกราฟยอดขายแต่ละเดือน
plt.figure(figsize=(12, 6))
plt.plot(monthly_sales['Egg Sales'], linewidth=1, c='cyan')
plt.title("Monthly sales")
plt.xlabel("Date")
plt.ylabel("Egg Sales")
plt.show()
เมื่อดูผลกราฟแล้ว จะเห็นว่าเส้นมีการขึ้นลงที่รูปแบบซ้ำใกล้เคียงกัน
ตรวจสอบความคงที่
def check_stationarity(timeseries):
# Perform the Dickey-Fuller test
result = adfuller(timeseries, autolag='AIC')
p_value = result[1]
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {p_value}')
print('Stationary' if p_value < 0.05 else 'Non-Stationary')
check_stationarity(monthly_sales['Egg Sales'])
ซึ่งการตรวจสอบที่ออกมานั้นเป็น Non-Stationary ซึ่งแสดงว่าข้อมูลนี้ไม่มีความคงที่
หาพารามิเตอร์ของโมเดล
# Plot ACF and PACF
plot_acf(monthly_sales)
plot_pacf(monthly_sales)
plt.show()
ACF กับ PACF คืออะไร
ACF - Autocorrelation Function
วัดความสัมพันธ์ระหว่างจุดข้อมูลและจุดข้อมูลก่อนหน้าโดยมีความล่าช้าต่างกันPACF - Partial Autocorrelation Function
ความสัมพันธ์ระหว่างจุดข้อมูลและความล่าช้า
สร้าง Model
กำหนดให้ p d q และ P D Q เป็น 1
- ค่าเปลี่ยนแปลงไปตาม ACF และ PACF กำหนด s ตามจำนวนเดือน
# Define SARIMA parameters
p, d, q = 1, 1, 1
P, D, Q, s = 1, 1, 1, 12 # Assuming monthly seasonality
# Fit the SARIMA model
model = SARIMAX(monthly_sales, order=(p, d, q), seasonal_order=(P, D, Q, s))
results = model.fit()
model
print(results.summary())
ลองทำนาย
โดยลองทำนายว่า 3 ปีต่อไปจะเป็นแบบไหน โดยใส่ค่า forecast_periods = 36
# Forecast future values
forecast_periods = 36 # Forecast the next 36 months
forecast = results.get_forecast(steps=forecast_periods)
forecast_mean = forecast.predicted_mean
forecast_ci = forecast.conf_int()
# Plot the forecast
plt.figure(figsize=(12, 6))
plt.plot(monthly_sales, label='Observed')
plt.plot(forecast_mean, label='Forecast', color='red')
plt.fill_between(forecast_ci.index, forecast_ci.iloc[:, 0], forecast_ci.iloc[:, 1], color='pink')
plt.title("Sales Forecast")
plt.xlabel("Date")
plt.ylabel("Sales")
plt.legend()
plt.show()
วัดประสิทธิภาพของโมเดล
- MAE (Mean Absolute Error) คือค่าเฉลี่ยของความต่างระหว่างค่าที่ทำนายและค่าจริง
- MSE (Mean Squared Error) คือค่าเฉลี่ยของความต่างระหว่างค่าที่ทำนายและค่าจริง โดยยกกำลังสองของความต่างแต่ละค่า
observed = monthly_sales[-forecast_periods:]
mae = mean_absolute_error(observed, forecast_mean)
mse = mean_squared_error(observed, forecast_mean)
print(f'MAE: {mae}')
print(f'MSE: {mse}')
ค่า MAE และ MSE มีค่าค่อนข้างมาก ซึ่งอาจไม่แม่นยำต่อความเป็นจริง
สรุป
การทำนายด้วย SARIMA นั้นแสดงค่าของการขายไข่ที่เพิ่มขึ้นในอีก 3 ปี
แต่อย่างไรก็ตาม ชุดข้อมูลที่ใช้นี้เป็น Non-Stationary หรือไม่คงที่
ทำให้เกิดการคาดเคลื่อนค่อนข้างมาก ซึ่งสามารถหาชุดข้อมูลอื่นที่เมื่อตรวจสอบเป็น Stationary จะให้ความแม่นยำมากกว่า หรือการแปลง Non-Stationary เป็น Stationary จากอ้างอิงได้
อ้างอิง
- ข้อมูลที่เกี่ยวข้อง
https://www.geeksforgeeks.org/sarima-seasonal-autoregressive-integrated-moving-average/
https://www.kaggle.com/code/shubhammisar/air-passenger-data-forecasting-sarima/notebook
https://www.kaggle.com/code/tanmay111999/air-passenger-forecast-arima-sarima/notebook
- ชุดข้อมูล
https://www.kaggle.com/datasets/kanchana1990/egg-sales-of-a-local-shop-for-30-years/data
Top comments (0)