หลังจากที่ผมได้เรียนรู้เกี่ยวกับเรื่อง AI จากหลักสูตร e-learning ต่างๆ ณ ตอนนี้ก็พอที่จะมีความรู้ในการนำ AI มาใช้งานง่ายๆได้บ้างแล้ว แน่นอนผมต้องลองนำ AI มาใช้กับเรื่องที่ผมให้ความสนใจเป็นพิเศษ นั่นก็คือการใช้ AI ทำนายราคาของเหรียญคริปโตในอนาคตด้วยภาษา python

จริงๆแล้วมีคนพยายามใช้ AI ทำนายราคาเหรียญคริปโตมาก่อนหน้านี้เยอะมากๆ สามารถค้นหาดูได้บนกูเกิ้ลหรือ Youtube ผมก็อาศัยโครงโปรแกรมของคนเหล่านั้นมาปรับใช้ในแนวทางของผม การนำโปรแกรมบนอินเตอร์เนทมา copy/paste และรันบน python ก็คงได้ผลลัพธ์ที่ไม่แตกต่างกันมากนัก แต่ที่สำคัญคือเราสามารถเข้าใจเหตุและผลของผลลัพธ์เหล่านั้น และเชื่อที่จะทำตามหรือไม่ต่างหาก?
การศึกษาเกี่ยวกับ AI เบื้องต้นช่วยให้ผมเข้าใจความหมายและขั้นตอนการทำงานของ AI ได้ดีขึ้น ผมขอสรุปขั้นตอนคร่าวๆของโปรแกรมภาษา Python ที่ใช้ในการคาดเดาราคาของ AI ดังต่อไปนี้ ซึ่งผมถือว่าเป็นมิติใหม่ในการวิเคราะห์ราคาเหรียญคริปโตเลย ในอดีตผู้คนมักใช้กราฟทางเทคนิคในการวิเคราะห์ทิศทางในอนาคต โดยอิงจากราคาในอดีต โดยเชื่อว่าการเคลื่อนไหวของราคานั้นมีผลมาจากความโลภและความกลัวของนักลงทุนในเวลานั้นๆ ซึ่งรูปแบบการเคลื่อนไหวของราคาที่เกิดขึ้นในอดีตจะถูกสะท้อนออกมาในรูปแบบของ indicator และ graph pattern
ผมก็เชื่อในหลักการวิเคราะห์แบบนั้นอยู่พอสมควรด้วยเหตุผลที่ว่านักลงทุนส่วนใหญ่ในตลาดเรียนรู้วิธีการเคลื่อนไหวของราคาทางเทคนิคมาเหมือนๆกัน ทำให้การตัดสินใจโดยรวมมีผลต่อการเคลื่อนไหวของราคาในอนาคตเป็นไปในทิศทางเดียวกัน
เพราะฉะนั้นถ้าเราลองให้ AI ศึกษาการเคลื่อนไหวของราคาในอดีตโดยไม่ต้องคำนึงถึงหลักการทางเทคนิคเลย ด้วยสมมุติฐานที่ว่ารูปแบบของการเคลื่อนไหวราคาในอดีตจะคล้ายๆกับการเคลื่อนไหวในปัจจุบันและอนาคต น่าจะทำให้ทราบถึงทิศทางของราคาที่กำลังจะเกิดขึ้นได้ เพราะปัจจัยการตัดสินใจทางเทคนิคของนักลงทุนได้ถูกฝังเข้าไปและสะท้อนออกมาเป็นราคาในแต่ละวันแล้ว ทั้งนี้ราคาที่เกิดในอดีตอาจจะมีการเบี่ยงเบนเนื่องจากปัจจัยภายนอกที่คาดไม่ถึงได้ เช่น การปฏิวัติ, สงคราม, เศรษฐกิจโลก, เหตุการณ์ใหญ่ๆที่มีผลต่อการตัดสินใจของนักลงทุน เป็นต้น ทำให้เราต้องยอมรับว่าราคาที่ถูกทำนายจะไม่ตรงเป๊ะนั่นเอง
แล้วโปรแกรมวิเคราะห์นี้มีโครงสร้างอย่างไร?
แน่นอนครับ เริ่มต้นด้วยการ import library ต่างๆที่สำคัญต่อการคำนวณในรูปแบบของ AI ดังนี้
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pandas_datareader as web
import datetime as dt
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.layers import Dense, Dropout, LSTM
from tensorflow.keras.models import Sequential
- Library NumPy (np): Efficiently handles numerical computations and multidimensional arrays.
- Library pandas (pd): Provides high-performance data structures (DataFrames) for data manipulation and analysis.
- Library pandas_datareader (web): Simplifies fetching financial data from online sources.
- Library datetime (dt): Manages dates and times for time-series analysis.
- Library matplotlib.pyplot (plt): Creates various plots and charts for visual exploration of data.
- Library sklearn.preprocessing.MinMaxScaler: Data processing library to Normalizes data within a specific range (0 to 1) for better model performance.
- Library tensorflow.keras.layers: Offers building blocks for neural networks, including:
- Dense layers: Fully connected layers for learning non-linear relationships.
- Dropout layers: Randomly drop connections during training to prevent overfitting.
- LSTM layers: Recurrent layers specialized for sequential data, like time series.
- Library tensorflow.keras.models.Sequential: A straightforward model structure for stacking layers sequentially.
จากนั้นก็เป็นการกำหนดค่าให้กับตัวแปรที่ใช้แทนค่าสัญลักษณ์ของเหรียญที่เราสนใจ ในที่นี้ผมขอเลือกเหรียญ LINK เพื่อใช้ในการศึกษาราคา รวมถึงสกุลเงินที่ต้องการแสดงผล ในที่นี้ผมใช้ USD
จากนั้นก็ระบุช่วงเวลาของราคาที่เราสนใจจะศึกษา ซึ่งผมเริ่มให้เครื่องอ่านค่าราคาตั้งแต่วันที่ 1/1/2018 จนถึงปัจจุบัน ด้วยคำสั่ง DataReader ซึ่งเป็นคำสั่งของ pandas library โดยฟังก์ชั่นนี้รองรับการอ่านราคาจากหลายเวปไซด์ ในที่นี้เราเลือกที่จะอ่านจาก Yahoo Finance website (‘yahoo’) เพราะมีราคาของ crypto currency อยู่ เนื่องจากราคาที่เราดึงมาเป็นรายวันทั้งหมดซึ่งเยอะมาก ผมจึงอยากเห็นผลลัพธ์บางส่วนว่าข้อมูลที่ได้อยู่ในรูปแบบใด จึงแสดงผลด้วยคำสั่ง data.tail เพื่อแสดงข้อมูลตัวอย่างล่าสุดบนหน้าจอ ได้ผลลัพธ์ดังนี้

crypto_currency = 'LINK'
against_currency = 'USD'
start = dt.datetime(2018,1,1)
end = dt.datetime.now()
data = web.DataReader(f'{crypto_currency}-{against_currency}','yahoo', start, end)
print(data.tail())
AI จะสามารถวิเคราห์ข้อมูลแบบ Deep Learning ได้จะต้องมีการแปลงค่าให้อยู่ระหว่าง -1 กับ 1 เท่านั้น เราจึงต้องเรียกใช้ฟังก์ชั่นในการแปลงค่าราคา LINK ที่แท้จริงมาอยู่ในรูปค่าเฉลี่ยระหว่างราคาที่ต่ำที่สุด กับราคาที่สูงที่สุดในชุดข้อมูล โดยใช้ฟังก์ชั่น MinMaxScaler ในตัวอย่างนี้ผมสนใจเฉพาะราคาปิดในแต่ละวัน จะเห็นว่าผมจะเลือกเฉพาะข้อมูลในคอลัมน์ ‘Close’ เท่านั้น (column ที่ 3)
จากนั้นผมมีการกำหนดช่วงเวลาที่ใช้ในการทำนายข้อมูลในอนาคตจากชุดข้อมูลทุกๆ 50 วัน/ชุด (prediction_days) และแปลงข้อมูลเป็น array เพื่อให้ AI ใช้ในการเรียนรู้ชุดข้อมูลราคา เราต้องการให้ AI ใช้ข้อมูลชุดละ 50 วันและสอนให้ AI รู้ว่าข้อมูลในวันที่ 51 หน้าตาเป็นอย่างไรซึ่งเก็บเอาไว้ใน วิธีการแบบนี้เรียกว่า Supervised Learning ทำอย่างนี้ซ้ำๆตั้งแต่ในอดีตจนถึงปัจจุบัน ข้อมูลแต่ละชุดที่ใช้ในการเรียนรู้จะถูกเตรียมไว้ในรูปของ array X_train (เป็นราคาปิดที่ใช้ในการเรียนรู้ ชุดละ 50 วัน) และ y_train (เป็นราคารายวันเริ่มตั้งแต่วันที่ 51) เพื่อสอนให้ AI รู้ว่าข้อมูลชุดแรก 50 ตัวจะได้ผลลัพธ์เป็นราคาเป้าหมาย ณ วันที่ 51 นั่นเอง เช่น
ข้อมูลราคาใน X_train [1,2,3,…..47,48,49,50] = ควรจะได้ผลลัพธ์เป็น ราคา ณ วันที่ 51 (y_train)
ข้อมูลราคาใน X_train [2,3,4,…..48,49,50,51] = ควรจะได้ผลลัพธ์เป็น ราคา ณ วันที่ 52 (y_train)
prediction_days = 50
X_train, y_train = [], []
data = df.iloc[:,3]
for i in range(len(data)-prediction_days):
x=data[i:i+prediction_days]
y=data[i+prediction_days]
X_train.append(x)
y_train.append(y)
hist = np.array(X_train)
target = np.array(y_train)
target=target.reshape(-1,1)
sc = MinMaxScaler()
hist_scaled=sc.fit_transform(hist)
target_scaled=sc.fit_transform(target)
หลักจากเราได้ข้อมูลในการสอน AI กันแล้ว เราก็ต้องเลือก Model ที่เหมาะสมกับการทำนายมูลค่าในอนาคต เนื่องจากข้อมูลราคาเป็นรูปแบบของ time series ดังนั้น model ที่เหมาะสมคือการวิเคราะห์ข้อมูลแบบ Sequential
hist_scaled=hist_scaled.reshape((len(hist_scaled),prediction_days,1))
print(hist_scaled.shape)
ผมได้ทำการแบ่งข้อมูลทั้งหมดออกเป็น 2 ส่วน: ส่วนแรก 1205 ตัวอย่างใช้ในการสอน AI ส่วนข้อมูลที่เหลือประมาณ 50 ชุดใช้ในการทดสอบ prediction model
X_train = hist_scaled[:1205,:,:]
X_test = hist_scaled[1205:,:,:]
y_train = target_scaled[:1205,:]
y_test = target_scaled[1205:,:]
ข้างล่างนี้เป็นการบอกกับ AI ว่าเราเลือกใช้ Sequential model กับ LSTM algorithm โดยประมวลผลแบบ Deep Neural Network 4 layers โดย complile model ด้วย Adam optimizer และคำนวณ loss ด้วย mean absolute error (คนส่วนใหญ่จะใช้ mse ในการคำนวณ loss แต่ผมชอบ mae มากกว่า), จากนั้นเราอาจจะลอง plot graph ออกมาดูว่าค่า loss ลดลงจนเป็นที่หน้าพอใจหรือไม่ ถ้ายังสูงอยู่ อาจต้องปรับ parameter ต่างๆให้ลดลง เราจะให้เครื่องเรียนรู้ไป 100 รอบ
ผลจากการทดสอบด้วยการเรียนรู้จำนวน 100 รอบ ยังไม่พอที่จะทำให้ค่า loss ลดต่ำลงจนใกล้ค่าราคาที่แท้จริงได้ การเรียนรู้ประมาณ 400 รอบจะทำให้ค่าทำนายใกล้เคียงค่าราคาจริงมากกว่า
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(50,1)))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.4))
model.add(LSTM(units=50))
model.add(Dropout(0.5))
model.add(Dense(units=1))
model.summary()
model.compile(optimizer='adam', loss='mean_absolute_error')
model.fit(X_train, y_train, epochs=100, batch_size=32)
หลังจากการเทรน 100 รอบแล้วก็ถึงเวลาที่จะทำการทดสอบการทำนายด้วยข้อมูลที่เราแบ่งเอาไว้ test ด้วยคำสั่ง model.predict และลอง plot graph เปรียบเทียบข้อมูลต้นแบบกับข้อมูลที่เครื่องทำนายออกมากัน แต่เราควรจะแปลงข้อมูลในรูปแบบของ AI กลับไปเป็นข้อมูลราคาที่มนุษย์เราเข้าใจก่อน ด้วยคำสั่ง inverse_transform
จากข้อมูลที่เก็บเอาไว้ทำนาย 50 ตัวอย่างราคา คือราคาจนถึงวันปัจจุบันนั่นเอง AI จะสามารถทำนายราคาในวันที่ 51 ออกมา ซึ่งเป็นราคาทำนายของวันพรุ่งนี้ที่ไม่มีตัวอย่างเหมือนกับข้อมูลที่ใช้ในการสอน AI
pred = model.predict(X_test)
pred_transformed = sc.inverse_transform(pred)
y_test_transformed = sc.inverse_transform(y_test)plt.figure(figsize=(12,8))
plt.plot(y_test, color='blue', label='Real')
plt.plot(pred, color='red', label='Prediction')
plt.title('Link Price Prediction')
plt.legend()
plt.show()
ถ้าดูจากกราฟจะเห็นว่าข้อมูลที่เครื่องทำนายจะมีค่าโดยรวมต่ำกว่าราคาที่แท้จริงเป็นส่วนใหญ่ และกราฟเส้นก็ดูจะ smooth กว่ากราฟราคาจริง อันนี้ผมสันนิฐานเองว่ามันเกิดจากการใช้ MinMaxScaler ที่กล่าวเอาไว้ข้างต้น รวมถึงการนำข้อมูลทั้ง 50 ตัวในแต่ละชุดมาเฉลี่ยเพื่อหา รูปแบบในการเดาราคาลำดับถัดไปของ AI อีกทั้งยังมีการใช้ฟังก์ชั่น DropOut เพื่อตัดข้อมูลที่มีค่าเบี่ยงเบนสูง (overfitting) ออกไปจากการทำนาย แต่ถ้าใครรู้เหตุผลที่แท้จริงและวิธีแก้ไข ก็รบกวนด้วยนะครับ ด้วยการดูกราฟทำนายราคาแบบนี้อาจทำให้เราเห็นค่าที่ทำนายด้วยเส้นแดงวิ่งตามหลังค่าที่แท้จริงอยู่ ซึ่งเอาไปใช้ทำอะไรไม่ได้ ส่วนราคาที่ AI ทำนายอนาคตออกมาก็มีเพียงแค่ราคาของวันพรุ่งนี้ที่มีราคาโดยรวมต่ำกว่าความเป็นจริง เช่นเครื่องทำนายว่า ราคา ณ วันที่ 1 สิงหาคมจะอยู่ที่ 19.7 USD แต่จริงๆแล้ว ราคาของวันที่ 1 สิงหาคมพุ่งไปที่ 23 USD แล้ว สิ่งเดียวที่ผมเห็นว่าเป็นประโยชน์จากการทดลองนี้ก็คือการเห็นทิศทางการทำนายราคาของ AI จากกราฟที่มีความสอดคล้องกับทิศทางของราคาจริงที่เกิดขึ้น แต่ยังมีความล่าช้าเกินกว่าที่จะนำไปใช้งานได้

การทดลองที่ผมจะพยายามศึกษาต่อไปคือ
- การปรับแต่งโปรแกรมให้ AI ทำนายข้อมูลในอนาคตที่ยาวนานมากกว่า 1 วันด้วยการเอาข้อมูลที่เครื่องทำนายได้มาเป็นส่วนหนึ่งของการทำนายข้อมูลในวันถัดๆไป เช่น
- ข้อมูล 50 วันสุดท้ายที่ใช้ในการทำนาย จะได้ข้อมูลในอนาคตของวันที่ 51 จากนั้น เอาข้อมูลของวันที่ 51 ไปเป็นส่วนหนึ่งของข้อมูล 50 ตัวอย่างเพื่อทำนายวันที่ 52 ต่อๆไป
- [1,2,3,….48,49,50] -> predicted 51
- [2,3,4,….49,50,predicted 51] -> predicted 52
- [3,4,5,….50,predicted 51, predicted 52] -> predicted 53
- ข้อมูล 50 วันสุดท้ายที่ใช้ในการทำนาย จะได้ข้อมูลในอนาคตของวันที่ 51 จากนั้น เอาข้อมูลของวันที่ 51 ไปเป็นส่วนหนึ่งของข้อมูล 50 ตัวอย่างเพื่อทำนายวันที่ 52 ต่อๆไป
- หาวิธีแก้ไขค่าทำนายที่ตำ่กว่าความเป็นจริง (เพิ่มจำนวน epoch ช่วยเรื่องนี้ให้ดีขึ้นได้)
- แก้ไขเทรนการทำนายที่ส่งสัญญาณทิศทางราคาช้าเกินไป
หลังจากค้นคว้ามาสักพักก็พบว่า มีวิธีการที่ง่ายกว่าการเขียน AI script ขึ้นมาเอง อีกทั้งยังดูเหมือนว่าจะทำนายได้แม่นยำกว่าอีกด้วย ติดตามได้ในภาคสองครับ
เพิ่มค่าคงที่ ส่วนต่างจากกราคาจริง ไว้บวกขึ้นตอนสุดท้าย ไว้ในสูตรเลยสิครับ
LikeLike
ขอบคุณสำหรับคำแนะนำครับผมลองแล้วมันก็ทำให้ราคาเที่ยงตรงเฉพาะเหรียญนั้นๆ แต่ต้องแรกกับความยืดหยุ่นในการทำนายเหรียญอื่นๆด้วย coding ชุดเดียวกัน เพราะค่าคงที่ของแต่ละเหรียญไม่เหมือนกันครับ แต่ตอนนี้เปลี่ยนมาใช้ Facebook prophet algorithm ชีวิตดีขึ้นเยอะเลย
LikeLike