mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
update neural networks typing and add new preprocessing (add actual normalization and correctly rename nrormalization to mimax)
This commit is contained in:
@@ -23,7 +23,7 @@ MultiLayer_Perceptron = [
|
||||
{"Dense": {"units": 100, "activation": "relu"}},
|
||||
{"Dense": {"units": 80, "activation": "relu"}},
|
||||
{"Dense": {"units": 30, "activation": "relu"}},
|
||||
{"Dense": {"activation": "linear"}},
|
||||
{"Dense": {"activation": "relu"}},
|
||||
]
|
||||
|
||||
Recurrent_Neural_Network = [
|
||||
@@ -31,11 +31,11 @@ Recurrent_Neural_Network = [
|
||||
{"SimpleRNN": {"units": 50, "activation": "linear", "return_sequences": True}},
|
||||
{"Dropout": {"rate": 0.2}},
|
||||
{"SimpleRNN": {"units": 21, "activation": "linear", "return_sequences": False}},
|
||||
{"Dense": {"activation": "linear"}},
|
||||
{"Dense": {"activation": "relu"}},
|
||||
]
|
||||
|
||||
Long_Short_Term_Memory = [
|
||||
{"LSTM": {"units": 25, "activation": "tanh", "return_sequences": True}},
|
||||
{"LSTM": {"units": 15, "activation": "tanh", "return_sequences": False}},
|
||||
{"Dense": {"activation": "linear"}},
|
||||
{"Dense": {"activation": "relu"}},
|
||||
]
|
||||
|
||||
@@ -153,7 +153,7 @@ Facebook's Prophet:
|
||||
|
||||
## mlp <a name="mlp"></a>
|
||||
```
|
||||
usage: mlp [-d N_DAYS] [-i N_INPUTS] [-j N_JUMPS] [--epochs N_EPOCHS] [-p {normalization,standardization,none}]
|
||||
usage: mlp [-d N_DAYS] [-i N_INPUTS] [-j N_JUMPS] [--epochs N_EPOCHS] [-p {minmax, normalization,standardization,none}]
|
||||
[-o {adam,adagrad,adadelta,adamax,ftrl,nadam,optimizer,rmsprop,sgd}] [-l {mae,mape,mse,msle}] [-e S_END_DATE] [--loops N_LOOPS]
|
||||
```
|
||||
MulitLayer Perceptron:
|
||||
@@ -161,7 +161,7 @@ MulitLayer Perceptron:
|
||||
* -i : number of days to use for prediction. Default 40.
|
||||
* -j : number of jumps in training data. Default 1.
|
||||
* --epochs : number of training epochs. Default 200.
|
||||
* -p : pre-processing data. Default normalization.
|
||||
* -p : pre-processing data. Default minmax.
|
||||
* -o : optimization technique. Default adam.
|
||||
* -l : loss function. Default mae.
|
||||
* -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None.
|
||||
@@ -183,7 +183,7 @@ MultiLayer_Perceptron \
|
||||
{'Dense':
|
||||
{'units':30, 'activation':'relu'} },
|
||||
{'Dense':
|
||||
{'activation':'linear'} }]
|
||||
{'activation':'relu'} }]
|
||||
```
|
||||
|
||||

|
||||
@@ -220,7 +220,7 @@ Recurrent_Neural_Network \
|
||||
{'SimpleRNN':
|
||||
{'units':21, 'activation':'linear', 'return_sequences':False} },
|
||||
{'Dense':
|
||||
{'activation':'linear'} }]
|
||||
{'activation':'relu'} }]
|
||||
```
|
||||
|
||||

|
||||
@@ -260,7 +260,7 @@ Long_Short_Term_Memory \
|
||||
{'LSTM':
|
||||
{'units':15, 'activation':'tanh', 'return_sequences':False} },
|
||||
{'Dense':
|
||||
{'activation':'linear'} }]
|
||||
{'activation':'relu'} }]
|
||||
```
|
||||
|
||||

|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import List
|
||||
from typing import List, Union
|
||||
import datetime
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
@@ -49,7 +49,7 @@ def check_valid_seasonal(seasonal: str) -> str:
|
||||
)
|
||||
|
||||
|
||||
def exponential_smoothing(other_args:List[str], s_ticker:str, df_stock:pd.DataFrame):
|
||||
def exponential_smoothing(other_args: List[str], s_ticker: str, df_stock: pd.DataFrame):
|
||||
"""
|
||||
Perform exponential smoothing forecasting
|
||||
Parameters
|
||||
@@ -409,12 +409,14 @@ def exponential_smoothing(other_args:List[str], s_ticker:str, df_stock:pd.DataFr
|
||||
print("")
|
||||
|
||||
|
||||
def get_exponential_smoothing_model(data:pd.Series, trend, seasonal, seasonal_periods):
|
||||
def get_exponential_smoothing_model(
|
||||
data: Union[pd.Series, np.ndarray], trend, seasonal, seasonal_periods
|
||||
):
|
||||
"""
|
||||
Perform exponential smoothing
|
||||
Parameters
|
||||
----------
|
||||
data: pd.Series
|
||||
data: Union[pd.Series, np.ndarray]
|
||||
Series of closing values
|
||||
trend: str
|
||||
Trend component. One of [N, A, Ad]
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
""" Neural Networks View"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import List, Any
|
||||
import datetime
|
||||
import os
|
||||
import traceback
|
||||
@@ -8,7 +12,7 @@ import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
from TimeSeriesCrossValidation import splitTrain
|
||||
from sklearn.preprocessing import MinMaxScaler, StandardScaler
|
||||
from sklearn.preprocessing import MinMaxScaler, StandardScaler, Normalizer
|
||||
from tensorflow.keras.models import Sequential
|
||||
from tensorflow.keras.layers import LSTM, SimpleRNN, Dense, Dropout
|
||||
|
||||
@@ -44,7 +48,9 @@ ORIGINAL_TF_XLA_FLAGS = os.environ.get("TF_XLA_FLAGS")
|
||||
ORIGINAL_TF_FORCE_GPU_ALLOW_GROWTH = os.environ.get("TF_FORCE_GPU_ALLOW_GROWTH")
|
||||
|
||||
|
||||
def build_neural_network_model(Recurrent_Neural_Network, n_inputs, n_days):
|
||||
def build_neural_network_model(
|
||||
Recurrent_Neural_Network: List[Any], n_inputs: int, n_days: int
|
||||
):
|
||||
model = Sequential()
|
||||
|
||||
for idx_layer, d_layer in enumerate(Recurrent_Neural_Network):
|
||||
@@ -91,9 +97,24 @@ def build_neural_network_model(Recurrent_Neural_Network, n_inputs, n_days):
|
||||
return model
|
||||
|
||||
|
||||
def _parse_args(prog, description, l_args):
|
||||
"""Create an argparser and parse l_args. Will print help if user requests it.
|
||||
:return: ns_parser"""
|
||||
def _parse_args(prog: str, description: str, other_args: List[str]):
|
||||
"""
|
||||
Create an argparser and parse other_args. Will print help if user requests it.
|
||||
Parameters
|
||||
----------
|
||||
prog: str
|
||||
Program for argparser
|
||||
description: str
|
||||
Description for argparser
|
||||
other_args
|
||||
Argparse arguments to pass
|
||||
Returns
|
||||
-------
|
||||
ns_parser: argparse.Namespace
|
||||
|
||||
Parsed argument parser
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=prog,
|
||||
description=description,
|
||||
@@ -140,8 +161,8 @@ def _parse_args(prog, description, l_args):
|
||||
"--pp",
|
||||
action="store",
|
||||
dest="s_preprocessing",
|
||||
default="normalization",
|
||||
choices=["normalization", "standardization", "none"],
|
||||
default="minmax",
|
||||
choices=["normalization", "standardization", "minmax", "none"],
|
||||
help="pre-processing data.",
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -233,7 +254,7 @@ def _parse_args(prog, description, l_args):
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, l_args)
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
if not ns_parser:
|
||||
return None
|
||||
|
||||
@@ -276,10 +297,27 @@ def _restore_env():
|
||||
restore("TF_FORCE_GPU_ALLOW_GROWTH", ORIGINAL_TF_FORCE_GPU_ALLOW_GROWTH)
|
||||
|
||||
|
||||
def _setup_backtesting(df_stock, ns_parser):
|
||||
"""Set up backtesting if enabled
|
||||
:return: (df_stock, df_future), where df_future is None if s_end_date is not set.
|
||||
:raises Exception: if configuration is invalid"""
|
||||
def _setup_backtesting(df_stock: pd.DataFrame, ns_parser: argparse.Namespace):
|
||||
"""
|
||||
Setup backtesting when end data is specified
|
||||
Parameters
|
||||
----------
|
||||
df_stock: pd.DataFrame
|
||||
Stock data
|
||||
ns_parser: argparse.Namespace
|
||||
Parsed arguments
|
||||
Returns
|
||||
-------
|
||||
df_stock: pd.DataFrame
|
||||
Data before end date
|
||||
df_future: pd.DataFrame
|
||||
Data after end date
|
||||
Raises
|
||||
-------
|
||||
Exception
|
||||
If configuration is invalid
|
||||
"""
|
||||
|
||||
df_future = None
|
||||
if ns_parser.s_end_date:
|
||||
if ns_parser.s_end_date < df_stock.index[0]:
|
||||
@@ -319,11 +357,16 @@ def _preprocess_split(df_stock, ns_parser):
|
||||
stock_train_data = scaler.fit_transform(
|
||||
np.array(df_stock["5. adjusted close"].values.reshape(-1, 1))
|
||||
)
|
||||
elif ns_parser.s_preprocessing == "normalization":
|
||||
elif ns_parser.s_preprocessing == "minmax":
|
||||
scaler = MinMaxScaler()
|
||||
stock_train_data = scaler.fit_transform(
|
||||
np.array(df_stock["5. adjusted close"].values.reshape(-1, 1))
|
||||
)
|
||||
elif ns_parser.s_preprocessing == "normalization":
|
||||
scaler = Normalizer()
|
||||
stock_train_data = scaler.fit_transform(
|
||||
np.array(df_stock["5. adjusted close"].values.reshape(-1, 1))
|
||||
)
|
||||
else: # No pre-processing
|
||||
stock_train_data = np.array(df_stock["5. adjusted close"].values.reshape(-1, 1))
|
||||
|
||||
@@ -343,8 +386,10 @@ def _preprocess_split(df_stock, ns_parser):
|
||||
|
||||
def _rescale_data(df_stock, ns_parser, scaler, yhat, idx_loop):
|
||||
"""Re-scale the data back and return the prediction dataframe."""
|
||||
if (ns_parser.s_preprocessing == "standardization") or (
|
||||
ns_parser.s_preprocessing == "normalization"
|
||||
if (
|
||||
(ns_parser.s_preprocessing == "standardization")
|
||||
or (ns_parser.s_preprocessing == "normalization")
|
||||
or (ns_parser.s_preprocessing == "minmax")
|
||||
):
|
||||
y_pred_test_t = scaler.inverse_transform(yhat.tolist())
|
||||
else:
|
||||
@@ -699,10 +744,25 @@ def _plot_and_print_results(
|
||||
print("")
|
||||
|
||||
|
||||
def mlp(l_args, s_ticker, df_stock):
|
||||
def mlp(other_args: List[str], s_ticker: str, df_stock: pd.DataFrame):
|
||||
"""
|
||||
Train a multi-layer perceptron model
|
||||
Parameters
|
||||
----------
|
||||
other_args: List[str]
|
||||
Argparse Arguments
|
||||
s_ticker: str
|
||||
Ticker
|
||||
df_stock: pd.DataFrame
|
||||
Loaded stock dataframe
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
"""
|
||||
try:
|
||||
ns_parser = _parse_args(
|
||||
prog="mlp", description="""Multilayer Perceptron. """, l_args=l_args
|
||||
prog="mlp", description="""Multilayer Perceptron. """, other_args=other_args
|
||||
)
|
||||
if not ns_parser:
|
||||
return
|
||||
@@ -768,10 +828,12 @@ def mlp(l_args, s_ticker, df_stock):
|
||||
_restore_env()
|
||||
|
||||
|
||||
def rnn(l_args, s_ticker, df_stock):
|
||||
def rnn(other_args: List[str], s_ticker, df_stock):
|
||||
try:
|
||||
ns_parser = _parse_args(
|
||||
prog="rnn", description="""Recurrent Neural Network. """, l_args=l_args
|
||||
prog="rnn",
|
||||
description="""Recurrent Neural Network. """,
|
||||
other_args=other_args,
|
||||
)
|
||||
if not ns_parser:
|
||||
return
|
||||
@@ -839,10 +901,12 @@ def rnn(l_args, s_ticker, df_stock):
|
||||
_restore_env()
|
||||
|
||||
|
||||
def lstm(l_args, s_ticker, df_stock):
|
||||
def lstm(other_args: List[str], s_ticker, df_stock):
|
||||
try:
|
||||
ns_parser = _parse_args(
|
||||
prog="lstm", description="""Long-Short Term Memory. """, l_args=l_args
|
||||
prog="lstm",
|
||||
description="""Long-Short Term Memory. """,
|
||||
other_args=other_args,
|
||||
)
|
||||
if not ns_parser:
|
||||
return
|
||||
@@ -15,7 +15,7 @@ from gamestonk_terminal.prediction_techniques import (
|
||||
arima_view,
|
||||
ets_view,
|
||||
knn,
|
||||
neural_networks,
|
||||
neural_networks_view,
|
||||
regression,
|
||||
sma,
|
||||
)
|
||||
@@ -159,15 +159,15 @@ class PredictionTechniquesController:
|
||||
|
||||
def call_mlp(self, other_args: List[str]):
|
||||
"""Process mlp command"""
|
||||
neural_networks.mlp(other_args, self.ticker, self.stock)
|
||||
neural_networks_view.mlp(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_rnn(self, other_args: List[str]):
|
||||
"""Process rnn command"""
|
||||
neural_networks.rnn(other_args, self.ticker, self.stock)
|
||||
neural_networks_view.rnn(other_args, self.ticker, self.stock)
|
||||
|
||||
def call_lstm(self, other_args: List[str]):
|
||||
"""Process lstm command"""
|
||||
neural_networks.lstm(other_args, self.ticker, self.stock)
|
||||
neural_networks_view.lstm(other_args, self.ticker, self.stock)
|
||||
|
||||
if gtff.ENABLE_FBPROPHET:
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
""" Prediction helper functions """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from colorama import Fore, Style
|
||||
@@ -11,6 +14,7 @@ from gamestonk_terminal import feature_flags as gtff
|
||||
|
||||
|
||||
def price_prediction_color(val: float, last_val: float) -> str:
|
||||
"""Set prediction to be a colored string"""
|
||||
if float(val) > last_val:
|
||||
color = Fore.GREEN
|
||||
else:
|
||||
@@ -19,6 +23,7 @@ def price_prediction_color(val: float, last_val: float) -> str:
|
||||
|
||||
|
||||
def print_pretty_prediction(df_pred: pd.DataFrame, last_price: float):
|
||||
"""Print predictions"""
|
||||
if gtff.USE_COLOR:
|
||||
print(f"Actual price: {Fore.YELLOW}{last_price:.2f} ${Style.RESET_ALL}\n")
|
||||
print("Prediction:")
|
||||
@@ -44,12 +49,14 @@ def print_pretty_prediction_nn(df_pred: pd.DataFrame, last_price: float):
|
||||
print(df_pred.to_string())
|
||||
|
||||
|
||||
def mean_absolute_percentage_error(y_true, y_pred):
|
||||
def mean_absolute_percentage_error(y_true: np.ndarray, y_pred: np.ndarray) -> np.number:
|
||||
"""Calculate mean absolute percent error"""
|
||||
y_true, y_pred = np.array(y_true), np.array(y_pred)
|
||||
return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
|
||||
|
||||
|
||||
def print_prediction_kpis(real, pred):
|
||||
def print_prediction_kpis(real: np.ndarray, pred: np.ndarray):
|
||||
"""Print prediction statistics"""
|
||||
print("KPIs")
|
||||
print(f"MAPE: {mean_absolute_percentage_error(real, pred):.3f} %")
|
||||
print(f"R2: {r2_score(real, pred):.3f}")
|
||||
@@ -59,6 +66,7 @@ def print_prediction_kpis(real, pred):
|
||||
|
||||
|
||||
def price_prediction_backtesting_color(val: list) -> str:
|
||||
"""Add color to backtest data"""
|
||||
err_pct = 100 * (val[0] - val[1]) / val[1]
|
||||
if val[0] > val[1]:
|
||||
s_err_pct = f" {Fore.GREEN} +{err_pct:.2f} %"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from gamestonk_terminal.prediction_techniques.neural_networks import mlp
|
||||
from gamestonk_terminal.prediction_techniques.neural_networks_view import mlp
|
||||
except ModuleNotFoundError as e:
|
||||
print("One of the optional packages seems to be missing")
|
||||
print(e)
|
||||
|
||||
Reference in New Issue
Block a user