ทความนี้เราจะมาว่ากันต่อในเรื่องของการทำนายข้อมูล Time Series ด้วย ARIMA กันค่ะ โดยบทความนี้เป็นบทความที่ 3 ของบทความชุด “ARIMA เท่าที่เข้าใจ” ซึ่งได้เขียนไปแล้ว 2 ตอนด้วยกัน สามารถอ่านได้ตามลิงก์ด้านล่าง เมื่ออ่านครบทั้ง 3 บทความนี้ ก็น่าจะสามารถนำ ARIMA ไปประยุกต์ใช้ในการทำนายข้อมูลประเภทต่างๆ ได้อย่างไม่ยากแล้วค่ะ

บทความชุด “ARIMA เท่าที่เข้าใจ”

1) ARIMA เท่าที่เข้าใจ อธิบายการทำงานของ ARIMA model จากประสบการณ์ใช้งานของเรา

https://algoaddict.com/blog/54520/arima

2) ตัวอย่างการใช้ ARIMA ในการทำนายค่า GDP ของประเทศไทย พร้อม source code ตอนที่ 1

https://algoaddict.com/blog/54547/arima_th_gdp_1

ต่อกันเลยนะคะ หลังจากบทความที่แล้ว เราได้เตรียมข้อมูลที่เป็น “Stationary” ไว้เรียบร้อย พร้อมสำหรับ “การทำนาย” แล้ว ในบทความนี้ เราจะนำเอาข้อมูลนั้นมาเริ่มทำการทำนาย โดยใช้ ARIMA model โดยจะเริ่มจากขั้นตอนที่ 4 กำหนดค่าตัวแปร p และ q กันก่อนเลยค่ะ (ขั้นตอนที่ 1-3 สามารถอ่านได้จากบทความก่อนหน้า)

4) กำหนดค่าตัวแปร p และ q

ขั้นตอนนี้ เราจะมาหาค่า p และ q ที่เหมาะสมสำหรับ AR (Auto-Regressive) และ MA (Moving Average) ตามลำดับ หวังว่าคงจะยังไม่ลืมกันนะคะว่า AR model และ MA model นี้เป็นโมเดลที่จะนำมา Integreate กันเป็น ARIMA model ในภายหลัง ซึ่งเราจะหาค่า p, q นี้โดยการพล็อตกราฟ ACF และ PACF ค่ะ ก่อนจะเริ่มกัน มาทำความรู้จัก ACF กับ PACF คร่าวๆ กันก่อนค่ะ

4.1) ACF (Autocorrelation Function)

วัดความสัมพันธ์ Correlation ระหว่างข้อมูล Time series และ ข้อมูล lagged ของตัวมันเอง

4.2) PACF (Partial Autocorrelation Function

วัดความสัมพันธ์ Correlation ระหว่างข้อมูล Time series และ ข้อมูล lagged ของตัวมันเอง แต่จะไม่พิจารณาผลกระทบที่ได้พิจารณาไปแล้ว เช่น การหาค่า Correlation ของ lag n ก็จะไม่นำค่า correlatioin ของ lag n ถึง n-1 มารวมด้วย

การหาค่า ACF และ PACF ด้วย Python สามารถทำได้ง่ายมากๆ เนื่องจาก Python ได้มีการเตรียม library ของคำสั่งไว้ให้เราเรียบร้อยแล้วใน Statsmodes library มาลอง import ไลบรารี่นี้กันค่ะ


from statsmodels.tsa.stattools import acf, pacf

thAcf = acf(thGDP_log_diff, nlags=20)
thPacf = pacf(thGDP_log_diff, nlags=20, method='ols')


พล็อตดูหน้าตาของกราฟกัน

ACF

plt.plot(thAcf, color = ‘red’, label = ‘ACF of Thai GDP’)

plt.axhline(y=0,color=’gray’)

plt.axhline(y=-1.96/np.sqrt(len(thGDP_log_diff)), linestyle=’–‘, color=’blue’)

plt.axhline(y=1.96/np.sqrt(len(thGDP_log_diff)), linestyle=’–‘, color=’blue’)

plt.legend(loc = ‘best’)

plt.title(‘ACF’)

PACF

plt.plot(thPacf, color = ‘red’, label = ‘PACF of Thai GDP’)

plt.axhline(y=0,color=’gray’)

plt.axhline(y=-1.96/np.sqrt(len(thGDP_log_diff)), linestyle=’–‘, color=’blue’)

plt.axhline(y=1.96/np.sqrt(len(thGDP_log_diff)), linestyle=’–‘, color=’blue’)

plt.legend(loc = ‘best’)

plt.title(‘PACF’)

หนึ่งในวิธีการหาค่า p และ q สามารถทำได้โดยการหาค่า จุดตัดที่กราฟ PACF และ ACF (กราฟเส้นสีแดง) ตัดเส้น Upper Confidence (เส้นสีน้ำเงิน) เป็นครั้งแรก ซึ่งก็คือ จุดที่วงกลมไว้ในรูปทั้งสองด้านบนนั่นเอง ในที่นี้ เราได้เขียนฟังก์ชันเพื่อหาค่าตำแหน่ง ณ จุดนั้น ดังนี้

กำหนดค่า จุดตัด ซึ่งก็คือ ค่า Lower Confidence

cut_point = 1.96/np.sqrt(len(thGDP_log_diff))

หาค่า p จากจุดตัดของกราฟ PACF

p = 0;

idxP = 0;

for j in range(0, len(thPacf)):

if thPacf[j] < cut_point:

p = thPacf[j]

idxP = j

break

print(“p = “, idxP)

หาค่า q จากจุดตัดของกราฟ ACF

q = 0;

idxQ = 0;

for i in range(0, len(thAcf)):

if thAcf[i] < cut_point:

q = thAcf[i]

idxQ = i

break

print(“q = “, idxQ)

มาดูผลลัพธ์ค่า p และ q ที่ได้

เมื่อเราสั่ง print จะเห็นว่าค่า p และ q ที่ได้จากกราฟ ACF และ PACF จะเท่ากับ 2 และ 2 ตามลำดับ ต่อมาเราจะมาเริ่มต้นการทำนายค่าของ time series กันค่ะ ซึ่งก็จะประกอบด้วย 3 ขั้นตอนด้วยกัน ตามที่ได้กล่าวไว้ในบทความ “ARIMA เท่าที่เข้าใจ”

5) ทำนายค่า Time Series ด้วย AR Model

เริ่มด้วยการ import library ที่จำเป็นสำหรับ AR, MA และ ARIMA model

from statsmodels.tsa.arima_model import ARIMA

ทำนายด้วย AR model (set q = 0)

model1 = ARIMA(thGDP_log, order=(idxP, 1, 0))

results_AR = model1.fit(disp=-1)

plt.plot(thGDP_log_diff, color = ‘blue’, label = ‘actual data’)

plt.plot(results_AR.fittedvalues, color=’red’, label = ‘predicted data’)

plt.legend(loc = ‘best’)

plt.title(‘RSS: %f’% np.sum((results_AR.fittedvalues-thGDP_log_diff)**2))

ผลลัพธ์ที่ได้จะเป็นค่าที่ทำนายจาก AR model (เส้นสีแดง) เทียบกับข้อมูลจริง (เส้นสีน้ำเงิน)

จากรูป กราฟสีน้ำเงิน คือค่า logarithm ของ thGDP และ กราฟสีแดงคือค่าที่ได้จากการใช้ AR model ทำนาย เป็นยังไงบ้างคะ ส่วนใหญ่ก็ทำนายแนวโน้วขึ้นลงของข้อมูลค่อนข้างดี แต่ก็จะมีจุดที่ผิดทิศไปเลยอยู่บ้างเหมือนกัน ตามที่วงกลมไว้นะคะ แต่ทั้งนี้ทั้งนั้น การจะเปรียบเทียบว่าโมเดลไหนทำนายได้ดีแค่ไหนนั้น มองด้วยสวยตาอาจจะยาก เรามาดูค่าตัวเลขกันดีกว่าค่ะ ค่าที่เราจะพิจารณาในที่นี้คือค่า Residual (RSS) หรือ ค่าที่ได้จากการที่เหลือจากการทำการตัด trend กับ seasonality ออกไปจากข้อมูลแล้ว ค่านี้ยิ่งน้อยยิ่งดี ในที่นี้เราได้ RSS = 0.382125 เดี๋ยวเราจะนำมันไปเปรียบเทียบกับโมเดลอื่นกันค่ะ

6) ทำนายค่า Time Series ด้วย MA Model

ในที่นี้ เราไม่จำเป็นต้อง import library ใหม่แล้ว เนื่องจากเราจะใช้โมเดล ARIMA ตัวเดิมกับ AR model มาดูคำสั่งกัน

ทำนายด้วย AR model (set q = 0)

model2 = ARIMA(thGDP_log, order=(0, 1, idxQ))

results_MA = model2.fit(disp=-1)

plt.plot(thGDP_log_diff, color = ‘blue’, label = ‘actual data’)

plt.plot(results_MA.fittedvalues, color=’red’, label = ‘predicted data’)

plt.legend(loc = ‘best’)

plt.title(‘RSS: %f’% np.sum((results_MA.fittedvalues-thGDP_log_diff)**2))


ผลลัพธ์ที่ได้จะเป็นค่าที่ทำนายจาก MA model (เส้นสีแดง) เทียบกับข้อมูลจริง (เส้นสีน้ำเงิน)

ถ้าจะให้เปรียบเทียบด้วยตาเปล่าว่า ระหว่าง AR model และ MA model โมเดลไหนทำนายได้ดีกว่า ก็ออกจะดูยากไปซักนิด ดังนั้น เราก็ต้องมาดูกันที่ค่า RSS กันอีกแล้วค่ะ ซึ่งในที่นี้ค่า RSS =0.372505 ซึ่งน้อยกว่าค่า RSS ของ AR model ข้างต้น นั่นก็หมายความว่า MA model ทำนายข้อมูลนี้ได้ดีกว่า AR model นั่นเองค่ะ

ขั้นตอนต่อไป เราทำการ integrate model 2 ตัวนี้เข้าด้วยกัน เป็น ARIMA model อย่างที่ได้กล่าวไปแล้วในบทความแรกเรื่อง “ARIMA เท่าที่เข้าใจ”


7) ทำนายค่า Time Series ด้วย ARIMA Model

ในที่นี้เราจะนำ AR model และ MA model มา Integrate กันค่ะ ซึ่งในที่นี้ ค่า p และ q ก็จะถูกกำหนดให้เป็นค่า 2 ที่ได้จากการหาจุดตัดกราฟในขั้นตอนที่ 4 นั่นเองค่ะ มาดูโค้ดกัน

model3 = ARIMA(thGDP_log, order=(idxP, 1, idxQ))

results_ARIMA = model3.fit(disp=-1)

plt.plot(thGDP_log_diff, color = ‘blue’, label = ‘actual data’)

plt.plot(results_ARIMA.fittedvalues, color=’red’, label = ‘predicted data’)

plt.title(‘RSS: %f’% np.sum((results_ARIMA.fittedvalues-thGDP_log_diff)**2))

ผลลัพธ์ที่ได้จากการใช้ ARIMA ทำนายข้อมูล (เส้นสีแดง) เทียบกับข้อมูลจริง (เส้นสีน้ำเงิน)

จะเห็นว่าค่า RSS = 0.371102 ซึ่งน้อยกว่า AR model และ MA model นั่นก็หมายความว่าเมื่อนำโมเดล 2 โมเดลด้านบนมารวมกันเป็น ARIMA model จะทำให้การทำนายค่าทำได้ดีที่สุด ดังนั้น เราก็จะเลือกโมเดล ARIMA ในการทำนาย ขั้นตอนต่อไปก็คือ แปลงค่าผลลัพธ์นี้กลับเป็นค่าจริงๆ ของข้อมูล เนื่องจากในขั้นตอนการทำนาย เราไม่ได้ทำนายจากข้อมูลดิบ จำกันได้มั้ยคะ? ก่อนทำการทำนาย เราได้ปรับข้อมูลให้เป็น stationary ก่อน ด้วยการทำ logarithm และ differencing ขึ้นตอนสุดท้ายเราจึงต้องปรับข้อมูลกลับไปใน scale ของข้อมูลดิบค่ะ

มาย้อนดูข้อมูลดิบกันก่อนค่ะ


เห็นแล้วนะคะ ว่าข้อมูลดิบมี scale และ ลักษณะแนวโน้มข้อมูลต่างกับข้อมูลที่ได้จาก ARIMA อย่างเห็นได้ชัด เหตุผลก็เพราะว่าเราได้ปรับข้อมูลมาแล้ว (ในบทความที่แล้ว) ในส่วนนี้เราต้องทำการปรับกลับ เพื่อเอาข้อมูลที่ได้จากการทำนายโดย ARIMA มาผนวกเข้ากับข้อมูลดิบค่ะ มาดูกันเลย

8) ปรับข้อมูลทำนายกลับไปสู่สเกลเดิมของข้อมูล

prediction_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True)

prediction_ARIMA_diff_cumsum = prediction_ARIMA_diff.cumsum()

prediction_ARIMA_log = pd.Series(thGDP_log.ix[0], index=thGDP_log.index)

prediction_ARIMA_log = prediction_ARIMA_log.add(prediction_ARIMA_diff_cumsum,fill_value=0)

prediction_ARIMA = np.exp(prediction_ARIMA_log)

จากคำสั่งด้านบน เราได้ทำการหาค่า cummulative sum ของ ค่าที่ทำนายได้จาก ARIMA ซึ่งถือเป็นค่าที่ ARIMA ทำนายว่าค่าของข้อมูลแต่ละจุดจะเปลี่ยนแปลงไปแค่ไหน ต่อมาเราก็จะนำค่านั้นมาบวกเข้ากับข้อมูลดิบ (จะเป็นการทำค่าการเปลี่ยนแปลงที่ทำนายได้ ไปปรับกับข้อมูลจริงๆ) และ เก็บไว้ในตัวแปร prediction_ARIMA มาลองพล็อตกราฟเปรียบเทียบค่าจริงกับค่าที่ได้จากการทำนายด้วย ARIMA กันค่ะ

โค้ดพล็อตข้อมูลข้อมูลดิบ เปรียบเทียบกับค่าที่ใช้ ARIMA model ทำนาย

plt.plot(thGDP, color = ‘green’, label = ‘actual data’)

plt.plot(prediction_ARIMA, color = ‘red’, label = ‘ARIMA \’ predicted data’)

plt.legend(loc = ‘best’)

ผลลัพธ์


จะเห็นว่า ARIMA model สามารถทำนายค่าได้ค่อนข้างใกล้เคียงกับค่าจริง และ สามารถจับแนวโน้มของข้อมูลได้ ด้วยการทำนายทิศทางข้อมูลได้ดีพอสมควร แต่อย่างไรก็ตามข้อมูล GDP เป็นข้อมูลที่มีความผันผวนค่อนข้างต่ำ ถ้าเปลี่ยนเป็นทำนายข้อมูลหุ้นล่ะ? ผลลัพธ์ที่ได้จะเป็นอย่างไร? ผู้เขียนขออนุญาติไม่ทดลองให้ดูนะคะ เพราะคิดว่าบทความทั้ง 3 บทความที่ได้เขียนมา ได้ให้รายละเอียด พร้อมวิธีทำไว้ชัดเจนแล้ว ก็ขอให้ไปลองทำกันดูเองแล้วกันค่ะ ได้ผลลัพธ์อย่างไรก็อย่างลืมมาบอกเล่ากันบ้างนะคะ

หวังว่าบทความชุดนี้ จะเป็นประโยชน์แก่ผู้สนใจ ไม่มากก็น้อย และ ก็ขอขอบคุณเป็นอย่างสูงค่ะที่ติดตามอ่านกัน ก่อนจบบทความนี้ ผู้เขียนก็จะขอสรุปลำดับบทความชุดนี้ให้ คิดว่าถ้าอ่านจบทั้งสามบทความที่ได้เขียนไว้ให้ ซึ่งประกอบไปด้วย ทั้งทฤษฏี และ ปฏิบัติ ทุกท่านก็น่าจะสามารถประยุกต์ใช้ ARIMA model ในการทำงานข้อมูลที่ต้องการกันได้แล้วค่ะ

รวมลิงก์ บทความชุด “ARIMA เท่าที่เข้าใจ”

1) ARIMA เท่าที่เข้าใจ อธิบายการทำงานของ ARIMA model จากประสบการณ์ใช้งานของเรา

https://algoaddict.com/blog/54520/arima

2) ตัวอย่างการใช้ ARIMA ในการทำนายค่า GDP ของประเทศไทย พร้อม source code ตอนที่ 1

https://algoaddict.com/blog/54547/arima_th_gdp_1

2) ตัวอย่างการใช้ ARIMA ในการทำนายค่า GDP ของประเทศไทย พร้อม source code ตอนที่ 2

https://algoaddict.com/blog/54679/arima_th_gdp_2