FeedForward Neural Network
In [ ]:
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import Normalizer, MinMaxScaler
from sklearn.pipeline import make_pipeline
# from dataloader import DatasetHandler
# from model import MarketClassifier
import tensorflow_docs as tfdocs
import tensorflow_docs.modeling
import tensorflow_docs.plots
from tensorflow import keras
import tensorflow as tf
import seaborn as sns
import pandas as pd
import numpy as np
In [ ]:
import pandas as pd
class DatasetHandler:
def __init__(self):
pass
@staticmethod
def create_train_test(data: pd.DataFrame, y_col:str, sample_fraction:int=.8):
# create train_x, train_y, test_x, test_y.
train = data.sample(frac=sample_fraction, random_state=42)
train_x = train.drop(columns=[y_col])
train_y = train[y_col]
test = data.drop(train.index)
test_x = test.drop(columns=[y_col])
test_y = test[y_col]
assert train_x.shape[0] == train_y.shape[0]
assert test_x.shape[0] == test_y.shape[0]
print(f"Number of train record={train_x.shape}, test records={test_x.shape}")
return (train_x, train_y, test_x, test_y)
In [ ]:
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.models import Sequential
import tensorflow as tf
class MarketClassifier(tf.keras.Model):
def __init__(self, input_shape, **kwargs):
super().__init__(**kwargs)
self.input_dim = [input_shape]
self.layer_1 = Dense(16, activation= tf.nn.relu, input_shape=[input_shape[1]])
self.layer_2 = Dense(32, activation= tf.nn.relu)
self.layer_3 = Dense(16, activation= tf.nn.relu)
self.out = Dense(1, activation=tf.nn.sigmoid)
def call(self, inputs):
x = self.layer_1(inputs)
x = self.layer_2(x)
x = self.layer_3(x)
x = self.out(x)
return x
In [ ]:
data = pd.read_csv('data/market.csv')
data.drop(columns=['Year'], inplace=True)
data.dropna(inplace=True)
print(np.unique(data.Direction, return_counts=True))
data.head(3)
(array(['Down', 'Up'], dtype=object), array([602, 648], dtype=int64))
Out[ ]:
Lag1 | Lag2 | Lag3 | Lag4 | Lag5 | Volume | Today | Direction | |
---|---|---|---|---|---|---|---|---|
0 | 0.381 | -0.192 | -2.624 | -1.055 | 5.010 | 1.1913 | 0.959 | Up |
1 | 0.959 | 0.381 | -0.192 | -2.624 | -1.055 | 1.2965 | 1.032 | Up |
2 | 1.032 | 0.959 | 0.381 | -0.192 | -2.624 | 1.4112 | -0.623 | Down |
In [ ]:
# Encoding the target y
label_binarizer = LabelBinarizer()
data.Direction = label_binarizer.fit_transform(data.Direction)
# train - test
(train_x, train_y, test_x, test_y) = DatasetHandler.create_train_test(data=data, y_col='Direction', sample_fraction=0.8)
# Feature scaling
scaler = make_pipeline(MinMaxScaler(), Normalizer())
train_scal = scaler.fit_transform(train_x)
test_scal = scaler.fit_transform(test_x)
Number of train record=(1000, 7), test records=(250, 7)
In [ ]:
model = MarketClassifier(input_shape=train_scal.shape)
######################## Summary
model.build(train_scal.shape)
model.summary()
Model: "market_classifier_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_12 (Dense) multiple 128 dense_13 (Dense) multiple 544 dense_14 (Dense) multiple 528 dense_15 (Dense) multiple 17 ================================================================= Total params: 1,217 Trainable params: 1,217 Non-trainable params: 0 _________________________________________________________________
In [ ]:
METRICS = [
keras.metrics.TruePositives(name='tp'),
keras.metrics.FalsePositives(name='fp'),
keras.metrics.TrueNegatives(name='tn'),
keras.metrics.FalseNegatives(name='fn'),
keras.metrics.BinaryAccuracy(name='accuracy'),
keras.metrics.Precision(name='precision'),
keras.metrics.Recall(name='recall'),
keras.metrics.AUC(name='auc'),
keras.metrics.AUC(name='prc', curve='PR'), # precision-recall curve
]
optimizer = keras.optimizers.Adam(learning_rate=.001)
loss_function = keras.losses.BinaryCrossentropy()
model.compile(optimizer=optimizer, loss= loss_function, metrics=METRICS)
In [ ]:
early_stop=tf.keras.callbacks.EarlyStopping( monitor='val_loss', patience=50)
history = model.fit(
x=train_scal,
y=train_y,
epochs=1000,
validation_split = 0.1,
verbose=0,
callbacks=[early_stop, tfdocs.modeling.EpochDots()]
)
Epoch: 0, accuracy:0.5189, auc:0.6762, fn:29.0000, fp:404.0000, loss:0.6895, prc:0.6977, precision:0.5162, recall:0.9370, tn:36.0000, tp:431.0000, val_accuracy:0.5700, val_auc:0.7977, val_fn:0.0000, val_fp:43.0000, val_loss:0.6853, val_prc:0.8006, val_precision:0.5426, val_recall:1.0000, val_tn:6.0000, val_tp:51.0000, .................................................................................................... Epoch: 100, accuracy:0.8656, auc:0.9457, fn:55.0000, fp:66.0000, loss:0.2980, prc:0.9437, precision:0.8599, recall:0.8804, tn:374.0000, tp:405.0000, val_accuracy:0.9000, val_auc:0.9716, val_fn:7.0000, val_fp:3.0000, val_loss:0.2394, val_prc:0.9718, val_precision:0.9362, val_recall:0.8627, val_tn:46.0000, val_tp:44.0000, .................................................................................................... Epoch: 200, accuracy:0.8722, auc:0.9496, fn:57.0000, fp:58.0000, loss:0.2862, prc:0.9494, precision:0.8742, recall:0.8761, tn:382.0000, tp:403.0000, val_accuracy:0.9000, val_auc:0.9734, val_fn:7.0000, val_fp:3.0000, val_loss:0.2308, val_prc:0.9721, val_precision:0.9362, val_recall:0.8627, val_tn:46.0000, val_tp:44.0000, ...........................................................................
In [ ]:
evals = model.evaluate(test_scal,test_y, verbose=2)
plot_obj = tfdocs.plots.HistoryPlotter(smoothing_std=2)
plot_obj.plot({'Auto MPG': history}, metric = "precision",)
8/8 - 0s - loss: 0.3041 - tp: 119.0000 - fp: 15.0000 - tn: 98.0000 - fn: 18.0000 - accuracy: 0.8680 - precision: 0.8881 - recall: 0.8686 - auc: 0.9474 - prc: 0.9579 - 147ms/epoch - 18ms/step
In [ ]:
model.save("ClassficationModel")
# reconstructed_model = tf.keras.models.load_model( 'ClassficationModel' )
INFO:tensorflow:Assets written to: ClassficationModel\assets