3
fokus pada
1444
Pengikut

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

Dibuat di: 2019-07-12 14:28:20, diperbarui pada: 2024-12-19 20:58:01
comments   3
hits   7580

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

1. Pengantar Singkat

Jaringan saraf dalam telah menjadi semakin populer dalam beberapa tahun terakhir, memecahkan masalah yang sebelumnya tidak dapat dipecahkan di banyak bidang dan menunjukkan kemampuannya yang hebat. Dalam prediksi deret waktu, harga jaringan syaraf yang umum digunakan adalah RNN, karena RNN tidak hanya memiliki input data terkini, tetapi juga input data historis. Tentu saja, ketika kita berbicara tentang RNN yang memprediksi harga, kita sering berbicara tentang jenis RNN : LSTM . Artikel ini akan membangun model untuk memprediksi harga Bitcoin berdasarkan pytorch. Meskipun ada banyak informasi relevan di Internet, itu masih belum cukup menyeluruh, dan relatif sedikit orang yang menggunakan pytorch. Tetap perlu menulis artikel. Hasil akhirnya adalah menggunakan harga pembukaan, harga penutupan, harga tertinggi, harga terendah, dan volume transaksi pasar Bitcoin. untuk memprediksi harga penutupan berikutnya. Pengetahuan pribadi saya tentang jaringan saraf rata-rata, dan saya menyambut kritik dan koreksi Anda. Tutorial ini dibuat oleh FMZ, penemu platform perdagangan kuantitatif mata uang digital (www.fmz.com). Selamat bergabung di grup QQ: 863946592 untuk komunikasi.

2. Data dan Referensi

Contoh prediksi harga terkait: https://yq.aliyun.com/articles/538484 Pengenalan terperinci tentang model RNN: https://zhuanlan.zhihu.com/p/27485750 Memahami input dan output RNN: https://www.zhihu.com/question/41949741/answer/318771336 Tentang pytorch: Dokumentasi resmi https://pytorch.org/docs Cari sendiri informasi lainnya. Selain itu, diperlukan beberapa pengetahuan prasyarat untuk memahami artikel ini, seperti pandas/crawler/pemrosesan data, dll., tetapi tidak masalah jika Anda tidak mengetahuinya.

3. Parameter model LSTM pytorch

Parameter LSTM:

Ketika saya pertama kali melihat parameter yang padat ini pada dokumen, reaksi saya adalah: Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin Saat saya membaca perlahan, saya akhirnya memahaminya.

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

input_size: Ukuran fitur vektor input x. Jika harga penutupan digunakan untuk memprediksi harga penutupan, maka input_size=1; jika harga penutupan diprediksi oleh harga pembukaan tertinggi dan harga penutupan terendah, maka input_size=4 hidden_size: Ukuran lapisan tersembunyi num_layers: Jumlah lapisan RNN batch_first: Jika Benar, dimensi input pertama adalah batch_size. Parameter ini juga sangat membingungkan dan akan dijelaskan secara rinci di bawah ini.

Parameter data masukan:

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

input: Data masukan spesifik adalah tensor tiga dimensi dengan bentuk spesifik (seq_len, batch, input_size). Di antara mereka, seq_len mengacu pada panjang urutan, yaitu, seberapa panjang data historis yang perlu dipertimbangkan LSTM. Perhatikan bahwa ini hanya mengacu pada format data, bukan struktur internal LSTM. Model LSTM yang sama dapat data input dengan seq_len yang berbeda dan dapat memberikan prediksi. Hasil; batch mengacu pada ukuran batch, yang menunjukkan berapa banyak kelompok data yang berbeda; input_size adalah input_size sebelumnya. h_0: Keadaan tersembunyi awal, bentuknya (num_layers * num_directions, batch, hidden_size), jika merupakan jaringan dua arah num_directions=2 c_0: Keadaan sel awal, bentuknya sama seperti di atas, dapat dibiarkan tidak ditentukan.

Parameter keluaran:

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

output: Bentuk keluaran (seq_len, batch, num_directions * hidden_size), perhatikan bahwa ini terkait dengan parameter model batch_first h_n: h state pada waktu t = seq_len, bentuknya sama dengan h_0 c_n: c state pada waktu t = seq_len, bentuknya sama dengan c_0

4. Contoh sederhana input dan output LSTM

Pertama impor paket yang diperlukan

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

Mendefinisikan model LSTM

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

Mempersiapkan data masukan

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]]])

Bentuk x adalah (3,4,5), karena kita mendefinisikanbatch_first=True, saat ini, batch_size adalah 3, sqe_len adalah 4, dan input_size adalah 5. X[[0] mewakili kelompok pertama.

Jika batch_first tidak didefinisikan, nilainya akan menjadi False secara default, dan data direpresentasikan secara berbeda, dengan ukuran batch 4, sqe_len 3, dan input_size 5. Pada saat ini x[[0] mewakili data semua batch pada t=0, dan seterusnya. Saya pribadi merasa bahwa pengaturan ini tidak intuitif, jadi saya menambahkan parameterbatch_first=True.

Konversi data antara keduanya juga sangat nyaman:x.permute(1,0,2)

Masukan dan Keluaran

Bentuk input dan output LSTM mudah membingungkan, dengan bantuan gambar berikut untuk membantu pemahaman: Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin
Sumber: 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])

Amati hasil keluaran yang konsisten dengan penjelasan parameter sebelumnya. Perhatikan bahwa nilai kedua hn.size() adalah 3, yang konsisten dengan ukuran batch_size, yang menunjukkan bahwa tidak ada status peralihan yang disimpan dalam hn, hanya langkah terakhir. Karena jaringan LSTM kita memiliki dua lapisan, output dari lapisan terakhir hn sebenarnya adalah nilai output, dan bentuk outputnya adalah[3, 4, 10], menyimpan hasil semua momen t=0,1,2,3, jadi:

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. Siapkan data pasar Bitcoin

Banyak hal yang telah saya katakan sebelumnya hanyalah pendahuluan. Sangat penting untuk memahami input dan output LSTM. Jika tidak, akan mudah membuat kesalahan jika Anda menyalin beberapa kode dari Internet secara acak. Karena kemampuan yang hebat dari LSTM dalam deret waktu, meskipun modelnya salah, Anda bisa mendapatkannya pada akhirnya. Hasil yang bagus.

Akuisisi Data

Data yang digunakan adalah data pasar pasangan perdagangan BTC_USD dari bursa Bitfinex.

import requests
import json

resp = requests.get('https://q.fmz.com/chart/history?symbol=bitfinex.btc_usd&resolution=15&from=0&to=0&from=1525622626&to=1562658565')
data = resp.json()
df = pd.DataFrame(data,columns = ['t','o','h','l','c','v'])
print(df.head(5))

Format datanya adalah sebagai berikut: Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

Prapemrosesan data

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

Metode standarisasi data sangat kasar dan akan ada beberapa masalah. Ini hanya untuk demonstrasi. Anda dapat menggunakan standarisasi data seperti yield.

Mempersiapkan data pelatihan

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))

Bentuk akhir dari train_x dan train_y adalah: torch.Size([800, 10, 5]), torch.Size([800, 10, 1]). Karena model kami memprediksi harga penutupan periode berikutnya berdasarkan data dari 10 periode, secara teoritis, 800 batch hanya memerlukan 800 harga penutupan yang diprediksi. Namun train_y memiliki 10 data dalam setiap batch. Faktanya, hasil antara dari setiap prediksi batch dipertahankan, bukan hanya yang terakhir. Saat menghitung Kerugian akhir, semua 10 hasil prediksi dapat diperhitungkan dan dibandingkan dengan nilai aktual di train_y. Secara teoritis, hanya mungkin untuk menghitung Kerugian hasil prediksi terakhir. Saya menggambar diagram kasar untuk mengilustrasikan masalah ini. Karena model LSTM sebenarnya tidak berisi parameter seq_len, model tersebut dapat diterapkan pada panjang yang berbeda, dan hasil prediksi antara juga bermakna, jadi saya cenderung menggabungkan perhitungan Loss. Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

Perlu diperhatikan bahwa saat menyiapkan data pelatihan, pergerakan jendela akan tersendat-sendat, dan data yang telah digunakan tidak lagi digunakan. Tentu saja, jendela juga dapat dipindahkan satu per satu, sehingga set pelatihan yang diperoleh akan jauh lebih besar. . Tetapi saya merasa data batch yang berdekatan terlalu berulang, jadi saya mengadopsi metode saat ini. Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

6. Membangun model LSTM

Model akhir adalah sebagai berikut, yang mencakup LSTM dua lapis dan lapisan 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. Mulai melatih model

Akhirnya mulai pelatihan, kodenya adalah sebagai berikut:

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()))

Hasil pelatihannya adalah sebagai berikut: Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin

8. Evaluasi Model

Nilai prediksi modelnya adalah:

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()

Jaringan Saraf dan Seri Perdagangan Kuantitatif Mata Uang Digital (1) - LSTM Memprediksi Harga Bitcoin
Seperti yang terlihat pada gambar, tingkat kecocokan data pelatihan (sebelum 800) sangat tinggi, tetapi harga Bitcoin telah naik ke titik tertinggi baru kemudian, dan model belum melihat data ini, jadi prediksinya adalah tidak dapat bekerja dengan baik. Ini juga menunjukkan adanya masalah dalam standardisasi data sebelumnya. Meskipun harga yang diprediksi mungkin tidak akurat, seberapa akurat prediksi kenaikan dan penurunannya? Lihatlah bagian data prediksi:

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)))

Akurasi prediksi naik turunnya mencapai 81,4%, melebihi ekspektasi saya. Saya tidak tahu apakah saya membuat kesalahan di suatu tempat.

Tentu saja, model ini tidak memiliki nilai riil, tetapi sederhana dan mudah dipahami. Gunakan saja ini sebagai titik awal. Akan ada lebih banyak kursus pengantar tentang penerapan jaringan saraf dalam kuantifikasi mata uang digital.