<jupyter_start><jupyter_text>Loading Data<jupyter_code>import tensorflow as tf
import numpy as np
import pandas as pd
import os
import distutils
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from keras.models import Model
from tensorflow.keras.layers import *
from tensorflow.keras.activations import *
from keras.utils.vis_utils import plot_model
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from datetime import datetime

from google.colab import drive
drive.mount("/content/drive")
from zipfile import ZipFile
file_name = '/content/drive/MyDrive/Machine Learning/g-research-crypto-forecasting.zip'

with ZipFile(file_name, 'r') as zip:
  zip.extractall('g-research-crypto-forecasting')
data_folder = "g-research-crypto-forecasting/"
crypto_df = pd.read_csv(data_folder + 'train.csv')
crypto_df
asset_details = pd.read_csv(data_folder + 'asset_details.csv')
asset_details<jupyter_output><empty_output><jupyter_text>Helper Methods<jupyter_code>def plot_results(history):
  fig, ax = plt.subplots()
  ax.plot(history.history['RMSE'],label = 'train')
  ax.plot(history.history['val_RMSE'],label = 'test')
  ax.set_title('RMSE')
  ax.legend(loc='lower right')
  fig, ax = plt.subplots()
  ax.plot(history.history['MAPE'],label = 'train')
  ax.plot(history.history['val_MAPE'],label = 'test')
  ax.set_title('MAPE')
  ax.legend(loc='lower right')
  fig, ax = plt.subplots()
  ax.plot(history.history['loss'],label = 'train')
  ax.plot(history.history['val_loss'],label = 'test')
  ax.set_title('MSE')
  ax.legend(loc='upper right')
#function to conver d/m/y to time stamp making it easier to split data
def to_time_stamp(s):
  import time
  return np.int32(time.mktime(datetime.strptime(s, "%d/%m/%Y").timetuple()))
#function to get the fixed coin data frame given coin id
def get_crypto_data(crypto_df, id):
  #creates specific coin df
  coin = crypto_df[crypto_df["Asset_ID"]==id].set_index("timestamp")

  #Replaces Null values
  coin.fillna(method ='ffill', inplace = True)

  #removes gaps in time
  coin = coin.reindex(range(coin.index[0],coin.index[-1]+60,60),method='pad')
  
  return coin
#gets the coin data frame and converts it into numpy train test split (used for testing)
def get_split_data_random(coin):
  from sklearn.preprocessing import MinMaxScaler
  # Scalaing data is important
  scaler = MinMaxScaler()

  #converts df to numpy
  coin = coin.to_numpy()

  #gets target price
  y = coin[:, -1]

  #removes id column and target column
  X = np.delete(coin , (0,8), axis=1)

  #creates split
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)

  #scales data
  X_train = scaler.fit_transform(X_train)
  X_test = scaler.transform(X_test)

  return  X_train, X_test, y_train, y_test
def get_split_data(coin):
  from sklearn.preprocessing import MinMaxScaler
  # Scalaing data is important
  scaler = MinMaxScaler()

  # 80/20 split for time 
  train_window = [to_time_stamp("01/01/2018"), to_time_stamp("23/12/2020")]
  test_window = [to_time_stamp("24/12/2020"), to_time_stamp("21/09/2021")]

  #Y is Target price
  Y = coin.Target

  #creates x_train and x_test with the time windows
  X_train = coin.loc[train_window[0]:train_window[1]].to_numpy()
  X_test = coin.loc[test_window[0]:test_window[1]].to_numpy()

  #we remove the id and target col from X
  X_train = np.delete(X_train, (0,8), axis = 1)
  X_test = np.delete(X_test, (0,8), axis = 1)

  #create Y with time windows
  y_train = Y.loc[train_window[0]:train_window[1]].to_numpy()
  y_test = Y.loc[test_window[0]:test_window[1]].to_numpy()

  #scale the data
  X_train = scaler.fit_transform(X_train)
  X_test = scaler.transform(X_test)

  return X_train, X_test, y_train, y_test

#Given a coin dataframe, prints out random forest regression results
def randomForestRegression(coin):
  from sklearn.ensemble import RandomForestRegressor
  #gets data
  X_train, X_test, y_train, y_test = get_split_data(coin)

  #creates random forest
  RF = RandomForestRegressor(n_estimators= 50 , max_depth = 10)
  RF.fit(X_train , y_train)
  
  #predicts targets
  pred = RF.predict(X_test)

  print('Mean absolute error: {:.4f}'.format(mean_absolute_error(y_test,pred)))
  print('Mean squared error: {:.4f}'.format(mean_squared_error(y_test,pred)))

def linearRegression(coin):
  from sklearn.linear_model import LinearRegression
  X_train, X_test, y_train, y_test = get_split_data(coin)

  LR = LinearRegression()
  LR.fit(X_train, y_train)
  pred = LR.predict(X_test)
  print('Mean Squared error: {:.10f}'.format(mean_squared_error(y_test,pred)))
  print('Test score for LR baseline:', f"{np.corrcoef(pred, y_test)[0,1]:.10f}")<jupyter_output><empty_output><jupyter_text>Baselines for BTC , ETH , LTC<jupyter_code>btc = get_crypto_data(crypto_df , 1)
print("Metrics for BTC:")
linearRegression(btc)
print()
print("Metrics for ETH:")
eth = get_crypto_data(crypto_df , 6)
linearRegression(eth)
print()
print("Metrics for LTC:")
ltc = get_crypto_data(crypto_df , 9)
linearRegression(ltc)
print()
btc = get_crypto_data(crypto_df , 1)
X_train, X_test, y_train, y_test = get_split_data(btc)

import matplotlib.pyplot as plt
f = plt.figure(figsize=(30,5))

ax = f.add_subplot(131)
combined = np.concatenate([X_train[:,4],X_test[:,4]])
plt.plot(combined,color = 'red' ,label='Test')
ax.plot(X_train[:,4], label='Train')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Bitcoin')

plt.tight_layout()
plt.show()<jupyter_output><empty_output><jupyter_text>Code for drawing graphs<jupyter_code>import matplotlib.pyplot as plt
f = plt.figure(figsize=(30,5))

ax = f.add_subplot(131)
plt.plot(btc['Close'], label='BTC')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Bitcoin')

ax2 = f.add_subplot(132)
ax2.plot(eth['Close'], color='red', label='ETH')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Ethereum')

ax3 = f.add_subplot(133)
ax3.plot(ltc['Close'], color='green', label='LTC')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Litecoin')

plt.tight_layout()
plt.show()

f = plt.figure(figsize=(30,5))

ax = f.add_subplot(131)
plt.plot(btc['Target'], label='BTC')
ax.plot(eth['Target'], color='red', label='ETH')
ax.plot(ltc['Target'], color='green', label='LTC')
plt.legend()
plt.xlabel('Time')
plt.ylabel('target')

plt.tight_layout()
plt.show()
btc = get_crypto_data(crypto_df , 1)
X_train, X_test, y_train, y_test = get_split_data(btc)
eth = get_crypto_data(crypto_df , 6)
X_train, X_test, y_train, y_test = get_split_data(eth)
ltc = get_crypto_data(crypto_df , 9)
X_train, X_test, y_train, y_test = get_split_data(ltc)
def dense_model(inputs = 7,hidden_1=512, hidden_2=256):
  model = tf.keras.models.Sequential()
  model.add(Dense(hidden_1, input_shape=(inputs,)))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(hidden_2))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(128))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(64))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(1))
  return model

dense = dense_model()
dense.summary() 
dense.compile(optimizer=tf.keras.optimizers.Adam(), loss="mse", metrics=[tf.keras.metrics.RootMeanSquaredError("RMSE") , "MAPE"])
history = dense.fit(
    X_train, y_train,
    epochs =  10, 
    batch_size= 2048, 
    verbose = 1,
    validation_data=(X_test, y_test),
)


print('Final accuracy on training set: {:.10f}'.format(history.history['loss'][-1]))
print('Final accuracy on test set: {:.10f}'.format(history.history['val_loss'][-1]))
print('Mean Squared Error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_loss'][-5:])))
print('Mean Root Mean Squared error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_RMSE'][-5:])))
print('Mean Apolute Percentage error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_MAPE'][-5:])))
plot_results(history)
pred = dense(X_test).numpy()
pred= pred.reshape(-1)

f = plt.figure(figsize=(30,5))

ax = f.add_subplot(131)
ax.plot(y_test, label = 'actual')
ax.plot(pred , label = 'predicted' , color = 'red')
plt.legend()
plt.xlabel('Time')
plt.ylabel('target')

plt.tight_layout()
plt.show()<jupyter_output><empty_output><jupyter_text>Data Augmentation<jupyter_code>#adds upper shadow, lowershadow, high/low, and open - close to data 
def get_features(df):
    df_feat = df[['Asset_ID','Count', 'Open', 'High', 'Low', 'Close', 'Volume', 'VWAP', 'Target']].copy()
    df_feat['upper_Shadow'] = df['High'] - np.maximum(df['Close'], df['Open'])
    df_feat['lower_Shadow'] = np.minimum(df['Close'], df['Open']) - df['Low']
    df_feat["high_div_low"] = df_feat["High"] / df_feat["Low"]
    df_feat["open_sub_close"] = df_feat["Open"] - df_feat["Close"]
    return df_feat
def rolling_mean(series, window): return series.rolling(window).mean()
def rolling_std(series, window): return series.rolling(window).std()
def rolling_sum(series, window): return series.rolling(window).sum()
def ewma(series, span, min_periods): return series.ewm(span = span, min_periods = min_periods).mean()
#Moving Average
def MA(df, n = 15):
    MA = pd.Series(rolling_mean(df['Close'], n), name = 'MA_' + str(n))
    df['MA'] = MA
    return df

#Exponential Moving Average
def EMA(df, n = 15):
    EMA = pd.Series(ewma(df['Close'], span = n, min_periods = n - 1), name = 'EMA_' + str(n))
    df['EMA'] = EMA
    return df

#Momentum
def MOM(df, n = 15):
    M = pd.Series(df['Close'].diff(n), name = 'Momentum_' + str(n))
    df['MOM'] = M
    return df

#Rate of Change
def ROC(df, n = 15):
    M = df['Close'].diff(n - 1)
    N = df['Close'].shift(n - 1)
    ROC = pd.Series(M / N, name = 'ROC_' + str(n))
    df['ROC'] = ROC
    return df


#after you call these you have to use .fillna(method = 'bfill')<jupyter_output><empty_output><jupyter_text>Testing Data Augmentation<jupyter_code>btc = get_crypto_data(crypto_df , 1)
btc = get_features(btc)
btc = MA(btc)
btc = EMA(btc)
btc = MOM(btc)
btc = ROC(btc)

btc.fillna(method = 'bfill' , inplace = True)
btc_X_train, btc_X_test, btc_y_train, btc_y_test = get_split_data(btc)
eth = get_crypto_data(crypto_df , 6)
eth = get_features(btc)
eth = MA(eth)
eth = EMA(eth)
eth = MOM(eth)
eth = ROC(eth)

eth.fillna(method = 'bfill' , inplace = True)
eth_X_train, eth_X_test, eth_y_train, eth_y_test = get_split_data(eth)
ltc = get_crypto_data(crypto_df , 9)
ltc = get_features(ltc)
ltc = MA(ltc)
ltc = EMA(ltc)
ltc = MOM(ltc)
ltc = ROC(ltc)

ltc.fillna(method = 'bfill' , inplace = True)
ltc_X_train, ltc_X_test, ltc_y_train, ltc_y_test = get_split_data(ltc)
def dense_model(inputs = 7,hidden_1=512, hidden_2=256):
  model = tf.keras.models.Sequential()
  model.add(Dense(hidden_1, input_shape=(inputs,)))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(hidden_2))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(128))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(64))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(1))
  return model

dense = dense_model(inputs=14)
dense.summary() 
dense.compile(optimizer=tf.keras.optimizers.Adam(), loss="mse", metrics=[tf.keras.metrics.RootMeanSquaredError("RMSE") , "MAPE"])
history = dense.fit(
    btc_X_train, btc_y_train,
    epochs =  10, 
    batch_size= 2048, 
    verbose = 1,
    validation_data=(btc_X_test, btc_y_test),
)


print('Final accuracy on training set: {:.10f}'.format(history.history['loss'][-1]))
print('Final accuracy on test set: {:.10f}'.format(history.history['val_loss'][-1]))
print('Mean Squared Error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_loss'][-5:])))
print('Mean Root Mean Squared error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_RMSE'][-5:])))
print('Mean Apolute Percentage error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_MAPE'][-5:])))
history = dense.fit(
    eth_X_train, eth_y_train,
    epochs =  10, 
    batch_size= 2048, 
    verbose = 1,
    validation_data=(eth_X_test, eth_y_test),
)


print('Final accuracy on training set: {:.10f}'.format(history.history['loss'][-1]))
print('Final accuracy on test set: {:.10f}'.format(history.history['val_loss'][-1]))
print('Mean Squared Error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_loss'][-5:])))
print('Mean Root Mean Squared error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_RMSE'][-5:])))
print('Mean Apolute Percentage error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_MAPE'][-5:])))
history = dense.fit(
    ltc_X_train, ltc_y_train,
    epochs =  10, 
    batch_size= 2048, 
    verbose = 1,
    validation_data=(ltc_X_test, ltc_y_test),
)


print('Final accuracy on training set: {:.10f}'.format(history.history['loss'][-1]))
print('Final accuracy on test set: {:.10f}'.format(history.history['val_loss'][-1]))
print('Mean Squared Error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_loss'][-5:])))
print('Mean Root Mean Squared error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_RMSE'][-5:])))
print('Mean Apolute Percentage error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_MAPE'][-5:])))
plot_results(history)<jupyter_output><empty_output><jupyter_text>Combining Multiple coins<jupyter_code>all_X_train = np.concatenate((btc_X_train, eth_X_train , ltc_X_train), axis=0)
all_X_test = np.concatenate((btc_X_test, eth_X_test , ltc_X_test), axis=0)

all_y_train = np.concatenate((btc_y_train, eth_y_train , ltc_y_train), axis=0)
all_y_test = np.concatenate((btc_y_test, eth_y_test , ltc_y_test), axis=0)
def dense_model(inputs = 7,hidden_1=512, hidden_2=256):
  model = tf.keras.models.Sequential()
  model.add(Dense(hidden_1, input_shape=(inputs,)))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(hidden_2))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(128))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(64))
  model.add(Dropout(.25))
  model.add(BatchNormalization())
  model.add(Dense(1))
  return model

dense = dense_model(inputs=14)
dense.summary() 
dense.compile(optimizer=tf.keras.optimizers.Adam(), loss="mse", metrics=[tf.keras.metrics.RootMeanSquaredError("RMSE") , "MAPE"])
history = dense.fit(
    all_X_train, all_y_train,
    epochs =  10, 
    batch_size= 2048, 
    verbose = 1,
    validation_data=(all_X_test, all_y_test),
)


print('Final accuracy on training set: {:.10f}'.format(history.history['loss'][-1]))
print('Final accuracy on test set: {:.10f}'.format(history.history['val_loss'][-1]))
print('Mean Squared Error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_loss'][-5:])))
print('Mean Root Mean Squared error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_RMSE'][-5:])))
print('Mean Apolute Percentage error in last 5 epochs: {:.10f}'.format(np.mean(history.history['val_MAPE'][-5:])))
plot_results(history)
pred = dense(all_X_test).numpy()
pred= pred.reshape(-1)

f = plt.figure(figsize=(30,5))

ax = f.add_subplot(131)
ax.plot(all_y_test, label = 'actual')
ax.plot(pred , label = 'predicted' , color = 'red')
plt.legend()
plt.xlabel('Time')
plt.ylabel('target')

plt.tight_layout()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16465994142531729, 'fraction_numerical': 0.022974292222583795, 'mean_word_length': 5.7247264770240704, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '300462', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 6258, 'n_tokens_neox': 5825, 'n_words': 1139, 'path': 'ML_Final_Project.ipynb', 'repo_name': 'EstevanRamos/.github.io', 'size': '15365'}