Predicción del valor de una acción a tres días. Apple (LSTM)
Contents
Predicción del valor de una acción a tres días. Apple (LSTM)#
Importar las librería requeridas#
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#%matplotlib inline
from sklearn.preprocessing import MinMaxScaler
#setting figure size
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 20,10
#importing required libraries
from sklearn.preprocessing import MinMaxScaler
# importa objetos de keras
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Dropout, LSTM
print("Versión de Tensorflow: ", tf.__version__)
# optimizador
from tensorflow.keras.optimizers import Adam
Versión de Tensorflow: 2.9.1
Lectura de los datos#
Estos datos corresponden a la empresa Apple. Son 3019 datos que corresponden a observaciones del precio de la acción, el número de transacciones de la acción (compra-venta). Los datos son diarios (dias hábiles o comerciales). Están entre el 3 de enero de 2006 hasta el 1 de enero de 2018.
la columna Date es la fecha, Open es el valor de acción a la apertura del mercado, High el valor más alto alcanzado en el día, Low el valor más bajo del día, Close el valor al cierre, Volume es el volúmenes de acciones transadas en el día y Name es el código de identificación de la empresa, Apple en este caso.
Los datos puede ser bajados directamente de Kaggle
#reading from a local file
df = pd.read_csv('https://raw.githubusercontent.com/AprendizajeProfundo/Libro-Fundamentos/main/Redes_Recurrentes/Datos/AAPL_2006-01-01_to_2018-01-01.csv')
# looking at the first five rows of the data
print('\n Shape of the data:')
print(df.shape)
df.head()
Shape of the data:
(3019, 7)
Date | Open | High | Low | Close | Volume | Name | |
---|---|---|---|---|---|---|---|
0 | 2006-01-03 | 10.34 | 10.68 | 10.32 | 10.68 | 201853036 | AAPL |
1 | 2006-01-04 | 10.73 | 10.85 | 10.64 | 10.71 | 155225609 | AAPL |
2 | 2006-01-05 | 10.69 | 10.70 | 10.54 | 10.63 | 112396081 | AAPL |
3 | 2006-01-06 | 10.75 | 10.96 | 10.65 | 10.90 | 176139334 | AAPL |
4 | 2006-01-09 | 10.96 | 11.03 | 10.82 | 10.86 | 168861224 | AAPL |
Vamos a cambiar el índice de los datos. Tomaremos la fecha como indice: df.index. Los datos se reordenan para invertir la tabla, debido a que los datos contienen las observaciones más recientes en la parte superior de la tabla.
Extrae datos para la serie que se desea predecir-close#
#creating dataframe with date and the target variable
df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d')
df.index = df['Date']
# df = df.sort_index(ascending=True, axis=0)
data = pd.DataFrame(df[['Date', 'Close']])
#
#setting index
data.index = data.Date
data.drop('Date', axis=1, inplace=True)
data.head()
Close | |
---|---|
Date | |
2006-01-03 | 10.68 |
2006-01-04 | 10.71 |
2006-01-05 | 10.63 |
2006-01-06 | 10.90 |
2006-01-09 | 10.86 |
Visualización de la serie precio al cierre#
# plot
len_data = len(data)
len_train = int(len_data*0.8) # 80% = 3019
len_test = len_data- len_train # 20% = 2415
print (len_data, '=', len_train, '+',len_test)
3019 = 2415 + 604
plt.figure(figsize=(16,8))
plt.plot(data[:len_train], label='Conjunto de entrenamiento (Training set): {} puntos (80%)'.format(len_train))
plt.plot(data['Close'][len_train:], label='Conjunto de validación (Validation set): {} puntos (20%)'.format(len_test)) #248 data
plt.title("Apple: Historia del precio la acción al cierre (Close)", size = 20)
plt.legend()
plt.show()
Preparación de los datos para el entrenamiento de la red LSTM#
Para evitar problemas con las tendencias y para mejorar la estimación (entrenamiento) los datos se van a transformar a la escala \([0,1]\). Para las predicciones se utiliza la transformación inversa.
Primero extrae los valores y se crea el objeto MinMaxScaler#
#creating train and test sets
dataset = data.values
# create the scaler object and scale the data
scaler = MinMaxScaler(feature_range=(0, 1))
#scaled_data = np.array(scaler.fit_transform(dataset))
dataset = np.squeeze(np.array(scaler.fit_transform(dataset)),axis=1)
# dataset = pd.DataFrame(scaled_data,index=data.index, columns=['serie'])
dataset.shape
(3019,)
Crea datos de entrenamiento#
La red LSTM tendrá como entrada «time_step» datos consecutivos, y como salida 5 datos (la predicción a partir de esos «time_step» datos se hace para los siguentes 5 días). Se conformará de esta forma el set de entrenamiento
Número de datos consecutivos para entrenamiento: time_step = 60.
Días a predecir: days = 1
Función para crear los datos de entrenamiento#
def univariate_data(dataset, start_index, end_index, history_size, target_size):
''' dataset: conjunto de datos
start_index: índice inicial de donde empezar a tomar los datos
end_index: índice final para tomar los datos. None para tomarlos todos
history_size: tamaño de la venytana para crear las secuencias
target_size: dentro de cuántas observaciones futuras desea pronosticar
'''
data = []
labels = []
start_index = start_index + history_size
if end_index is None:
end_index = len(dataset) - target_size
for i in range(start_index, end_index):
indices = range(i-history_size, i)
# Reshape data from (history_size,) to (history_size, 1)
data.append(np.reshape(dataset[indices], (history_size, 1)))
labels.append(dataset[i+target_size])
return np.array(data), np.array(labels)
Se coloca una semilla para gerantizar reproductibidad
tf.random.set_seed(100)
#
# hiperparámetros para crear las secuencias
past_history = 60 # tamaño secuencias de entrada
future_target = 3 # días adelante
TRAIN_SPLIT = int(len_data*0.8) #2415: nuḿer0 de datos entreno
# secuencias de entrenamiento
X_train, y_train = univariate_data(dataset, 0, TRAIN_SPLIT,
past_history,
future_target)
#
#secuencias de validación
# No se usará ningún dato que el modelo haya visto
X_test, y_test = univariate_data(dataset, TRAIN_SPLIT, None,
past_history,
future_target)
print(TRAIN_SPLIT)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
2415
(2355, 60, 1)
(2355,)
(541, 60, 1)
(541,)
Crea el modelo LSTM#
Omitimos esta sección. Usaremso el modelo entrenado a un día
# shapes
input_shape = (X_train.shape[1], X_train.shape[2])
units = 64
# layers
inputs = Input(input_shape)
#x = Dropout(0.0, name= 'Dropout_01')(inputs)
#x = LSTM(units=units, name='LSTM_layer')(x)
x = LSTM(units=units, return_sequences=True,name='LSTM_layer')(inputs)
x = Dropout(0.4, name= 'Dropout_02')(x)
x = LSTM(units=units//2, name='LSTM_layer_2')(x)
x = Dropout(0.4, name= 'Dropout_03')(x)
outputs = Dense(1)(x)
# model
model_01 = Model(inputs=inputs, outputs=outputs, name='series_LSTM_model')
model_01.summary()
Model: "series_LSTM_model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 60, 1)] 0
LSTM_layer (LSTM) (None, 60, 64) 16896
Dropout_02 (Dropout) (None, 60, 64) 0
LSTM_layer_2 (LSTM) (None, 32) 12416
Dropout_03 (Dropout) (None, 32) 0
dense (Dense) (None, 1) 33
=================================================================
Total params: 29,345
Trainable params: 29,345
Non-trainable params: 0
_________________________________________________________________
Compila#
Se usará el optimizador Adam y la función de pérdida MSE
model_01.compile(loss='mean_squared_error',
optimizer=Adam(0.001))
Entrena el modelo#
#history = model_01.fit(X_train,y_train,epochs=20,batch_size=32)
tf.random.set_seed(100)
history = model_01.fit(
X_train, y_train,
epochs=15,
batch_size=32,
validation_split=0.1,
verbose=1,
shuffle=False
)
Epoch 1/15
1/67 [..............................] - ETA: 7:44 - loss: 2.4157e-04
2/67 [..............................] - ETA: 5s - loss: 1.4562e-04
3/67 [>.............................] - ETA: 4s - loss: 1.2524e-04
4/67 [>.............................] - ETA: 4s - loss: 1.0101e-04
5/67 [=>............................] - ETA: 4s - loss: 9.9967e-05
6/67 [=>............................] - ETA: 4s - loss: 1.1648e-04
7/67 [==>...........................] - ETA: 3s - loss: 1.1462e-04
8/67 [==>...........................] - ETA: 3s - loss: 1.0868e-04
9/67 [===>..........................] - ETA: 3s - loss: 1.1215e-04
10/67 [===>..........................] - ETA: 3s - loss: 1.2017e-04
11/67 [===>..........................] - ETA: 3s - loss: 1.3608e-04
12/67 [====>.........................] - ETA: 3s - loss: 1.5585e-04
13/67 [====>.........................] - ETA: 3s - loss: 2.0753e-04
14/67 [=====>........................] - ETA: 3s - loss: 2.1871e-04
15/67 [=====>........................] - ETA: 3s - loss: 3.1331e-04
16/67 [======>.......................] - ETA: 3s - loss: 3.2149e-04
18/67 [=======>......................] - ETA: 3s - loss: 3.8504e-04
19/67 [=======>......................] - ETA: 3s - loss: 3.9329e-04
20/67 [=======>......................] - ETA: 3s - loss: 4.2395e-04
21/67 [========>.....................] - ETA: 2s - loss: 4.5621e-04
22/67 [========>.....................] - ETA: 2s - loss: 4.9952e-04
23/67 [=========>....................] - ETA: 2s - loss: 5.0137e-04
24/67 [=========>....................] - ETA: 2s - loss: 4.8637e-04
25/67 [==========>...................] - ETA: 2s - loss: 4.8661e-04
26/67 [==========>...................] - ETA: 2s - loss: 5.1376e-04
27/67 [===========>..................] - ETA: 2s - loss: 6.0306e-04
28/67 [===========>..................] - ETA: 2s - loss: 7.3945e-04
29/67 [===========>..................] - ETA: 2s - loss: 8.4674e-04
30/67 [============>.................] - ETA: 2s - loss: 9.2930e-04
31/67 [============>.................] - ETA: 2s - loss: 9.6262e-04
32/67 [=============>................] - ETA: 2s - loss: 0.0010
33/67 [=============>................] - ETA: 2s - loss: 0.0011
34/67 [==============>...............] - ETA: 2s - loss: 0.0011
35/67 [==============>...............] - ETA: 2s - loss: 0.0011
36/67 [===============>..............] - ETA: 1s - loss: 0.0011
37/67 [===============>..............] - ETA: 1s - loss: 0.0012
38/67 [================>.............] - ETA: 1s - loss: 0.0012
39/67 [================>.............] - ETA: 1s - loss: 0.0013
40/67 [================>.............] - ETA: 1s - loss: 0.0013
41/67 [=================>............] - ETA: 1s - loss: 0.0013
42/67 [=================>............] - ETA: 1s - loss: 0.0014
43/67 [==================>...........] - ETA: 1s - loss: 0.0015
44/67 [==================>...........] - ETA: 1s - loss: 0.0015
45/67 [===================>..........] - ETA: 1s - loss: 0.0016
46/67 [===================>..........] - ETA: 1s - loss: 0.0016
47/67 [====================>.........] - ETA: 1s - loss: 0.0017
48/67 [====================>.........] - ETA: 1s - loss: 0.0018
49/67 [====================>.........] - ETA: 1s - loss: 0.0019
50/67 [=====================>........] - ETA: 1s - loss: 0.0020
51/67 [=====================>........] - ETA: 1s - loss: 0.0022
52/67 [======================>.......] - ETA: 0s - loss: 0.0023
53/67 [======================>.......] - ETA: 0s - loss: 0.0026
54/67 [=======================>......] - ETA: 0s - loss: 0.0026
55/67 [=======================>......] - ETA: 0s - loss: 0.0027
56/67 [========================>.....] - ETA: 0s - loss: 0.0027
57/67 [========================>.....] - ETA: 0s - loss: 0.0027
58/67 [========================>.....] - ETA: 0s - loss: 0.0027
60/67 [=========================>....] - ETA: 0s - loss: 0.0030
61/67 [==========================>...] - ETA: 0s - loss: 0.0032
62/67 [==========================>...] - ETA: 0s - loss: 0.0033
63/67 [===========================>..] - ETA: 0s - loss: 0.0034
64/67 [===========================>..] - ETA: 0s - loss: 0.0034
65/67 [============================>.] - ETA: 0s - loss: 0.0035
66/67 [============================>.] - ETA: 0s - loss: 0.0036
67/67 [==============================] - ETA: 0s - loss: 0.0036
67/67 [==============================] - 13s 98ms/step - loss: 0.0036 - val_loss: 0.0017
Epoch 2/15
1/67 [..............................] - ETA: 5s - loss: 0.0616
2/67 [..............................] - ETA: 4s - loss: 0.0603
3/67 [>.............................] - ETA: 4s - loss: 0.0552
4/67 [>.............................] - ETA: 3s - loss: 0.0490
5/67 [=>............................] - ETA: 3s - loss: 0.0435
6/67 [=>............................] - ETA: 3s - loss: 0.0383
7/67 [==>...........................] - ETA: 3s - loss: 0.0339
8/67 [==>...........................] - ETA: 3s - loss: 0.0300
9/67 [===>..........................] - ETA: 3s - loss: 0.0268
10/67 [===>..........................] - ETA: 3s - loss: 0.0242
11/67 [===>..........................] - ETA: 3s - loss: 0.0220
12/67 [====>.........................] - ETA: 3s - loss: 0.0204
13/67 [====>.........................] - ETA: 3s - loss: 0.0193
14/67 [=====>........................] - ETA: 3s - loss: 0.0184
15/67 [=====>........................] - ETA: 3s - loss: 0.0173
16/67 [======>.......................] - ETA: 3s - loss: 0.0165
17/67 [======>.......................] - ETA: 3s - loss: 0.0159
18/67 [=======>......................] - ETA: 3s - loss: 0.0153
19/67 [=======>......................] - ETA: 3s - loss: 0.0148
20/67 [=======>......................] - ETA: 2s - loss: 0.0141
21/67 [========>.....................] - ETA: 2s - loss: 0.0135
22/67 [========>.....................] - ETA: 2s - loss: 0.0129
23/67 [=========>....................] - ETA: 2s - loss: 0.0123
24/67 [=========>....................] - ETA: 2s - loss: 0.0118
25/67 [==========>...................] - ETA: 2s - loss: 0.0114
26/67 [==========>...................] - ETA: 2s - loss: 0.0110
27/67 [===========>..................] - ETA: 2s - loss: 0.0106
28/67 [===========>..................] - ETA: 2s - loss: 0.0103
29/67 [===========>..................] - ETA: 2s - loss: 0.0100
30/67 [============>.................] - ETA: 2s - loss: 0.0098
31/67 [============>.................] - ETA: 2s - loss: 0.0095
32/67 [=============>................] - ETA: 2s - loss: 0.0094
33/67 [=============>................] - ETA: 2s - loss: 0.0092
34/67 [==============>...............] - ETA: 2s - loss: 0.0090
35/67 [==============>...............] - ETA: 2s - loss: 0.0089
36/67 [===============>..............] - ETA: 2s - loss: 0.0087
37/67 [===============>..............] - ETA: 2s - loss: 0.0086
38/67 [================>.............] - ETA: 2s - loss: 0.0085
39/67 [================>.............] - ETA: 2s - loss: 0.0084
40/67 [================>.............] - ETA: 2s - loss: 0.0082
41/67 [=================>............] - ETA: 2s - loss: 0.0081
42/67 [=================>............] - ETA: 2s - loss: 0.0080
43/67 [==================>...........] - ETA: 2s - loss: 0.0078
44/67 [==================>...........] - ETA: 1s - loss: 0.0078
45/67 [===================>..........] - ETA: 1s - loss: 0.0077
46/67 [===================>..........] - ETA: 1s - loss: 0.0076
47/67 [====================>.........] - ETA: 1s - loss: 0.0076
48/67 [====================>.........] - ETA: 1s - loss: 0.0077
49/67 [====================>.........] - ETA: 1s - loss: 0.0077
50/67 [=====================>........] - ETA: 1s - loss: 0.0077
51/67 [=====================>........] - ETA: 1s - loss: 0.0078
52/67 [======================>.......] - ETA: 1s - loss: 0.0078
53/67 [======================>.......] - ETA: 1s - loss: 0.0079
54/67 [=======================>......] - ETA: 1s - loss: 0.0080
55/67 [=======================>......] - ETA: 1s - loss: 0.0079
56/67 [========================>.....] - ETA: 0s - loss: 0.0079
57/67 [========================>.....] - ETA: 0s - loss: 0.0078
58/67 [========================>.....] - ETA: 0s - loss: 0.0078
59/67 [=========================>....] - ETA: 0s - loss: 0.0077
60/67 [=========================>....] - ETA: 0s - loss: 0.0078
61/67 [==========================>...] - ETA: 0s - loss: 0.0079
62/67 [==========================>...] - ETA: 0s - loss: 0.0081
63/67 [===========================>..] - ETA: 0s - loss: 0.0081
64/67 [===========================>..] - ETA: 0s - loss: 0.0082
65/67 [============================>.] - ETA: 0s - loss: 0.0083
66/67 [============================>.] - ETA: 0s - loss: 0.0083
67/67 [==============================] - ETA: 0s - loss: 0.0083
67/67 [==============================] - 6s 91ms/step - loss: 0.0083 - val_loss: 0.0022
Epoch 3/15
1/67 [..............................] - ETA: 7s - loss: 0.0553
2/67 [..............................] - ETA: 6s - loss: 0.0567
3/67 [>.............................] - ETA: 6s - loss: 0.0547
4/67 [>.............................] - ETA: 5s - loss: 0.0518
5/67 [=>............................] - ETA: 5s - loss: 0.0475
6/67 [=>............................] - ETA: 5s - loss: 0.0439
7/67 [==>...........................] - ETA: 5s - loss: 0.0396
8/67 [==>...........................] - ETA: 5s - loss: 0.0357
9/67 [===>..........................] - ETA: 5s - loss: 0.0322
10/67 [===>..........................] - ETA: 5s - loss: 0.0292
11/67 [===>..........................] - ETA: 5s - loss: 0.0266
12/67 [====>.........................] - ETA: 5s - loss: 0.0244
13/67 [====>.........................] - ETA: 5s - loss: 0.0226
14/67 [=====>........................] - ETA: 5s - loss: 0.0211
15/67 [=====>........................] - ETA: 5s - loss: 0.0197
16/67 [======>.......................] - ETA: 5s - loss: 0.0186
17/67 [======>.......................] - ETA: 5s - loss: 0.0177
18/67 [=======>......................] - ETA: 5s - loss: 0.0169
19/67 [=======>......................] - ETA: 5s - loss: 0.0162
20/67 [=======>......................] - ETA: 4s - loss: 0.0154
21/67 [========>.....................] - ETA: 4s - loss: 0.0147
22/67 [========>.....................] - ETA: 4s - loss: 0.0141
23/67 [=========>....................] - ETA: 4s - loss: 0.0135
24/67 [=========>....................] - ETA: 4s - loss: 0.0130
25/67 [==========>...................] - ETA: 4s - loss: 0.0126
26/67 [==========>...................] - ETA: 4s - loss: 0.0122
27/67 [===========>..................] - ETA: 4s - loss: 0.0118
28/67 [===========>..................] - ETA: 4s - loss: 0.0115
29/67 [===========>..................] - ETA: 4s - loss: 0.0112
30/67 [============>.................] - ETA: 4s - loss: 0.0109
31/67 [============>.................] - ETA: 3s - loss: 0.0106
32/67 [=============>................] - ETA: 3s - loss: 0.0104
33/67 [=============>................] - ETA: 3s - loss: 0.0102
34/67 [==============>...............] - ETA: 3s - loss: 0.0100
35/67 [==============>...............] - ETA: 3s - loss: 0.0097
36/67 [===============>..............] - ETA: 3s - loss: 0.0096
37/67 [===============>..............] - ETA: 3s - loss: 0.0095
38/67 [================>.............] - ETA: 3s - loss: 0.0093
39/67 [================>.............] - ETA: 3s - loss: 0.0091
40/67 [================>.............] - ETA: 3s - loss: 0.0090
41/67 [=================>............] - ETA: 2s - loss: 0.0088
42/67 [=================>............] - ETA: 2s - loss: 0.0086
43/67 [==================>...........] - ETA: 2s - loss: 0.0085
44/67 [==================>...........] - ETA: 2s - loss: 0.0083
45/67 [===================>..........] - ETA: 2s - loss: 0.0082
46/67 [===================>..........] - ETA: 2s - loss: 0.0081
47/67 [====================>.........] - ETA: 2s - loss: 0.0081
48/67 [====================>.........] - ETA: 2s - loss: 0.0081
49/67 [====================>.........] - ETA: 1s - loss: 0.0080
50/67 [=====================>........] - ETA: 1s - loss: 0.0080
51/67 [=====================>........] - ETA: 1s - loss: 0.0080
52/67 [======================>.......] - ETA: 1s - loss: 0.0081
53/67 [======================>.......] - ETA: 1s - loss: 0.0081
54/67 [=======================>......] - ETA: 1s - loss: 0.0081
55/67 [=======================>......] - ETA: 1s - loss: 0.0081
56/67 [========================>.....] - ETA: 1s - loss: 0.0080
57/67 [========================>.....] - ETA: 1s - loss: 0.0079
58/67 [========================>.....] - ETA: 0s - loss: 0.0078
59/67 [=========================>....] - ETA: 0s - loss: 0.0078
60/67 [=========================>....] - ETA: 0s - loss: 0.0077
61/67 [==========================>...] - ETA: 0s - loss: 0.0078
62/67 [==========================>...] - ETA: 0s - loss: 0.0078
63/67 [===========================>..] - ETA: 0s - loss: 0.0078
64/67 [===========================>..] - ETA: 0s - loss: 0.0079
65/67 [============================>.] - ETA: 0s - loss: 0.0079
66/67 [============================>.] - ETA: 0s - loss: 0.0079
67/67 [==============================] - ETA: 0s - loss: 0.0080
67/67 [==============================] - 7s 106ms/step - loss: 0.0080 - val_loss: 0.0045
Epoch 4/15
1/67 [..............................] - ETA: 6s - loss: 0.0180
2/67 [..............................] - ETA: 5s - loss: 0.0195
3/67 [>.............................] - ETA: 5s - loss: 0.0199
4/67 [>.............................] - ETA: 5s - loss: 0.0194
5/67 [=>............................] - ETA: 5s - loss: 0.0189
6/67 [=>............................] - ETA: 4s - loss: 0.0180
7/67 [==>...........................] - ETA: 4s - loss: 0.0170
8/67 [==>...........................] - ETA: 4s - loss: 0.0158
9/67 [===>..........................] - ETA: 4s - loss: 0.0145
10/67 [===>..........................] - ETA: 4s - loss: 0.0134
11/67 [===>..........................] - ETA: 4s - loss: 0.0123
12/67 [====>.........................] - ETA: 4s - loss: 0.0113
13/67 [====>.........................] - ETA: 4s - loss: 0.0105
14/67 [=====>........................] - ETA: 4s - loss: 0.0098
15/67 [=====>........................] - ETA: 3s - loss: 0.0092
16/67 [======>.......................] - ETA: 3s - loss: 0.0087
17/67 [======>.......................] - ETA: 3s - loss: 0.0083
18/67 [=======>......................] - ETA: 3s - loss: 0.0079
19/67 [=======>......................] - ETA: 3s - loss: 0.0076
20/67 [=======>......................] - ETA: 3s - loss: 0.0072
21/67 [========>.....................] - ETA: 3s - loss: 0.0071
22/67 [========>.....................] - ETA: 3s - loss: 0.0069
23/67 [=========>....................] - ETA: 3s - loss: 0.0067
24/67 [=========>....................] - ETA: 3s - loss: 0.0066
25/67 [==========>...................] - ETA: 3s - loss: 0.0064
26/67 [==========>...................] - ETA: 2s - loss: 0.0062
27/67 [===========>..................] - ETA: 2s - loss: 0.0060
28/67 [===========>..................] - ETA: 2s - loss: 0.0058
29/67 [===========>..................] - ETA: 2s - loss: 0.0056
30/67 [============>.................] - ETA: 2s - loss: 0.0054
31/67 [============>.................] - ETA: 2s - loss: 0.0053
32/67 [=============>................] - ETA: 2s - loss: 0.0051
33/67 [=============>................] - ETA: 2s - loss: 0.0050
34/67 [==============>...............] - ETA: 2s - loss: 0.0049
35/67 [==============>...............] - ETA: 2s - loss: 0.0048
36/67 [===============>..............] - ETA: 2s - loss: 0.0047
37/67 [===============>..............] - ETA: 2s - loss: 0.0046
39/67 [================>.............] - ETA: 1s - loss: 0.0044
40/67 [================>.............] - ETA: 1s - loss: 0.0043
41/67 [=================>............] - ETA: 1s - loss: 0.0043
42/67 [=================>............] - ETA: 1s - loss: 0.0042
43/67 [==================>...........] - ETA: 1s - loss: 0.0042
44/67 [==================>...........] - ETA: 1s - loss: 0.0041
45/67 [===================>..........] - ETA: 1s - loss: 0.0041
46/67 [===================>..........] - ETA: 1s - loss: 0.0040
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend();
Predicciones#
Prepara los datos de validación#
X_test.shape
(541, 60, 1)
Calcula predicciones#
# predictions
prediction = model_01.predict(X_test)
#prediction = scaler.inverse_transform(prediction)
17/17 [==============================] - 2s 18ms/step
print(prediction.shape)
print(y_test.shape)
(541, 1)
(541,)
Elimina dimensiones sobrante para los gráficos#
y_train_p = y_train# np.squeeze(y_train, axis=-1)
y_test_p = y_test #np.squeeze(y_test, axis=-1)
y_pred_p = np.squeeze(prediction, axis=-1)
print(y_train_p.shape)
print(y_test_p.shape)
print(y_pred_p.shape)
k=0
for i,j in zip(y_test_p, y_pred_p):
print (i,j, i-j)
k+=1
if k==10:
break
(2355,)
(541,)
(541,)
0.6727745596406196 0.64994586 0.022828704499933572
0.6698782361981322 0.6543955 0.015482715511028977
0.6474169523584349 0.6584121 -0.010995146526147637
0.6435157820073296 0.6614015 -0.017885728231317843
0.6412105449816764 0.66360754 -0.022396992764753043
0.6212318240926825 0.664968 -0.04373618967074522
0.6321078141624307 0.664171 -0.03206316629106054
0.6292114907199433 0.66194737 -0.03273587885555718
0.6504906017259725 0.65891695 -0.008426348499857572
0.6592977893368012 0.6542779 0.00501986861383974
Gráfica de las predicciones#
plt.plot(np.arange(0, len(y_train_p)), y_train_p, 'g', label="historia")
plt.plot(np.arange(len(y_train_p), len(y_train_p) + len(y_test_p)), y_test_p, marker='.', label="verdadero")
plt.plot(np.arange(len(y_train_p), len(y_train_p) + len(y_test_p)), y_pred_p, 'r', label="predicción")
#plt.ylabel('Valor')
plt.xlabel('Time Step')
plt.title("Apple: Historia del precio la acción al cierre. Escala (0,1)", size = 20)
plt.legend()
plt.show();
Regreso a la escala original#
y_pred_or = scaler.inverse_transform(y_pred_p.reshape(-1,1))
y_test_or = scaler.inverse_transform(y_test_p.reshape(-1,1))
k=0
for i,j in zip(y_test_or, y_pred_or):
print (i,j, i-j)
k+=1
if k==10:
break
[121.06] [117.19784] [3.86216217]
[120.57] [117.95063] [2.61936981]
[116.77] [118.63016] [-1.86015747]
[116.11] [119.1359] [-3.0259024]
[115.72] [119.509125] [-3.78912476]
[112.34] [119.73929] [-7.39928833]
[114.18] [119.60445] [-5.42444641]
[113.69] [119.22826] [-5.53825623]
[117.29] [118.71557] [-1.42556854]
[118.78] [117.93074] [0.84925964]
rmsLSTM = np.sqrt(np.mean(np.power(y_pred_or-y_test_or,2)))
print(rmsLSTM )
8.170484800047866
plt.plot(np.arange(0, len(y_test_or)), y_test_or, marker='.', label="verdadero")
plt.plot(np.arange(0, len(y_test_or)), y_pred_or, marker='+', label="predicho")
plt.xlabel('Time Step')
plt.annotate("rms = "+str(round(rmsLSTM,2)) , xy=(100, 140), size = 15)
plt.annotate("modelo = LSTM(50), timestep=60" , xy=(100, 146), size = 15)
plt.annotate("epochs=40" , xy=(100, 143), size = 15)
plt.title("Apple: Intervalo de predicción a tres días. Escala original", size = 20)
plt.legend()
plt.show();
Guarda el modelo entrenado#
model_01.save('../Datos/modelo_Apple_3_dia.h5')
Intervalos de confianza. TO DO#
model_01.get_config()
{'name': 'series_LSTM_model',
'layers': [{'class_name': 'InputLayer',
'config': {'batch_input_shape': (None, 60, 1),
'dtype': 'float32',
'sparse': False,
'ragged': False,
'name': 'input_1'},
'name': 'input_1',
'inbound_nodes': []},
{'class_name': 'LSTM',
'config': {'name': 'LSTM_layer',
'trainable': True,
'dtype': 'float32',
'return_sequences': True,
'return_state': False,
'go_backwards': False,
'stateful': False,
'unroll': False,
'time_major': False,
'units': 64,
'activation': 'tanh',
'recurrent_activation': 'sigmoid',
'use_bias': True,
'kernel_initializer': {'class_name': 'GlorotUniform',
'config': {'seed': None},
'shared_object_id': 1},
'recurrent_initializer': {'class_name': 'Orthogonal',
'config': {'gain': 1.0, 'seed': None},
'shared_object_id': 2},
'bias_initializer': {'class_name': 'Zeros',
'config': {},
'shared_object_id': 3},
'unit_forget_bias': True,
'kernel_regularizer': None,
'recurrent_regularizer': None,
'bias_regularizer': None,
'activity_regularizer': None,
'kernel_constraint': None,
'recurrent_constraint': None,
'bias_constraint': None,
'dropout': 0.0,
'recurrent_dropout': 0.0,
'implementation': 2},
'name': 'LSTM_layer',
'inbound_nodes': [[['input_1', 0, 0, {}]]]},
{'class_name': 'Dropout',
'config': {'name': 'Dropout_02',
'trainable': True,
'dtype': 'float32',
'rate': 0.4,
'noise_shape': None,
'seed': None},
'name': 'Dropout_02',
'inbound_nodes': [[['LSTM_layer', 0, 0, {}]]]},
{'class_name': 'LSTM',
'config': {'name': 'LSTM_layer_2',
'trainable': True,
'dtype': 'float32',
'return_sequences': False,
'return_state': False,
'go_backwards': False,
'stateful': False,
'unroll': False,
'time_major': False,
'units': 32,
'activation': 'tanh',
'recurrent_activation': 'sigmoid',
'use_bias': True,
'kernel_initializer': {'class_name': 'GlorotUniform',
'config': {'seed': None},
'shared_object_id': 7},
'recurrent_initializer': {'class_name': 'Orthogonal',
'config': {'gain': 1.0, 'seed': None},
'shared_object_id': 8},
'bias_initializer': {'class_name': 'Zeros',
'config': {},
'shared_object_id': 9},
'unit_forget_bias': True,
'kernel_regularizer': None,
'recurrent_regularizer': None,
'bias_regularizer': None,
'activity_regularizer': None,
'kernel_constraint': None,
'recurrent_constraint': None,
'bias_constraint': None,
'dropout': 0.0,
'recurrent_dropout': 0.0,
'implementation': 2},
'name': 'LSTM_layer_2',
'inbound_nodes': [[['Dropout_02', 0, 0, {}]]]},
{'class_name': 'Dropout',
'config': {'name': 'Dropout_03',
'trainable': True,
'dtype': 'float32',
'rate': 0.4,
'noise_shape': None,
'seed': None},
'name': 'Dropout_03',
'inbound_nodes': [[['LSTM_layer_2', 0, 0, {}]]]},
{'class_name': 'Dense',
'config': {'name': 'dense',
'trainable': True,
'dtype': 'float32',
'units': 1,
'activation': 'linear',
'use_bias': True,
'kernel_initializer': {'class_name': 'GlorotUniform',
'config': {'seed': None}},
'bias_initializer': {'class_name': 'Zeros', 'config': {}},
'kernel_regularizer': None,
'bias_regularizer': None,
'activity_regularizer': None,
'kernel_constraint': None,
'bias_constraint': None},
'name': 'dense',
'inbound_nodes': [[['Dropout_03', 0, 0, {}]]]}],
'input_layers': [['input_1', 0, 0]],
'output_layers': [['dense', 0, 0]]}
Referencias#
Introducción a Redes LSTM
Time Series Forecasting with LSTMs using TensorFlow 2 and Keras in Python
Ralf C. Staudemeyer and Eric Rothstein Morris,Understanding LSTM a tutorial into Long Short-Term Memory Recurrent Neural Networks, arxiv, September 2019
Karpathy, The Unreasonable Effectiveness of Recurrent Neural Networks
Anton Lucanus, Making Automation More Efficient by Learning from Historical Trade Data, 8:43 AM, January 7, 2020
https://www.youtube.com/watch?v=2BrpKpWwT2A&list=PLQVvvaa0QuDcOdF96TBtRtuQksErCEBYZ&index=1
https://towardsdatascience.com/using-lstms-for-stock-market-predictions-tensorflow-9e83999d4653
https://github.com/llSourcell/Reinforcement_Learning_for_Stock_Prediction/blob/master/README.md