<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BiozW</title>
    <description>The latest articles on DEV Community by BiozW (@biozw).</description>
    <link>https://dev.to/biozw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1426512%2F431251b6-24ab-45e3-8755-4448d91d74ec.jpeg</url>
      <title>DEV Community: BiozW</title>
      <link>https://dev.to/biozw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/biozw"/>
    <language>en</language>
    <item>
      <title>ทำนายการขายไข่ด้วย SARIMA</title>
      <dc:creator>BiozW</dc:creator>
      <pubDate>Tue, 16 Apr 2024 13:48:19 +0000</pubDate>
      <link>https://dev.to/biozw/thamnaaykaarkhaayaikhdwy-sarima-1lmj</link>
      <guid>https://dev.to/biozw/thamnaaykaarkhaayaikhdwy-sarima-1lmj</guid>
      <description>&lt;p&gt;หากเรามีข้อมูลที่เก็บซ้ำๆ ต่อเนื่องกันเป็นเวลานาน แล้วต้องการคาดเดาว่าในอนาคตจะมีแนวโน้มเป็นอย่างไร สิ่งที่สามารถทำนายได้คือ SARIMA&lt;/p&gt;

&lt;h2&gt;
  
  
  SARIMA คืออะไร
&lt;/h2&gt;

&lt;p&gt;SARIMA นั้นเป็นส่วนขยายมาจาก ARIMA &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AR - Autoregressive : จำนวนครั้งที่ข้อมูลในช่วงเวลาก่อนหน้าถูกใช้เป็นตัวแปรอิสระในการคำนวณค่าในช่วงเวลาปัจจุบัน&lt;/li&gt;
&lt;li&gt;I  - Integrated     : ทำให้ข้อมูลมีลักษณะคงที่&lt;/li&gt;
&lt;li&gt;MA - Moving Average : จำนวนครั้งที่ค่าเฉลี่ยของข้อมูลในช่วงเวลาก่อนหน้าถูกใช้ในการคำนวณค่าในช่วงเวลาปัจจุบัน&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;โดยมีการใช้พารามิเตอร์ p, d, และ q เพื่อกำหนดโครงสร้างของโมเดล ARIMA ที่เหมาะสมกับชุดข้อมูลที่กำลังวิเคราะห์&lt;/p&gt;

&lt;p&gt;เหมาะสำหรับการจัดการกับข้อมูลชุดเวลาที่มีแนวโน้มหรือลักษณะซ้ำซาก&lt;br&gt;
การทำ ARIMA มักนิยมใช้ในงานทางการเงิน การวิเคราะห์ภาวะเศรษฐกิจ หรือการทำนายภัยพิบัติทางธรรมชาติ ที่มีข้อมูลบันทึกไว้ซ้ำๆ ตลอดก่อนหน้า&lt;/p&gt;

&lt;p&gt;ส่วนที่เพิ่มเข้ามา คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S - Seasonal : ช่วงฤดูกาล
มีการใช้พารามิเตอร์ s เพิ่มเข้าไป&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;นั่นคือการคำนึงถึงช่วงเวลาฤดูกาลเข้าไปใน ARIMA กลายเป็น SARIMA นั่นเอง&lt;/p&gt;
&lt;h2&gt;
  
  
  ขั้นตอน
&lt;/h2&gt;

&lt;p&gt;อธิบายคร่าวๆ ถึงการทำ SARIMA&lt;/p&gt;
&lt;h2&gt;
  
  
  นำเข้า Libraries
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  นำเข้าชุดข้อมูล (Dataset)
&lt;/h2&gt;

&lt;p&gt;โดยชุดข้อมูลที่ใช้คือ Egg Sales of a local shop for 30 years&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;df = pd.read_csv('/content/train_egg_sales.csv', sep=';')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เนื่องจากชุดข้อมูลที่นำมาใช้นั้นมีข้อมูลรวมกันอยู่ จำเป็นต้องใช้ &lt;code&gt;sep=';'&lt;/code&gt;&lt;br&gt;
หากชุดข้อมูลอื่นแยกมาอยู่แล้ว ก็ไม่จำเป็น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในขั้นตอนนี้ สามารถดูข้อมูลที่นำเข้ามาเพื่อตรวจสอบความถูกต้องของจำนวนข้อมูล&lt;br&gt;
 ด้วย&lt;code&gt;df.info()&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15jb2mbwvjyrdvjkvnw7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15jb2mbwvjyrdvjkvnw7.png" alt="Image description" width="653" height="300"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  รวมช่วงเวลา
&lt;/h2&gt;

&lt;p&gt;จากข้อมูลที่เป็นต่อวัน รวมกันให้เป็นต่อเดือน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;df1 = sales_data.set_index('Date')

monthly_sales = df1.resample('M').mean()
monthly_sales.head()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  แสดงกราฟยอดขายแต่ละเดือน
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เมื่อดูผลกราฟแล้ว จะเห็นว่าเส้นมีการขึ้นลงที่รูปแบบซ้ำใกล้เคียงกัน&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o4tqs25p94z15zdyjsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o4tqs25p94z15zdyjsi.png" alt="Image description" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ตรวจสอบความคงที่
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 &amp;lt; 0.05 else 'Non-Stationary')

check_stationarity(monthly_sales['Egg Sales'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;ซึ่งการตรวจสอบที่ออกมานั้นเป็น Non-Stationary ซึ่งแสดงว่าข้อมูลนี้ไม่มีความคงที่&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbra2l2k4kcwla8xxjro8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbra2l2k4kcwla8xxjro8.png" alt="Image description" width="534" height="116"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  หาพารามิเตอร์ของโมเดล
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Plot ACF and PACF
plot_acf(monthly_sales)
plot_pacf(monthly_sales)
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;ACF กับ PACF&lt;/strong&gt; คืออะไร&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ACF - Autocorrelation Function &lt;br&gt;
วัดความสัมพันธ์ระหว่างจุดข้อมูลและจุดข้อมูลก่อนหน้าโดยมีความล่าช้าต่างกัน&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PACF - Partial Autocorrelation Function &lt;br&gt;
ความสัมพันธ์ระหว่างจุดข้อมูลและความล่าช้า&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhhtibzmkemaj1wjn0sm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhhtibzmkemaj1wjn0sm.png" alt="Image description" width="800" height="1228"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  สร้าง Model
&lt;/h2&gt;

&lt;p&gt;กำหนดให้ p d q และ P D Q เป็น 1&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ค่าเปลี่ยนแปลงไปตาม ACF และ PACF
กำหนด s ตามจำนวนเดือน
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 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())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  ลองทำนาย
&lt;/h2&gt;

&lt;p&gt;โดยลองทำนายว่า 3 ปีต่อไปจะเป็นแบบไหน โดยใส่ค่า &lt;code&gt;forecast_periods = 36&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 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()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7cc9k8gk0aqxjpinpd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7cc9k8gk0aqxjpinpd3.png" alt="Image description" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  วัดประสิทธิภาพของโมเดล
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MAE (Mean Absolute Error) คือค่าเฉลี่ยของความต่างระหว่างค่าที่ทำนายและค่าจริง&lt;/li&gt;
&lt;li&gt;MSE (Mean Squared Error) คือค่าเฉลี่ยของความต่างระหว่างค่าที่ทำนายและค่าจริง โดยยกกำลังสองของความต่างแต่ละค่า
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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}')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ค่า MAE และ MSE มีค่าค่อนข้างมาก ซึ่งอาจไม่แม่นยำต่อความเป็นจริง &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0s5d1p86bv09ydt3qq62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0s5d1p86bv09ydt3qq62.png" alt="Image description" width="372" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;การทำนายด้วย SARIMA นั้นแสดงค่าของการขายไข่ที่เพิ่มขึ้นในอีก 3 ปี&lt;/p&gt;

&lt;p&gt;แต่อย่างไรก็ตาม ชุดข้อมูลที่ใช้นี้เป็น Non-Stationary หรือไม่คงที่&lt;br&gt;
ทำให้เกิดการคาดเคลื่อนค่อนข้างมาก ซึ่งสามารถหาชุดข้อมูลอื่นที่เมื่อตรวจสอบเป็น Stationary จะให้ความแม่นยำมากกว่า หรือการแปลง Non-Stationary เป็น Stationary จากอ้างอิงได้&lt;/p&gt;

&lt;h2&gt;
  
  
  อ้างอิง
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ข้อมูลที่เกี่ยวข้อง&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/sarima-seasonal-autoregressive-integrated-moving-average/"&gt;https://www.geeksforgeeks.org/sarima-seasonal-autoregressive-integrated-moving-average/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kaggle.com/code/shubhammisar/air-passenger-data-forecasting-sarima/notebook"&gt;https://www.kaggle.com/code/shubhammisar/air-passenger-data-forecasting-sarima/notebook&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kaggle.com/code/tanmay111999/air-passenger-forecast-arima-sarima/notebook"&gt;https://www.kaggle.com/code/tanmay111999/air-passenger-forecast-arima-sarima/notebook&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ชุดข้อมูล&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/datasets/kanchana1990/egg-sales-of-a-local-shop-for-30-years/data"&gt;https://www.kaggle.com/datasets/kanchana1990/egg-sales-of-a-local-shop-for-30-years/data&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
