برنامه جامع یادگیری ماشینی در دنیای واقعی با استفاده از شبکه های عصبی LSTM برای پیش بینی قیمت ارز دیجیتال را در ادامه بخوانید.
با محبوبیت ارزهای دیجیتال در سال 2017، ارزش آنها در چندین ماه متوالی رشد تصاعدی یافت. قیمت ها در ژانویه 2018 به بیش از 800 میلیارد دلار رسید.
اگرچه یادگیری ماشینی در پیش بینی قیمت های بازار سهام از طریق مجموعه ای از مدل های مختلف موفق بوده است، اما کاربرد آن در پیش بینی قیمت ارزهای دیجیتال کاملاً محدود بوده است. دلیل این امر واضح است زیرا قیمت ارزهای دیجیتال به عوامل زیادی مانند پیشرفت فناوری، رقابت داخلی، فشار بر بازارها برای ارائه، مشکلات اقتصادی، مسائل امنیتی، عوامل سیاسی و غیره بستگی دارد. نوسانات بالای آنها منجر به پتانسیل بالا میشود.
اگر راهبردهای ابداع هوشمندانه ای اتخاذ شود، سود میبرد. متأسفانه، به دلیل کمبود شاخص ها، ارزهای دیجیتال در مقایسه با پیش بینی های مالی سنتی مانند بازار سهام، نسبتاً غیرقابل پیش بینی هستند.
در این مقاله، من یک فرآیند چهار مرحله ای را برای پیش بینی قیمت ارزهای دیجیتال طی میکنم:
- دریافت اطلاعات ارزهای دیجیتال در زمان واقعی
- داده ها را برای آموزش و آزمایش آماده کنید.
- پیش بینی قیمت ارز دیجیتال با استفاده از شبکه عصبی LSTM.
- نتایج پیش بینی را تجسم کنید.
چالش
برای پیش بینی قیمت ارزهای دیجیتال باید از ویژگی های معاملاتی مانند قیمت، حجم، مقادیر باز، بالا و پایین موجود در مجموعه داده مطلع بود.
داده ها
مجموعه داده را میتوان از وبسایت CryptoCompare بارگیری کرد.
مجموعه داده در مجموع شامل 5 ویژگی است. جزئیات مربوط به آنها به شرح زیر است:
- قیمت بسته – قیمت بسته بازار برای ارز برای آن روز خاص است.
- قیمت بالا – بالاترین قیمت ارز در روز است.
- قیمت پایین – پایین ترین قیمت ارز برای آن روز است.
- قیمت باز – قیمت باز بازار برای ارز آن روز است.
- حجم – حجم ارزی که برای آن روز در حال معامله است.
کد کجاست؟
بدون بحث زیاد، بیایید با کد شروع کنیم.
من با بارگیری تمام کتابخانه ها و وابستگی های مورد نیاز شروع کردم.
import json
import requests
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, LSTM
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.metrics import mean_absolute_error
%matplotlib inline
من از نرخ ارز کانادایی استفاده کرده ام و داده های زمان واقعی را در یک قاب داده پاندا ذخیره کرده ام. من از روش ()to_datetime برای تبدیل رشته Date time به Data time object Python استفاده کردم. این امر ضروری است زیرا Date time object در فایل به عنوان یک object رشته خوانده میشوند. انجام عملیاتی مانند تفاوت زمان بر روی یک رشته به جای Data time object بسیار آسان است.
endpoint = ‘https://min-api.cryptocompare.com/data/histoday’
res = requests.get(endpoint + ‘?fsym=BTC&tsym=CAD&limit=500’)
hist = pd.DataFrame(json.loads(res.content)[‘Data’])
hist = hist.set_index(‘time’)
hist.index = pd.to_datetime(hist.index, unit=’s’)
target_col = ‘close’
بیایید ببینیم مجموعه داده با تمام ویژگی های معاملاتی مانند قیمت، حجم، باز، زیاد، پایین چگونه به نظر میرسد.
hist.head(5)
سپس من داده ها را به دو مجموعه تقسیم کردم – مجموعه آموزشی و مجموعه آزمایشی به ترتیب متشکل از 80٪ و 20٪ داده. تصمیمی که در اینجا گرفته شده فقط برای هدف این آموزش است. در پروژه های واقعی، شما همیشه باید داده های خود را به آموزش، اعتبارسنجی، آزمایش تقسیم کنید (مانند 60٪، 20٪، 20٪).
def train_test_split(df, test_size=0.2):
split_row = len(df) – int(test_size * len(df))
train_data = df.iloc[:split_row]
test_data = df.iloc[split_row:]
return train_data, test_data
train, test = train_test_split(hist, test_size=0.2)
حالا بیایید با استفاده از کد زیر قیمت ارزهای دیجیتال را به دلار کانادا به صورت تابعی از زمان ترسیم کنیم:
def line_plot(line1, line2, label1=None, label2=None, title=”, lw=2):
fig, ax = plt.subplots(1, figsize=(13, 7))
ax.plot(line1, label=label1, linewidth=lw)
ax.plot(line2, label=label2, linewidth=lw)
ax.set_ylabel(‘price [CAD]’, fontsize=14)
ax.set_title(title, fontsize=16)
ax.legend(loc=’best’, fontsize=16)
line_plot(train[target_col], test[target_col], ‘training’, ‘test’, title=”)
ما میتوانیم مشاهده کنیم که بین دسامبر 2018 و آوریل 2019 کاهش واضحی در قیمت ها وجود دارد. قیمت ها از آوریل 2019 تا آگوست 2019 با نوساناتی که در ماه های جولای و آگوست رخ میدهد، همچنان در حال افزایش است. از سپتامبر 2019 به بعد قیمت ها به طور مداوم در حال کاهش است. نکته جالب توجه از این نوسان قیمت پایین بودن قیمت ها در زمستان و افزایش آن در تابستان است. اگرچه این را نمیتوان تعمیم داد زیرا مجموعه داده مورد بررسی فقط یک نمونه کوچک است که برای یک سال است. همچنین با ارزهای دیجیتال، تعمیم هر چیزی دشوار است.
سپس چند تابع برای عادی سازی مقادیر ایجاد کردم. عادی سازی تکنیکی است که اغلب به عنوان بخشی از آماده سازی داده ها برای یادگیری ماشین استفاده میشود. هدف ساده سازی تغییر مقادیر ستون های عددی در مجموعه داده ها به یک مقیاس مشترک است، بدون اینکه تفاوت در محدوده های مقادیر را تحریف کند.
def normalise_zero_base(df):
return df / df.iloc[0] – 1
def normalise_min_max(df):
return (df – df.min()) / (data.max() – df.min())
در مرحله بعد، من یک تابع برای استخراج داده های پنجره هایی که هر کدام اندازه 5 هستند، همانطور که در کد زیر نشان داده شده است ایجاد کردم:
def extract_window_data(df, window_len=5, zero_base=True):
window_data = []
for idx in range(len(df) – window_len):
tmp = df[idx: (idx + window_len)].copy()
if zero_base:
tmp = normalise_zero_base(tmp)
window_data.append(tmp.values)
return np.array(window_data)
من به ساخت تابعی ادامه دادم تا داده ها را در قالبی آماده کنم تا بعداً به شبکه عصبی وارد شود. من از همان مفهوم تقسیم داده ها به دو مجموعه استفاده کردم – مجموعه آموزشی و مجموعه آزمایشی به ترتیب با داده های 80٪ و 20٪ همانطور که در کد زیر نشان داده شده است:
def prepare_data(df, target_col, window_len=10, zero_base=True, test_size=0.2):
train_data, test_data = train_test_split(df, test_size=test_size)
X_train = extract_window_data(train_data, window_len, zero_base)
X_test = extract_window_data(test_data, window_len, zero_base)
y_train = train_data[target_col][window_len:].values
y_test = test_data[target_col][window_len:].values
if zero_base:
y_train = y_train / train_data[target_col][:-window_len].values – 1
y_test = y_test / test_data[target_col][:-window_len].values – 1
return train_data, test_data, X_train, X_test, y_train, y_test
LSTM
با استفاده از گیت های ویژه به هر لایه LSTM اجازه میدهد تا اطلاعات لایه های قبلی و فعلی را بگیرد. داده ها از چندین دروازه (مانند دروازه فراموشی، دروازه ورودی و غیره) و توابع فعال سازی مختلف (مانند تابع tanh، تابع relu) عبور میکنند و از سلول های LSTM عبور میکنند. مزیت اصلی این است که به هر سلول LSTM اجازه میدهد تا الگوها را برای مدت زمان معینی به خاطر بسپارد. نکته ای که باید به آن توجه داشت این است که LSTM میتواند اطلاعات مهم را به خاطر بسپارد و در عین حال اطلاعات نامربوط را فراموش کند. معماری LSTM در زیر نشان داده شده است:
حالا بیایید مدل را بسازیم. مدل ترتیبی برای انباشته کردن تمام لایه ها (ورودی، مخفی و خروجی) استفاده میشود. شبکه عصبی از یک لایه LSTM و به دنبال آن 20% لایه Dropout و یک لایه متراکم با تابع فعال سازی خطی تشکیل شده است. من مدل را با استفاده از Adam به عنوان بهینه ساز و میانگین مربعات خطا به عنوان تابع ضرر انجام دادم.
def build_lstm_model(input_data, output_size, neurons=100, activ_func=’linear’, dropout=0.2, loss=’mse’, optimizer=’adam’):
model = Sequential()
model.add(LSTM(neurons, input_shape=(input_data.shape[1], input_data.shape[2])))
model.add(Dropout(dropout))
model.add(Dense(units=output_size))
model.add(Activation(activ_func))
model.compile(loss=loss, optimizer=optimizer)
return model
بعد برخی از پارامترها را تنظیم کردم تا بعداً استفاده شوند. این پارامترها عبارتند از: دانه تصادفی، طول پنجره، اندازه مجموعه آزمایشی، تعداد نورون ها در لایه LSTM، دوره ها، اندازه دسته، از دست دادن، حذف و بهینه ساز.
np.random.seed(42)
window_len = 5
test_size = 0.2
zero_base = True
lstm_neurons = 100
epochs = 20
batch_size = 32
loss = ‘mse’
dropout = 0.2
optimizer = ‘adam’
حالا بیایید مدل را با استفاده از ورودی های x_train و برچسب های y_train آموزش دهیم.
train, test, X_train, X_test, y_train, y_test = prepare_data(
hist, target_col, window_len=window_len, zero_base=zero_base, test_size=test_size)
model = build_lstm_model(
X_train, output_size=1, neurons=lstm_neurons, dropout=dropout, loss=loss,
optimizer=optimizer)
history = model.fit(
X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=1, shuffle=True)
اجازه دهید نگاهی به عکس فوری در طول آموزش مدل برای 20 دوره بیندازیم.
من از میانگین خطای مطلق (MAE) به عنوان معیار ارزیابی استفاده کردم. دلیل انتخاب MAE بر RMSE (خطای میانگین مربعات ریشه) این است که MAE قابل تفسیرتر است. RMSE به تنهایی خطای متوسط را توصیف نمیکند و از این رو درک آن بسیار دشوارتر است. از آنجایی که ما میخواهیم این مدل به راحتی حتی برای مخاطبان غیر فنی توضیح داده شود، MAE انتخاب بهتری به نظر میرسد.
میانگین خطای مطلق
میانگین بزرگی خطاها را در مجموعه ای از پیش بینی ها بدون در نظر گرفتن جهت آنها اندازه گیری میکند. این میانگین بیش از نمونه آزمایشی از تفاوت های مطلق بین مشاهدات واقعی و پیش بینی شده است که در آن همه تفاوت های فردی، وزن برابر دارند.
targets = test[target_col][window_len:]
preds = model.predict(X_test).squeeze()
mean_absolute_error(preds, y_test)
# 0.027955859325876943
مقدار MAE بدست آمده خوب به نظر میرسد. در نهایت، بیایید قیمت های واقعی و پیش بینی شده را با استفاده از کد زیر ترسیم کنیم:
preds = test[target_col].values[:-window_len] * (preds + 1)
preds = pd.Series(index=targets.index, data=preds)
line_plot(targets, preds, ‘actual’, ‘prediction’, lw=3)
پیش بینی قیمت ارز دیجیتال: نتیجه گیری
در این مقاله، نحوه پیش بینی قیمت ارزهای دیجیتال را در زمان واقعی با استفاده از شبکه عصبی LSTM نشان دادیم. من یک فرآیند چهار مرحله ای را طی کردم تا داده های ارزهای دیجیتال را در زمان واقعی دریافت کنم، داده ها را برای آموزش و آزمایش آماده کردم، قیمت ها را با استفاده از شبکه عصبی LSTM پیش بینی کردم و نتایج پیش بینی را تجسم کردم. به راحتی میتوانید با پارامترهای فوق بازی کنید یا معماری های مختلف شبکه عصبی را برای نتایج بهتر امتحان کنید.
نظرات کاربران