টিপঃ এই কেসটি শুধুমাত্র গবেষণা এবং শেখার উদ্দেশ্যে এবং এটি কোনও বিনিয়োগের পরামর্শ নয়।
বিটকয়েনের দামের তথ্য সময়সূচীর উপর ভিত্তি করে, তাই বিটকয়েনের দামের পূর্বাভাস বেশিরভাগ এলএসটিএম মডেল ব্যবহার করে করা হয়।
দীর্ঘমেয়াদী স্বল্পমেয়াদী স্মৃতি (LSTM) একটি গভীর শেখার মডেল যা বিশেষ করে সময়কালীন ধারাবাহিক ডেটা (বা সময় / স্থান / কাঠামোগত ক্রম সহ ডেটা, যেমন চলচ্চিত্র, বাক্য ইত্যাদি) এর জন্য উপযুক্ত। এটি ক্রিপ্টোকারেন্সির দামের গতিপথের পূর্বাভাসের জন্য আদর্শ মডেল।
এই নিবন্ধটি মূলত বিটকয়েনের ভবিষ্যতের মূল্য পূর্বাভাস দেওয়ার জন্য এলএসটিএমের মাধ্যমে ডেটা সমন্বয় করার জন্য লেখা।
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
from matplotlib import pyplot as plt
%matplotlib inline
ডেটা লোড হচ্ছে
বিটিসির দৈনিক লেনদেনের তথ্য পড়ুন
data = pd.read_csv(filepath_or_buffer="btc_data_day")
ডেটা পাওয়া যায়, বর্তমানে ১৩৮০টি ডাটা রয়েছে, যা ডেট, ওপেন, হাই, লো, ক্লোজ, ভলিউম (বিটিসি), ভলিউম (মুদ্রা) এবং ওজনযুক্ত মূল্যের কলামগুলির সমন্বয়ে গঠিত।
data.info()
প্রথম ১০টি পংক্তি দেখুন
data.head(10)
ডেটা ভিজ্যুয়ালাইজেশন
matplotlib ব্যবহার করে ওজনযুক্ত মূল্যের একটি মানচিত্র তৈরি করা হয়, যা ডেটার বন্টন এবং প্রবণতা দেখায়। চিত্রে আমরা একটি অংশের ডেটা 0 খুঁজে পেয়েছি, যেখানে আমরা নিশ্চিত করতে চাই যে নিম্নলিখিত ডেটাতে কোনও ব্যতিক্রম আছে কিনা।
plt.plot(data['Weighted Price'], label='Price')
plt.ylabel('Price')
plt.legend()
plt.show()
অস্বাভাবিক তথ্য প্রক্রিয়াকরণ
প্রথমে আমরা দেখব যে, আমাদের ডেটাতে nan-নং ডেটা আছে কি না।
data.isnull().sum()
Date 0
Open 0
High 0
Low 0
Close 0
Volume (BTC) 0
Volume (Currency) 0
Weighted Price 0
dtype: int64
যদি আমরা আবার 0 এর ডেটা দেখি, তাহলে আমরা দেখতে পাব যে আমাদের ডেটাতে 0 আছে, এবং আমাদের 0 এর সাথে কাজ করতে হবে।
(data == 0).astype(int).any()
Date False
Open True
High True
Low True
Close True
Volume (BTC) True
Volume (Currency) True
Weighted Price True
dtype: bool
data['Weighted Price'].replace(0, np.nan, inplace=True)
data['Weighted Price'].fillna(method='ffill', inplace=True)
data['Open'].replace(0, np.nan, inplace=True)
data['Open'].fillna(method='ffill', inplace=True)
data['High'].replace(0, np.nan, inplace=True)
data['High'].fillna(method='ffill', inplace=True)
data['Low'].replace(0, np.nan, inplace=True)
data['Low'].fillna(method='ffill', inplace=True)
data['Close'].replace(0, np.nan, inplace=True)
data['Close'].fillna(method='ffill', inplace=True)
data['Volume (BTC)'].replace(0, np.nan, inplace=True)
data['Volume (BTC)'].fillna(method='ffill', inplace=True)
data['Volume (Currency)'].replace(0, np.nan, inplace=True)
data['Volume (Currency)'].fillna(method='ffill', inplace=True)
(data == 0).astype(int).any()
Date False
Open False
High False
Low False
Close False
Volume (BTC) False
Volume (Currency) False
Weighted Price False
dtype: bool
এখন, তথ্যের বন্টন এবং প্রবণতা দেখুন, এবং এই সময়ে, এই কার্ভটি বেশ ধারাবাহিক।
plt.plot(data['Weighted Price'], label='Price')
plt.ylabel('Price')
plt.legend()
plt.show()
প্রশিক্ষণ ডেটাসেট এবং পরীক্ষার ডেটাসেট বিভক্ত
0 থেকে 0-এ ডেটা একীভূত করুন
data_set = data.drop('Date', axis=1).values
data_set = data_set.astype('float32')
mms = MinMaxScaler(feature_range=(0, 1))
data_set = mms.fit_transform(data_set)
টেস্ট ডেটাসেট এবং প্রশিক্ষণ ডেটাসেটকে ২ঃ৮ দিয়ে বিভক্ত করুন
ratio = 0.8
train_size = int(len(data_set) * ratio)
test_size = len(data_set) - train_size
train, test = data_set[0:train_size,:], data_set[train_size:len(data_set),:]
আমাদের ট্রেনিং ডেটাসেট এবং টেস্ট ডেটাসেট তৈরি করার জন্য ১ দিনের উইন্ডো ব্যবহার করুন।
def create_dataset(data):
window = 1
label_index = 6
x, y = [], []
for i in range(len(data) - window):
x.append(data[i:(i + window), :])
y.append(data[i + window, label_index])
return np.array(x), np.array(y)
train_x, train_y = create_dataset(train)
test_x, test_y = create_dataset(test)
এইবার আমরা একটি সহজ মডেল ব্যবহার করেছি, যার মডেলের কাঠামো হল 1. LSTM2. Dense.
এখানে LSTM এর ইনপুট shape এর ব্যাখ্যা প্রয়োজন, ইনপুট Shape এর ইনপুট মাত্রা হচ্ছে ((batch_size, time steps, features) ); এখানে, time steps মান হল ডাটা ইনপুট করার সময় সময় উইন্ডো ব্যবধান, এখানে আমরা 1 দিন ব্যবহার করি সময় উইন্ডো হিসাবে, এবং আমাদের ডেটা দিন ডেটা, তাই এখানে আমাদের time steps হল 1 ।
লং শর্ট-টার্ম মেমরি (এলএসটিএম) একটি বিশেষ ধরনের আরএনএন, যা মূলত লং সিকোয়েন্স ট্রেনিংয়ের সময় গ্রেডিয়েন্ট বিলুপ্তি এবং গ্রেডিয়েন্ট বিস্ফোরণের সমস্যা সমাধানের জন্য ব্যবহৃত হয়। এখানে লং শর্ট-টার্ম মেমরির সংক্ষিপ্ত বিবরণ দেওয়া হল।
এলএসটিএম এর নেটওয়ার্ক কাঠামোর চিত্র থেকে দেখা যায় যে এলএসটিএম আসলে একটি ছোট মডেল, এতে 3 টি সিগময়েড অ্যাক্টিভেশন ফাংশন, 2 টি ট্যানহ অ্যাক্টিভেশন ফাংশন, 3 টি গুণক এবং 1 টি যোগ রয়েছে।
কোষের অবস্থা
কোষের অবস্থা হল এলএসটিএম-এর কেন্দ্রস্থল, এটি উপরের চিত্রের শীর্ষে থাকা কালো রেখা। এই কালো রেখার নীচে কিছু গেট রয়েছে, যা আমরা পরে দেখব। কোষের অবস্থা প্রতিটি গেটের ফলাফল অনুযায়ী আপডেট করা হবে। নীচে আমরা এই গেটগুলি দেখব এবং আপনি কোষের অবস্থার প্রক্রিয়াটি বুঝতে পারবেন।
এলএসটিএম নেটওয়ার্কগুলি একটি গেট নামে পরিচিত কাঠামোর মাধ্যমে কোষের অবস্থা সম্পর্কে তথ্য মুছে ফেলতে বা যুক্ত করতে পারে। গেটগুলি নির্বাচনীভাবে সিদ্ধান্ত নিতে পারে যে কোন তথ্যটি পাস করা উচিত। গেটগুলির কাঠামোটি একটি সিগময়েড স্তর এবং একটি পয়েন্ট গুণিতকরণের সংমিশ্রণ। যেহেতু সিগময়েড স্তরের আউটপুটটি 0-১ এর মান, 0 কোনওটি পাস করতে পারে না এবং 1 উভয়ই পাস করতে পারে। একটি এলএসটিএমে তিনটি গেট রয়েছে যা কোষের অবস্থা নিয়ন্ত্রণ করে। আমরা নীচে একের পর এক এই গেটগুলি সম্পর্কে জানব।
ভুলে যাওয়া দরজা
এলএসটিএম-এর প্রথম ধাপ হল সেল স্টেট-এর কোন তথ্য বাদ দিতে হবে তা নির্ধারণ করা। এই অংশটি একটি সিগময়েড ইউনিট দ্বারা পরিচালিত হয় যা ভুলে যাওয়া গেট নামে পরিচিত।
আমরা দেখতে পাচ্ছি যে ভুলে যাওয়া দরজাটি $h_{l-1}$ এবং $x_{t}$ বার্তাগুলি দেখে একটি 0 থেকে 1 এর মধ্যে একটি ভেক্টর আউটপুট করে, যার মধ্যে 0 থেকে 1 এর মানটি নির্দেশ করে যে কোষের অবস্থা $C_{t-1}$ এর মধ্যে কোন তথ্যটি কতটুকু সংরক্ষণ বা বর্জন করা হয়েছে। 0 মানে সংরক্ষণ করা হয়নি এবং 1 মানে সংরক্ষণ করা হয়েছে।
গাণিতিক অভিব্যক্তিঃ $f_{t}=\sigma\left ((W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right) $
প্রবেশদ্বার
পরবর্তী ধাপটি হল সেল স্টেটে কোন নতুন তথ্য যুক্ত করা হবে তা নির্ধারণ করা, যা ইনপুট দিয়ে সম্পন্ন হয়।
আমরা দেখতে পাচ্ছি যে $h_{l-1}$ এবং $x_{t}$ বার্তাগুলি আবার একটি ভুলে যাওয়া গেট (sigmoid) এবং ইনপুট গেট (tanh) এ রাখা হয়েছে। কারণ ভুলে যাওয়া গেটের আউটপুটটি 0 - 1 এর মান, সুতরাং যদি ভুলে যাওয়া গেটটি 0 আউটপুট করে তবে ইনপুটের পরে ফলাফল $C_{i}$ বর্তমান কোষের অবস্থানে যুক্ত হবে না, যদি এটি 1 হয় তবে এটি সমস্ত কোষের অবস্থানে যুক্ত হবে, সুতরাং এখানে ভুলে যাওয়া গেটের কাজ হল ইনপুট গেটের ফলাফলটি বেছে বেছে কোষের অবস্থানে যুক্ত করা।
গাণিতিক সূত্র হলঃ $C_{t}=f_{t} * C_{t-1} + i_{t} * \tilde{C}_{t} $
আউটপুট
কোষের অবস্থা আপডেট করার পর $h_{l-1}$ এবং $x_{t}$ যোগের ভিত্তিতে কোষের কোন অবস্থা বৈশিষ্ট্য নির্ণয় করতে হবে, এখানে ইনপুটটি একটি সিগময়েড স্তর যা আউটপুট গেট নামে পরিচিত এর মাধ্যমে নির্ণয় করা হয়, তারপরে কোষের অবস্থাটি tanh স্তর দিয়ে একটি ভেক্টর পাওয়া যায় যা -1 থেকে 1 এর মধ্যে একটি মান পায়, যা ভেক্টরটি আউটপুট গেট দ্বারা প্রাপ্ত সিদ্ধান্তের শর্তের সাথে গুণিত হয় যা চূড়ান্ত RNN ইউনিটের আউটপুট পায়।
def create_model():
model = Sequential()
model.add(LSTM(50, input_shape=(train_x.shape[1], train_x.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')
model.summary()
return model
model = create_model()
history = model.fit(train_x, train_y, epochs=80, batch_size=64, validation_data=(test_x, test_y), verbose=1, shuffle=False)
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show()
train_x, train_y = create_dataset(train)
test_x, test_y = create_dataset(test)
predict = model.predict(test_x)
plt.plot(predict, label='predict')
plt.plot(test_y, label='ground true')
plt.legend()
plt.show()
বর্তমানে মেশিন লার্নিং ব্যবহার করে বিটকয়েনের দীর্ঘমেয়াদী মূল্যের গতিবিধি পূর্বাভাস দেওয়া খুব কঠিন, এই নিবন্ধটি কেবল একটি শেখার কেস হিসাবে ব্যবহার করা যেতে পারে। এই কেসটি পরে মটর পুল মেঘের সাথে ডেমো মিররগুলির মধ্যে সরাসরি অভিজ্ঞতা অর্জন করতে আগ্রহী ব্যবহারকারীদের জন্য চালু হবে।