Mạng thần kinh và số tiền kỹ thuật số chuỗi giao dịch định lượng ((1) LSTM dự đoán giá Bitcoin

Tác giả:Cỏ nhỏ, Tạo: 2019-07-12 14:28:20, Cập nhật: 2023-10-24 21:42:00

img

1.简单介绍

Mạng lưới thần kinh sâu đã trở nên phổ biến trong những năm qua và có khả năng giải quyết các vấn đề khó giải quyết trong nhiều lĩnh vực. Trong dự đoán chuỗi thời gian, giá của mạng lưới thần kinh thường được sử dụng là RNN, vì RNN không chỉ có đầu vào dữ liệu hiện tại mà còn có đầu vào dữ liệu lịch sử, tất nhiên, khi chúng ta nói về dự đoán giá RNN, chúng ta thường nói về một loại RNN: LSTM. Bài viết này sẽ dựa trên pytorch để xây dựng mô hình dự đoán giá Bitcoin. Bài hướng dẫn này được cung cấp bởi FMZ, nhà phát minh của nền tảng giao dịch định lượng tiền kỹ thuật số.www.fmz.com), chào mừng bạn đến với nhóm QQ: 863946592.

2.数据和参考

Dữ liệu giá Bitcoin được lấy từ nền tảng giao dịch định lượng của FMZ:https://www.quantinfo.com/Tools/View/4.htmlMột ví dụ về dự báo giá có liên quan:https://yq.aliyun.com/articles/538484Các chi tiết về mô hình RNNhttps://zhuanlan.zhihu.com/p/27485750Hiểu đầu vào và đầu ra của RNN:https://www.zhihu.com/question/41949741/answer/318771336Về pytorch: tài liệu chính thứchttps://pytorch.org/docsCác bạn có thể tự tìm kiếm thông tin khác nhé. Ngoài ra, việc đọc bài viết này cũng đòi hỏi một số kiến thức trước, chẳng hạn như panda / bò sát / xử lý dữ liệu, nhưng không có vấn đề.

3. Các tham số của mô hình pytorch LSTM

Các tham số của LSTM:

Khi lần đầu tiên nhìn thấy các thông số này trên tài liệu, tôi đã phản ứng như sau:imgBạn đọc chậm, bạn có thể hiểu.

img

input_size: Kích thước đặc trưng của vector x, nếu dự đoán giá đóng bằng giá đóng, thì input_size = 1; nếu dự đoán giá đóng bằng giá mở cao và thấp, thì input_size = 4hidden_size: Kích thước lớp ẩnnum_layers: Số lớp của RNNbatch_first: Nếu cho True, đầu tiên nhập kích thước là batch_size, thì tham số này cũng sẽ gây nhầm lẫn, và sẽ được giải thích chi tiết dưới đây.

Các thông số nhập:

img

input: Dữ liệu được nhập cụ thể, là một tensor ba chiều, hình dạng cụ thể là: ((seq_len, batch, input_size) ). Trong đó, chiều dài của chuỗi seq_len, tức là LSTM cần phải xem xét thời gian dữ liệu lịch sử bao lâu, lưu ý rằng đây chỉ là định dạng của dữ liệu, không phải là cấu trúc bên trong LSTM, cùng một mô hình LSTM có thể nhập dữ liệu khác nhau seq_len, đều có thể đưa ra kết quả dự đoán; batch chỉ kích thước batch, đại diện cho số lượng dữ liệu khác nhau; input_size là input_size trước đó.h_0: trạng thái ẩn ban đầu, hình dạng là ((num_layers * num_directions, batch, hidden_size), nếu số đường hai chiều = 2c_0: trạng thái tế bào ban đầu, hình dạng giống nhau, có thể không được chỉ định.

Các thông số đầu ra:

img

output: hình dạng đầu ra (seq_len, batch, num_directions * hidden_size), chú ý liên quan đến tham số mô hình batch_firsth_n: t = trạng thái h tại thời điểm seq_len, hình dạng giống h_0c_n: t = trạng thái c tại thời điểm seq_len, cùng hình dạng với c_0

4.LSTM输入输出的简单例子

Đầu tiên, nhập các gói cần thiết

import pandas as pd
import numpy as np
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

Định nghĩa mô hình LSTM

LSTM = nn.LSTM(input_size=5, hidden_size=10, num_layers=2, batch_first=True)

Dữ liệu sẵn sàng nhập

x = torch.randn(3,4,5)
# x的值为:
tensor([[[ 0.4657,  1.4398, -0.3479,  0.2685,  1.6903],
         [ 1.0738,  0.6283, -1.3682, -0.1002, -1.7200],
         [ 0.2836,  0.3013, -0.3373, -0.3271,  0.0375],
         [-0.8852,  1.8098, -1.7099, -0.5992, -0.1143]],

        [[ 0.6970,  0.6124, -0.1679,  0.8537, -0.1116],
         [ 0.1997, -0.1041, -0.4871,  0.8724,  1.2750],
         [ 1.9647, -0.3489,  0.7340,  1.3713,  0.3762],
         [ 0.4603, -1.6203, -0.6294, -0.1459, -0.0317]],

        [[-0.5309,  0.1540, -0.4613, -0.6425, -0.1957],
         [-1.9796, -0.1186, -0.2930, -0.2619, -0.4039],
         [-0.4453,  0.1987, -1.0775,  1.3212,  1.3577],
         [-0.5488,  0.6669, -0.2151,  0.9337, -1.1805]]])

X có hình dạng là ((3, 4, 5) như chúng ta đã định nghĩa trước đây.batch_first=True, kích thước của batch_size lúc này là 3, sqe_len là 4, input_size là 5; x[0] đại diện cho batch đầu tiên.

Nếu không định nghĩa batch_first, mặc định là False, thì đại diện của dữ liệu tại thời điểm này hoàn toàn khác, batch size là 4, sqe_len là 3, input_size là 5; tại thời điểm này x[0] đại diện cho tất cả các batch khi t = 0 dữ liệu, theo kiểu.batch_first=True.

Trong khi đó, các nhà nghiên cứu khác cũng cho rằng việc chuyển đổi dữ liệu giữa hai phương tiện này rất dễ dàng:x.permute(1,0,2)

Nhập và xuất

Các hình dạng đầu vào và đầu ra của LSTM dễ bị nhầm lẫn.img
Nguồn:https://www.zhihu.com/question/41949741/answer/318771336

x = torch.randn(3,4,5)
h0 = torch.randn(2, 3, 10)
c0 = torch.randn(2, 3, 10)
output, (hn, cn) = LSTM(x, (h0, c0))
print(output.size()) #在这里思考一下,如果batch_first=False输出的大小会是多少?
print(hn.size())
print(cn.size())
#结果
torch.Size([3, 4, 10])
torch.Size([2, 3, 10])
torch.Size([2, 3, 10])

Kết quả của việc xem xét đầu ra, phù hợp với giải thích của tham số trước. Lưu ý rằng giá trị thứ hai củahn.size (()) là 3, và kích thước của batch_size phù hợp, cho thấy không lưu giữ trạng thái giữa tronghn, chỉ lưu giữ bước cuối. Vì mạng lưới LSTM của chúng tôi có hai lớp, thực tế đầu ra của lớp cuối cùng là giá trị đầu ra, đầu ra có hình dạng [3, 4, 10], lưu kết quả của t = 0, 1, 2, 3 tất cả các thời điểm, vì vậy:

hn[-1][0] == output[0][-1] #第一个batch在hn最后一层的输出等于第一个batch在t=3时output的结果
hn[-1][1] == output[1][-1]
hn[-1][2] == output[2][-1]

5.准备比特币行情数据

Những gì đã được nói ở trên chỉ là một sự vạch trần, hiểu đầu vào và đầu ra của LSTM rất quan trọng, nếu không, việc lấy một số mã bất ngờ từ internet rất dễ bị sai, vì khả năng mạnh mẽ của LSTM trên chuỗi thời gian, thậm chí mô hình cũng sai, cuối cùng có thể đưa ra kết quả tốt.

Thu thập dữ liệu

Dữ liệu được sử dụng là dữ liệu thị trường của cặp giao dịch BTC_USD trên sàn giao dịch Bitfinex.

import requests
import json

resp = requests.get('https://www.quantinfo.com/API/m/chart/history?symbol=BTC_USD_BITFINEX&resolution=60&from=1525622626&to=1562658565')
data = resp.json()
df = pd.DataFrame(data,columns = ['t','o','h','l','c','v'])
print(df.head(5))

Dữ liệu được định dạng như sau:img

Xử lý trước dữ liệu

df.index = df['t'] # index设为时间戳
df = (df-df.mean())/df.std() # 数据的标准化,否则模型的Loss会非常大,不利于收敛
df['n'] = df['c'].shift(-1) # n为下一个周期的收盘价,是我们预测的目标
df = df.dropna()
df = df.astype(np.float32) # 改变下数据格式适应pytorch

Phương pháp tiêu chuẩn hóa dữ liệu rất thô và có thể gây ra một số vấn đề, chỉ là biểu hiện, bạn có thể sử dụng tiêu chuẩn hóa dữ liệu như tỷ lệ lợi nhuận.

Chuẩn bị dữ liệu huấn luyện

seq_len = 10 # 输入10个周期的数据
train_size = 800 # 训练集batch_size
def create_dataset(data, seq_len):
    dataX, dataY=[], []
    for i in range(0,len(data)-seq_len, seq_len):
        dataX.append(data[['o','h','l','c','v']][i:i+seq_len].values)
        dataY.append(data['n'][i:i+seq_len].values)
    return np.array(dataX), np.array(dataY)
data_X, data_Y = create_dataset(df, seq_len)
train_x = torch.from_numpy(data_X[:train_size].reshape(-1,seq_len,5)) #变化形状,-1代表的值会自动计算
train_y = torch.from_numpy(data_Y[:train_size].reshape(-1,seq_len,1))

Các hình dạng của train_x và train_y là: torch.Size (([800, 10, 5]), torch.Size (([800, 10, 1]) ). Vì mô hình của chúng tôi là dự đoán giá đóng cửa cho chu kỳ tiếp theo dựa trên dữ liệu 10 chu kỳ, theo lý thuyết 800 lô sẽ phù hợp với 800 giá đóng cửa dự đoán. Nhưng train_y có 10 dữ liệu trong mỗi lô, và thực tế mỗi lô dự đoán kết quả trung gian được giữ lại, không chỉ là cuối cùng. Trong việc tính toán Loss cuối cùng, tất cả 10 kết quả dự đoán có thể được tính vào kết quả và so sánh với giá trị thực tế trong train_y. Loss cũng có thể được tính toán theo lý thuyết chỉ với kết quả dự đoán cuối cùng.img

Lưu ý rằng khi chuẩn bị dữ liệu đào tạo, chuyển động của cửa sổ là nhảy vọt, dữ liệu đã được sử dụng không còn được sử dụng nữa, và tất nhiên cửa sổ cũng có thể di chuyển một cách riêng biệt, điều này sẽ mang lại một tập hợp đào tạo lớn. Nhưng cảm thấy dữ liệu lô hàng lân cận như vậy quá lặp đi lặp lại, vì vậy chúng tôi sử dụng phương pháp hiện tại.img

6.构造LSTM模型

Mô hình cuối cùng được xây dựng như sau, bao gồm một lớp LSTM hai lớp, một lớp Linear.

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, output_size=1, num_layers=2):
        super(LSTM, self).__init__()
        self.rnn = nn.LSTM(input_size,hidden_size,num_layers,batch_first=True)
        self.reg = nn.Linear(hidden_size,output_size) # 线性层,把LSTM的结果输出成一个值

    def forward(self, x):
        x, _ = self.rnn(x) # 如果不理解前向传播中数据维度的变化,可单独调试
        x = self.reg(x)
        return x
        
net = LSTM(5, 10) # input_size为5,代表了高开低收和交易量. 隐含层为10.

7.开始训练模型

Cuối cùng, chúng tôi bắt đầu đào tạo, mã là như sau:

criterion = nn.MSELoss() # 使用了简单的均方差损失函数
optimizer = torch.optim.Adam(net.parameters(),lr=0.01) # 优化函数,lr可调
for epoch in range(600): # 由于速度很快,这里的epoch多一些
    out = net(train_x) # 由于数据量很小, 直接拿全量数据计算
    loss = criterion(out, train_y)
    optimizer.zero_grad()
    loss.backward() # 反向传播损失
    optimizer.step() # 更新参数
    print('Epoch: {:<3}, Loss:{:.6f}'.format(epoch+1, loss.item()))

Kết quả đào tạo sau đây:img

8.模型评价

Giá trị dự đoán của mô hình:

p = net(torch.from_numpy(data_X))[:,-1,0] # 这里只取最后一个预测值作为比较
plt.figure(figsize=(12,8))
plt.plot(p.data.numpy(), label= 'predict')
plt.plot(data_Y[:,-1], label = 'real')
plt.legend()
plt.show()

img
Theo biểu đồ, sự trùng khớp giữa dữ liệu đào tạo (trước 800) rất cao, nhưng sau đó giá Bitcoin tăng cao hơn, mô hình đã không nhìn thấy dữ liệu này và dự đoán không thực sự đúng. Trong khi đó, giá cả dự đoán không phải lúc nào cũng chính xác, nhưng việc dự đoán giá giảm sẽ chính xác như thế nào?

r = data_Y[:,-1][800:1000]
y = p.data.numpy()[800:1000]
r_change = np.array([1 if i > 0 else 0 for i in r[1:200] - r[:199]])
y_change = np.array([1 if i > 0 else 0 for i in y[1:200] - r[:199]])
print((r_change == y_change).sum()/float(len(r_change)))

Kết quả cho thấy sự chính xác của dự báo giảm là 81.4%, hoặc tốt hơn tôi mong đợi.

Tất nhiên, mô hình này không có giá trị thực tế, nhưng nó đơn giản và dễ hiểu, chỉ cần giới thiệu về nó, sau đó sẽ có nhiều chương trình giới thiệu về ứng dụng mạng thần kinh về định lượng tiền kỹ thuật số.


Có liên quan

Thêm nữa

JackmaDữ liệu đào tạo giống như dữ liệu thử nghiệm?

a838899Điều đó có nghĩa là không rõ ràng là sử dụng dữ liệu 800 ngày để dự đoán số liệu của ngày hôm sau hay số liệu của 800 ngày tới.

Orion1708Tại sao bạn nói rằng mô hình này không có giá trị thực tế?