mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 21:12:16 +00:00
refactor train/valid data
This commit is contained in:
@@ -105,10 +105,10 @@ def k_nearest_neighbors(other_args: List[str], s_ticker: str, df_stock: pd.DataF
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--test_size",
|
||||
default = .2,
|
||||
default=0.2,
|
||||
dest="test_size",
|
||||
type = float,
|
||||
help = "Percentage of data to validate in sample"
|
||||
type=float,
|
||||
help="Percentage of data to validate in sample",
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -29,6 +29,7 @@ from gamestonk_terminal.prediction_techniques.pred_helper import (
|
||||
print_pretty_prediction_nn,
|
||||
price_prediction_backtesting_color,
|
||||
print_prediction_kpis,
|
||||
prepare_scale_train_valid_test,
|
||||
)
|
||||
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
@@ -143,7 +144,7 @@ def _parse_args(prog: str, description: str, other_args: List[str]):
|
||||
action="store",
|
||||
dest="n_epochs",
|
||||
type=check_positive,
|
||||
default=200,
|
||||
default=50,
|
||||
help="number of training epochs.",
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -251,6 +252,14 @@ def _parse_args(prog: str, description: str, other_args: List[str]):
|
||||
default=1,
|
||||
help="number of loops to iterate and train models",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--valid",
|
||||
type=float,
|
||||
dest="valid_split",
|
||||
default=0.1,
|
||||
help="Validation data split fraction",
|
||||
)
|
||||
|
||||
try:
|
||||
ns_parser = parse_known_args_and_warn(parser, other_args)
|
||||
@@ -1016,59 +1025,80 @@ def lstm(other_args: List[str], s_ticker: str, df_stock: pd.DataFrame):
|
||||
return
|
||||
|
||||
# Setup backtesting
|
||||
df_stock, df_future = _setup_backtesting(df_stock, ns_parser)
|
||||
# df_stock, df_future = _setup_backtesting(df_stock, ns_parser)
|
||||
|
||||
# Pre-process data
|
||||
scaler, stock_train_data, stock_x, stock_y = _preprocess_split(
|
||||
df_stock, ns_parser
|
||||
)
|
||||
stock_x = np.reshape(stock_x, (stock_x.shape[0], stock_x.shape[1], 1))
|
||||
stock_y = np.reshape(stock_y, (stock_y.shape[0], stock_y.shape[1], 1))
|
||||
# scaler, stock_train_data, stock_x, stock_y = _preprocess_split(
|
||||
# df_stock, ns_parser
|
||||
# )
|
||||
# stock_x = np.reshape(stock_x, (stock_x.shape[0], stock_x.shape[1], 1))
|
||||
# stock_y = np.reshape(stock_y, (stock_y.shape[0], stock_y.shape[1], 1))
|
||||
|
||||
(
|
||||
X_train,
|
||||
X_test,
|
||||
y_train,
|
||||
y_test,
|
||||
X_dates_train,
|
||||
X_dates_test,
|
||||
y_dates_train,
|
||||
y_dates_test,
|
||||
test_data,
|
||||
dates_test,
|
||||
scaler,
|
||||
) = prepare_scale_train_valid_test(df_stock, ns_parser)
|
||||
# Build Neural Network model
|
||||
model = build_neural_network_model(
|
||||
cfg_nn_models.Long_Short_Term_Memory, ns_parser.n_inputs, ns_parser.n_days
|
||||
)
|
||||
model.compile(optimizer=ns_parser.s_optimizer, loss=ns_parser.s_loss)
|
||||
|
||||
for idx_loop in range(ns_parser.n_loops):
|
||||
# Train our model
|
||||
model.fit(
|
||||
stock_x,
|
||||
stock_y,
|
||||
epochs=ns_parser.n_epochs,
|
||||
batch_size=ns_parser.n_batch_size,
|
||||
verbose=1,
|
||||
)
|
||||
print("")
|
||||
|
||||
print(model.summary())
|
||||
print("")
|
||||
|
||||
# Prediction
|
||||
yhat = model.predict(
|
||||
stock_train_data[-ns_parser.n_inputs :].reshape(
|
||||
1, ns_parser.n_inputs, 1
|
||||
),
|
||||
verbose=0,
|
||||
)
|
||||
|
||||
if idx_loop == 0:
|
||||
# Re-scale the data back, plot, and print the results
|
||||
df_pred = _rescale_data(
|
||||
df_stock, ns_parser, scaler, yhat, idx_loop
|
||||
).to_frame()
|
||||
else:
|
||||
df_pred = df_pred.join(
|
||||
_rescale_data(
|
||||
df_stock, ns_parser, scaler, yhat, idx_loop
|
||||
).to_frame()
|
||||
)
|
||||
|
||||
_plot_and_print_results(
|
||||
df_stock, ns_parser, df_future, df_pred, "LSTM", s_ticker
|
||||
print(X_train.shape, X_test.shape)
|
||||
model.fit(
|
||||
X_train.reshape(X_train.shape[0], X_train.shape[1], 1),
|
||||
y_train,
|
||||
epochs=ns_parser.n_epochs,
|
||||
verbose=True,
|
||||
validation_data=(X_test, y_test),
|
||||
)
|
||||
|
||||
# for idx_loop in range(ns_parser.n_loops):
|
||||
# Train our model
|
||||
# model.fit(
|
||||
# stock_x,
|
||||
# stock_y,
|
||||
# epochs=ns_parser.n_epochs,
|
||||
# batch_size=ns_parser.n_batch_size,
|
||||
# verbose=1,
|
||||
# )
|
||||
# print("")
|
||||
|
||||
# print(model.summary())
|
||||
# print("")
|
||||
|
||||
# # Prediction
|
||||
# yhat = model.predict(
|
||||
# stock_train_data[-ns_parser.n_inputs :].reshape(
|
||||
# 1, ns_parser.n_inputs, 1
|
||||
# ),
|
||||
# verbose=0,
|
||||
# )
|
||||
|
||||
# if idx_loop == 0:
|
||||
# Re-scale the data back, plot, and print the results
|
||||
# df_pred = _rescale_data(
|
||||
# df_stock, ns_parser, scaler, yhat, idx_loop
|
||||
# ).to_frame()
|
||||
# else:
|
||||
# df_pred = df_pred.join(
|
||||
# _rescale_data(
|
||||
# df_stock, ns_parser, scaler, yhat, idx_loop
|
||||
# ).to_frame()
|
||||
# )
|
||||
|
||||
# _plot_and_print_results(
|
||||
# df_stock, ns_parser, df_future, df_pred, "LSTM", s_ticker
|
||||
# )
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
""" Prediction helper functions """
|
||||
__docformat__ = "numpy"
|
||||
|
||||
import argparse
|
||||
from typing import Tuple
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from pandas.plotting import register_matplotlib_converters
|
||||
@@ -14,7 +15,7 @@ from sklearn.metrics import (
|
||||
mean_squared_error,
|
||||
)
|
||||
from sklearn.model_selection import train_test_split
|
||||
|
||||
from sklearn.preprocessing import StandardScaler, MinMaxScaler, Normalizer
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
get_next_stock_market_days,
|
||||
patch_pandas_text_adjustment,
|
||||
@@ -26,26 +27,72 @@ from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
register_matplotlib_converters()
|
||||
|
||||
|
||||
def prepare_train_valid_test(
|
||||
df_stock, parsed_end_date, n_input_days, n_predict_days, test_size
|
||||
def prepare_scale_train_valid_test(
|
||||
df_stock: pd.DataFrame, ns_parser: argparse.Namespace
|
||||
):
|
||||
"""
|
||||
Prepare and scale train, validate and test data.
|
||||
Parameters
|
||||
----------
|
||||
df_stock: pd.DataFrame
|
||||
Dataframe of stock prices
|
||||
ns_parser: argparse.Namespace
|
||||
Parsed arguments
|
||||
Returns
|
||||
-------
|
||||
X_train: np.ndarray
|
||||
Array of training data. Shape (# samples, n_inputs, 1)
|
||||
X_test: np.ndarray
|
||||
Array of validation data. Shape (#samples, n_inputs, 1)
|
||||
y_train: np.ndarray
|
||||
Array of training outputs. Shape (#samples, n_days)
|
||||
y_test: np.ndarray
|
||||
Array of validation outputs. Shape (#samples, n_days)
|
||||
X_dates_train: np.ndarray
|
||||
Array of dates for X_train
|
||||
X_dates_test: np.ndarray
|
||||
Array of dates for X_test
|
||||
y_dates_train: np.ndarray
|
||||
Array of dates for y_train
|
||||
y_dates_test: np.ndarray
|
||||
Array of dates for y)test
|
||||
test_data: np.ndarray
|
||||
Array of prices after the specified end date
|
||||
dates_test: np.ndarray
|
||||
Array of dates after specified end date
|
||||
scaler:
|
||||
Fitted preprocesser
|
||||
"""
|
||||
parsed_end_date = ns_parser.s_end_date or df_stock.index[-1]-timedelta(days=3)
|
||||
n_input_days = ns_parser.n_inputs
|
||||
n_predict_days = ns_parser.n_days
|
||||
test_size = ns_parser.valid_split
|
||||
|
||||
df_test = df_stock[df_stock.index >= parsed_end_date]
|
||||
df_stock = df_stock[df_stock.index < parsed_end_date]
|
||||
dates = df_stock.index
|
||||
prices = df_stock["5. adjusted close"].values
|
||||
# Pre-process data
|
||||
if ns_parser.s_preprocessing == "standardization":
|
||||
scaler = StandardScaler()
|
||||
|
||||
elif ns_parser.s_preprocessing == "minmax":
|
||||
scaler = MinMaxScaler()
|
||||
|
||||
elif ns_parser.s_preprocessing == "normalization":
|
||||
scaler = Normalizer()
|
||||
|
||||
test_data = df_stock[df_stock.index > parsed_end_date]
|
||||
train_data = df_stock[df_stock.index < parsed_end_date]
|
||||
dates = train_data.index
|
||||
dates_test = test_data.index
|
||||
scaler = scaler
|
||||
train_data = scaler.fit_transform(train_data.values.reshape(-1, 1))
|
||||
test_data = scaler.transform(test_data.values.reshape(-1, 1))
|
||||
prices = train_data
|
||||
|
||||
input_dates = []
|
||||
input_prices = []
|
||||
next_n_day_prices = []
|
||||
next_n_day_dates = []
|
||||
|
||||
test_days = []
|
||||
test_inputs = []
|
||||
test_next_n_days = []
|
||||
|
||||
for idx in range(len(prices) - n_input_days - n_predict_days):
|
||||
|
||||
input_prices.append(prices[idx : idx + n_input_days])
|
||||
input_dates.append(dates[idx : idx + n_input_days])
|
||||
next_n_day_prices.append(
|
||||
@@ -55,20 +102,20 @@ def prepare_train_valid_test(
|
||||
dates[idx + n_input_days : idx + n_input_days + n_predict_days]
|
||||
)
|
||||
|
||||
input_dates = np.asarray(input_dates)
|
||||
input_prices = np.asarray(input_prices)
|
||||
next_n_day_prices = np.asarray(next_n_day_prices)
|
||||
next_n_day_dates = np.asarray(next_n_day_dates)
|
||||
input_dates = np.array(input_dates)
|
||||
input_prices = np.array(input_prices)
|
||||
next_n_day_prices = np.array(next_n_day_prices)
|
||||
next_n_day_dates = np.array(next_n_day_dates)
|
||||
|
||||
(
|
||||
X_train,
|
||||
X_valid,
|
||||
X_test,
|
||||
y_train,
|
||||
y_valid,
|
||||
y_test,
|
||||
X_dates_train,
|
||||
X_dates_valid,
|
||||
X_dates_test,
|
||||
y_dates_train,
|
||||
y_dates_valid,
|
||||
y_dates_test,
|
||||
) = train_test_split(
|
||||
input_prices,
|
||||
next_n_day_prices,
|
||||
@@ -76,15 +123,19 @@ def prepare_train_valid_test(
|
||||
next_n_day_dates,
|
||||
test_size=test_size,
|
||||
)
|
||||
|
||||
return (
|
||||
X_train,
|
||||
X_valid,
|
||||
X_test,
|
||||
y_train,
|
||||
y_valid,
|
||||
y_test,
|
||||
X_dates_train,
|
||||
X_dates_valid,
|
||||
X_dates_test,
|
||||
y_dates_train,
|
||||
y_dates_valid,
|
||||
y_dates_test,
|
||||
test_data,
|
||||
dates_test,
|
||||
scaler,
|
||||
)
|
||||
|
||||
|
||||
@@ -144,132 +195,6 @@ def get_backtesting_data(
|
||||
return df_future, df_stock, True
|
||||
|
||||
|
||||
def plot_pred(
|
||||
df_stock: pd.DataFrame,
|
||||
df_future: pd.DataFrame,
|
||||
df_pred: pd.DataFrame,
|
||||
title: str,
|
||||
bt_flag: bool,
|
||||
):
|
||||
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2)
|
||||
plt.title(title)
|
||||
plt.xlim(df_stock.index[0], get_next_stock_market_days(df_pred.index[-1], 1)[-1])
|
||||
plt.xlabel("Time")
|
||||
plt.ylabel("Share Price ($)")
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
plt.minorticks_on()
|
||||
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
|
||||
df_ma = df_stock["5. adjusted close"].rolling(window=ns_parser.n_length).mean()
|
||||
plt.plot(df_ma.index, df_ma, lw=2, linestyle="--", c="tab:orange")
|
||||
plt.plot(
|
||||
[df_stock.index[-1], df_pred.index[0]],
|
||||
[df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
|
||||
lw=1,
|
||||
c="tab:green",
|
||||
linestyle="--",
|
||||
)
|
||||
plt.plot(df_pred.index, df_pred, lw=2, c="tab:green")
|
||||
plt.axvspan(
|
||||
df_stock.index[-1], df_pred.index[-1], facecolor="tab:orange", alpha=0.2
|
||||
)
|
||||
_, _, ymin, ymax = plt.axis()
|
||||
plt.vlines(df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k")
|
||||
|
||||
if bt_flag:
|
||||
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
plt.subplot(211)
|
||||
plt.plot(
|
||||
df_future.index,
|
||||
df_future["5. adjusted close"],
|
||||
lw=2,
|
||||
c="tab:blue",
|
||||
ls="--",
|
||||
)
|
||||
plt.plot(df_pred.index, df_pred, lw=2, c="green")
|
||||
plt.scatter(df_future.index, df_future["5. adjusted close"], c="tab:blue", lw=3)
|
||||
plt.plot(
|
||||
[df_stock.index[-1], df_future.index[0]],
|
||||
[
|
||||
df_stock["5. adjusted close"].values[-1],
|
||||
df_future["5. adjusted close"].values[0],
|
||||
],
|
||||
lw=2,
|
||||
c="tab:blue",
|
||||
ls="--",
|
||||
)
|
||||
plt.scatter(df_pred.index, df_pred, c="green", lw=3)
|
||||
plt.plot(
|
||||
[df_stock.index[-1], df_pred.index[0]],
|
||||
[df_stock["5. adjusted close"].values[-1], df_pred.values[0]],
|
||||
lw=2,
|
||||
c="green",
|
||||
ls="--",
|
||||
)
|
||||
plt.title("BACKTESTING: Real data price versus Prediction")
|
||||
plt.xlim(df_stock.index[-1], df_pred.index[-1] + datetime.timedelta(days=1))
|
||||
plt.xticks(
|
||||
[df_stock.index[-1], df_pred.index[-1] + datetime.timedelta(days=1)],
|
||||
visible=True,
|
||||
)
|
||||
plt.ylabel("Share Price ($)")
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
plt.minorticks_on()
|
||||
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
|
||||
plt.legend(["Real data", "Prediction data"])
|
||||
plt.xticks([])
|
||||
|
||||
plt.subplot(212)
|
||||
plt.axhline(y=0, color="k", linestyle="--", linewidth=2)
|
||||
plt.plot(
|
||||
df_future.index,
|
||||
100
|
||||
* (df_pred.values - df_future["5. adjusted close"].values)
|
||||
/ df_future["5. adjusted close"].values,
|
||||
lw=2,
|
||||
c="red",
|
||||
)
|
||||
plt.scatter(
|
||||
df_future.index,
|
||||
100
|
||||
* (df_pred.values - df_future["5. adjusted close"].values)
|
||||
/ df_future["5. adjusted close"].values,
|
||||
c="red",
|
||||
lw=5,
|
||||
)
|
||||
plt.title("BACKTESTING: Error between Real data and Prediction [%]")
|
||||
plt.plot(
|
||||
[df_stock.index[-1], df_future.index[0]],
|
||||
[
|
||||
0,
|
||||
100
|
||||
* (df_pred.values[0] - df_future["5. adjusted close"].values[0])
|
||||
/ df_future["5. adjusted close"].values[0],
|
||||
],
|
||||
lw=2,
|
||||
ls="--",
|
||||
c="red",
|
||||
)
|
||||
plt.xlim(df_stock.index[-1], df_pred.index[-1] + datetime.timedelta(days=1))
|
||||
plt.xticks(
|
||||
[df_stock.index[-1], df_pred.index[-1] + datetime.timedelta(days=1)],
|
||||
visible=True,
|
||||
)
|
||||
plt.xlabel("Time")
|
||||
plt.ylabel("Prediction Error (%)")
|
||||
plt.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
plt.minorticks_on()
|
||||
plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
|
||||
plt.legend(["Real data", "Prediction data"])
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
|
||||
plt.show()
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def price_prediction_color(val: float, last_val: float) -> str:
|
||||
"""Set prediction to be a colored string"""
|
||||
if float(val) > last_val:
|
||||
|
||||
Reference in New Issue
Block a user