เป้าหมายของบทช่วยสอนนี้คือการสร้างโมเดลการเรียนรู้ของเครื่องเพื่อทำนายมูลค่าในอนาคตของหุ้นที่ซื้อขายในตลาดหลักทรัพย์แบบเรียลไทม์ด้วยความแม่นยำสูง สำหรับบทช่วยสอนนี้ เราจะใช้ข้อมูลหุ้นของ Google เป็นข้อมูลอนุกรมเวลาเพื่อคาดการณ์ว่าราคาจะขึ้นหรือลงพรุ่งนี้ และเราจะใช้ yfinance API เพื่อรับข้อมูล

มาเริ่มกันเลย.. :)

นำเข้าไลบรารีที่จำเป็นสำหรับโปรเจ็กต์

import yfinance as yf
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt

จากนั้นดาวน์โหลดข้อมูลหุ้นของ Google โดยใช้ yfinance API

data = yf.download("GOOGL" , start = "2019-01-01" , interval = '1d')
data.head()

ตรวจสอบรายละเอียดเพิ่มเติมของชุดข้อมูล เช่น ประเภทข้อมูลของฟีเจอร์ต่างๆ และตรวจสอบว่ามีค่า Null ใดๆ หรือไม่

data.info()

ชุดข้อมูลประกอบด้วย 6 คุณสมบัติ คุณสมบัติเหล่านี้อธิบายไว้ด้านล่าง:

  • เปิด— หมายถึงราคาที่หุ้นเป็นเมื่อการซื้อขายเริ่มต้นในวันที่กำหนด
  • สูง— มูลค่าสูงสุดที่หุ้นพุ่งขึ้นในระหว่างวันซื้อขาย
  • ต่ำ— ค่าต่ำสุดที่หุ้นพุ่งถึงในระหว่างวันซื้อขาย
  • ปิด— ราคาสุดท้ายที่หุ้นซื้อขายระหว่างวันซื้อขาย
  • ปรับปิด — คือราคาปิดของหุ้นนั้นหลังจากบัญชีสำหรับการดำเนินการใดๆ ของบริษัท
  • ปริมาณ— จำนวนหุ้นที่ซื้อขายในหุ้นในช่วงเวลาที่กำหนด

ตัวอย่างเช่น ตลาดหลักทรัพย์นิวยอร์ก (NYSE) เปิดทำการตั้งแต่วันจันทร์ถึงวันศุกร์ เวลา 9.30 น. ถึง 16.00 น. เวลาตะวันออก. ดังนั้นราคาเปิด (เปิด) จะเป็นราคาเมื่อหุ้นเริ่มซื้อขายคือเวลา 09.30 น. และราคาปิด (ปิด) จะเป็นราคาเมื่อการซื้อขายสิ้นสุดคือเวลา 16.00 น. ตัวอย่างเช่น ตลาดหลักทรัพย์นิวยอร์ก (NYSE) เปิดทำการตั้งแต่วันจันทร์ถึงวันศุกร์ เวลา 9.30 น. ถึง 16.00 น. เวลาตะวันออก. ดังนั้นราคาเปิด (เปิด) จะเป็นราคาเมื่อหุ้นเริ่มซื้อขายคือเวลา 09.30 น. และราคาปิด (ปิด) จะเป็นราคาเมื่อการซื้อขายสิ้นสุดคือเวลา 16.00 น.

ต่อไปเราจะตรวจสอบว่าคุณลักษณะ "ปิด" มีค่าที่ไม่ใช่ตัวเลขหรือไม่ และหากมี เราจะเปลี่ยนเป็นน่าน และตรวจสอบว่าชุดข้อมูลมีค่าที่ไม่ใช่ตัวเลขหรือไม่

data["Close"]=pd.to_numeric(data.Close,errors='coerce')
data.isnull().sum().sum()

คุณลักษณะ 'ปิด' ไม่มีค่าน่านใด ๆ ต่อไปเรามาพล็อต 'ปิด' และตรวจสอบการเติบโตของหุ้นตามเวลาที่กำหนด

plt.plot(data.index, data['Close'], color='green', label='Close')
plt.show()

การประมวลผลข้อมูล

ในบทช่วยสอนนี้ เราจะใช้ฟีเจอร์ "ปิด" จากชุดข้อมูลเท่านั้น ดังนั้น เราจะสร้าง dataFrame ใหม่ dataV1 ที่มีเพียงฟีเจอร์ปิดอยู่ในนั้น

dataV1 = data.iloc[:,3:4]
dataV1 = dataV1.values

นำเข้า MinMaxScaler จากไลบรารี sklearn และใช้เพื่อทำให้ข้อมูลของเราเป็นมาตรฐาน เราต้องการการทำให้เป็นมาตรฐานเพื่อให้แน่ใจว่าข้อมูลจะคล้ายกันในบันทึกทั้งหมด MinMaxScaler ทำเช่นนี้โดยการแปลงคุณลักษณะโดยปรับขนาดเป็นช่วงที่กำหนดในกรณีนี้เฉพาะคุณลักษณะ "ปิด" เท่านั้น

from sklearn.preprocessing import MinMaxScaler
Scaler = MinMaxScaler(feature_range=(0,1))
dataV1 = Scaler.fit_transform(dataV1)

มาประกาศความยาวของฟีเจอร์กัน

feature_length = 100

ก่อนที่จะสร้างแบบจำลอง เราต้องแบ่งข้อมูลของเราออกเป็นตัวแปร X และ Y เพื่อทำเช่นนั้น เราจะเขียนฟังก์ชันที่เรียกว่า Create_Features_and_Targets เพื่อแยกข้อมูลของเรา

# Function to create x and y data
def Create_Features_and_Targets(data, feature_length):
  X = list()
  Y = list()
  for i in range(len(data) - feature_length -1):
    X.append(data[i:(i + feature_length), 0])
    Y.append(data[i + feature_length, 0])
  X = np.array(X)
  Y = np.array(Y)
  return X,Y
# calling the function
X_train,y_train= Create_Features_and_Targets(dataV1,feature_length)

การสร้างข้อมูล 3 มิติเนื่องจาก LSTM ใช้ข้อมูล 3 มิติเป็นอินพุต

X_train = np.reshape(X_train,(X_train.shape[0],X_train.shape[1],1))
X_train.shape, y_train.shape

การสร้างโมเดล

นำเข้าไลบรารีที่จำเป็นเพื่อสร้างโมเดล

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense , Dropout , LSTM

โมเดลที่เราจะสร้างคือโมเดล LSTM ซึ่งมี LSTM สองชั้น และเลเยอร์ dropout สองชั้นที่มีเลเยอร์หนาแน่นหนึ่งเลเยอร์ และเราจะใช้ adam เป็นตัวเพิ่มประสิทธิภาพสำหรับโมเดลนี้

แล้ว LSTM คืออะไร

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

# model
model = Sequential([
   LSTM(100,return_sequences=True,input_shape=(X_train.shape[1],1)),
   Dropout(0.3),
   LSTM(100, return_sequences = False),
   Dropout(0.3),
    
   Dense(1),
])
model.compile(optimizer='adam',loss="mean_squared_error")
model.summary()

จนถึงตอนนี้เราได้เตรียมข้อมูลของคุณและสร้างแบบจำลองแล้ว ตอนนี้ก็ถึงเวลาฝึกโมเดลโดยใช้ฟังก์ชัน model.fit เราจะฝึกโมเดลของเราโดยใช้ขนาดแบตช์ 12 ต่ำกว่า 100 ยุค

# Training the model
history = model.fit(
    X_train, 
    y_train, 
    epochs = 100, 
    batch_size = 12, 
    verbose=1,
)

ไชโย เราฝึกโมเดลสำเร็จแล้ว ถึงเวลาทดสอบโมเดลแล้ว เราจะใช้ข้อมูลทั้งหมดเพื่อทดสอบแบบจำลอง และพล็อตข้อมูลที่คาดการณ์ไว้กับข้อมูลจริง

การทดสอบและการทำนาย

รวบรวมข้อมูลที่จำเป็นจากชุดข้อมูลสองชุดเพื่อทำการทดสอบ ใช้คุณลักษณะ "ปิด" จากชุดข้อมูลและสร้างตัวแปรสองตัวขึ้นมา ตัวหนึ่งสำหรับลงจุดข้อมูลจริง y_real และอีกตัวเพื่อสร้างตัวแปร x_test เพื่อทำการคาดการณ์ ในการสร้างตัวแปร x_test เราจะรับค่าทั้งหมดจากฟีเจอร์ "ปิด" ปรับขนาดข้อมูลโดยใช้ฟังก์ชัน Scaler.transform และแปลงรูปร่างของข้อมูลเป็น 3 มิติ และเพื่อสร้างตัวแปร y_real เราสามารถรับค่าทั้งหมดจากฟีเจอร์ "ปิด" โดยเริ่มจากค่าที่ 101 (ข้าม 'feature_length' แรกเนื่องจากโมเดลคาดการณ์ถัดไป)

testData = data.iloc[:,3:4] # Get 'Close' feature
y_real=testData.iloc[feature_length+1:,0:].values #Actual values
x_test = testData.iloc[:,0:].values # data to test
# normalizing the Data using Scaler.transform function
x_test = Scaler.transform(x_test)
x_test, y_test = Create_Features_and_Targets(x_test, feature_length)
# Making data 3 dimensional
x_test = np.reshape(x_test,(x_test.shape[0],x_test.shape[1],1))

การคาดการณ์

มาทำการทดสอบการทำนายและแปลงข้อมูลกัน

y_pred = model.predict(x_test)
predicted_price = Scaler.inverse_transform(y_pred)

พล็อตผลลัพธ์ที่คาดการณ์และข้อมูลหุ้นจริง

plt.plot(y_real, color = 'red', label = 'Actual')
plt.plot(predicted_price, color = 'green', label = 'Predicted')
plt.xlabel('Time')
plt.ylabel('Stock')
plt.legend()
plt.show()

การคาดการณ์ตามเวลาจริง

เรามาลองคาดการณ์แบบเรียลไทม์กันดีกว่า เราจะสร้างฟังก์ชันเพื่อทำนายราคาหุ้นของวันที่ที่กำหนด

def predict_given_date(data, date, feature_length):
  if date not in data.index:
     data.loc[pd.Timestamp(date)] = 0
  idx = data.index.get_loc(date)
  close_col = data.iloc[:,3:4]
  close_col = close_col.iloc[idx - feature_length : idx,:].values
  close_col = np.expand_dims(Scaler.transform(close_col) , axis = 0)
  Prediction = model.predict(close_col)
  Prediction = Scaler.inverse_transform(Prediction)
  return Prediction
# calling the function
predict_given_date(data, '2022-09-20', feature_length)

ที่นี่เราจะเห็นแบบจำลองของเราที่คาดการณ์ไว้ว่า "101.7007" ในวันที่กำหนด ซึ่งก็คือ 2022–09–20 เรามาตรวจสอบว่าใกล้เคียงกับมูลค่าราคาจริงของวันที่ระบุนั้นหรือไม่ โค้ดชิ้นถัดไปทำเช่นนั้น สิ่งนี้จะให้ผลลัพธ์ที่ถูกต้องก็ต่อเมื่อวันที่ที่ระบุมีอยู่แล้วในชุดข้อมูล :)

# only gives the dates that already exists in the dataset
l = data.index.get_loc('2022-09-20')
data.iloc[l: l+1,:]['Close']
# well we can see the predicted value is very close

นี่เป็นจุดสิ้นสุดของคู่มือการปฏิบัตินี้ ยังมีสิ่งที่เราสามารถทำได้เพื่อทำให้สิ่งนี้ดีขึ้น สำหรับตอนนี้ฉันไม่แนะนำให้ใช้สิ่งนี้ในการซื้อขายแบบเรียลไทม์ นิ่ง

ลองทำสิ่งนี้เป็นแบบฝึกหัด ลองทำนาย 10 วันข้างหน้า..

ลิงก์ไปยัง repo github: https://github.com/nafiu-dev/stock_prediction_using_LSTM

คุณสามารถเชื่อมต่อกับฉันได้ที่นี่:



โพสต์อื่นๆ: