def model_svm(train_X, val_X, test_X, train_y, val_y, test_y, n_series, n_features, n_lags, scaler, last_values, calc_val_error, calc_test_error, verbosity, saved_model, model_file_name, returns): """ Función para crear, entrenar y calcular el error del modelo SVM, también sirve para predecir Este modelo se construye con la libreria sklearn con el algoritmo SVR (*support vector regressor*) el kernel actual es polinomial de grado 1 por que dió mejores resultados con un dataset con el que probamos pero este se peude cambiar en el futuro Parámetros: - train_X -- Arreglo de numpy, datos de entrenamiento - val_X -- Arreglo de numpy, datos de validación - test_X -- Arreglo de numpy, datos de *testing* - train_y -- Arreglo de numpy, observaciones de entrenamiento - val_y -- Arreglo de numpy, observaciones de validación - test_y -- Arreglo de numpy, observaciones de *testing* - n_series -- Entero, el número de time steps a predecir en el futuro - n_features -- Entero, el número de *features* con los que se entrena el modelo, también se conocen como variables exogenas - n_lags -- Entero, el número de *lags* que se usaran para entrenar - scaler -- Instancia de la clase MinMaxScaler de la libreria sklearn, sirve para escalar los datos y devolverlos a la escala original posteriormente - last_values -- Arreglo de numpy, últimos valores para realizar la predicción - calc_val_error -- Booleano, indica si se calcula el error de validación, si no se calcula se devuelve None en este campo - calc_test_error -- Booleano, indica si se calcula el error de *testing*, si no se calcula se devuelve None en este campo - verbosity -- Entero, nivel de verbosidad de la ejecución del modelo, entre más alto más información se mostrará el límite es 4 y debe ser mayor o igual a 0 - saved_model -- Booleano, indica si se desea entrenar el modelo o cargar uno guardado. Si True se carga un modelo guardado, si False se entrena un nuevo modelo. - model_file_name -- *String*, nombre del archivo donde se guardará y/o se cargará el modelo - returns -- Booleano, indica si se está trabajando con retornos o no (serie diferenciada). True es que si se trabaja con retornos. Retorna: - rmse -- Flotante, raíz del error medio cuadrático de *testing*; retorna None si calc_test_error es False - rmse_val -- Flotante, raíz del error medio cuadrático de validación; retorna None si calc_val_error es False - y -- Arreglo de numpy, observaciones de la particón de *testing* en escala real - y_hat -- Arreglo de numpy, predicciones de la partición de *testing* en escala real - y_valset -- Arreglo de numpy, observaciones de la particón de validación en escala real - y_hat_val -- Arreglo de numpy, predicciones de la partición de validación en escala real - last -- arreglo de numpy, predicción de los últimos valores - [valor] -- Flotante, % de acierto en la dirección """ from sklearn.externals import joblib if(not saved_model): # print('training...') from sklearn.svm import SVR verbose = 0 if verbosity < 3 else min(verbosity - 2, 2) # model = SVR(kernel='poly', degree=1, gamma='scale', verbose=verbose) model = SVR(verbose=verbose, gamma='auto') model.fit(train_X, train_y.ravel()) joblib.dump(model, model_file_name) if(calc_val_error): y_valset, y_hat_val, rmse_val = calculate_rmse(n_series, n_features, n_lags, val_X, val_y, scaler, model) else: rmse_val, y_valset, y_hat_val = None, None, None if(calc_test_error): y, y_hat, rmse = calculate_rmse(n_series, n_features, n_lags, test_X, test_y, scaler, model) else: y, y_hat, rmse = calculate_rmse(n_series, n_features, n_lags, test_X, test_y, scaler, model) rmse = None last = predict_last(n_series, n_features, n_lags, last_values, scaler, model, 0) if(returns): dir_acc = utils.get_returns_direction_accuracy(y_valset.ravel(), y_hat_val.ravel()) else: dir_acc = utils.get_direction_accuracy(y_valset.ravel(), y_hat_val.ravel()) else: model = joblib.load(model_file_name) rmse = None rmse_val = None test_y = None y_hat_test = None val_y = None y_hat_val = None dir_acc = None return rmse, rmse_val, y, y_hat, y_valset, y_hat_val, last, dir_acc, model
def model_arima(train_X, val_X, test_X, train_y, val_y, test_y, n_series, d, q, n_features, n_lags, scaler, last_values, calc_val_error, calc_test_error, verbosity, saved_model, model_file_name, returns): """ Función para crear, entrenar y calcular el error del modelo ARIMA, también sirve para predecir Este modelo se contruye con la libreria statsmodels con el algoritmo SARIMAX por que proporciona mayor estabilidad y por que el problema contiene variables exogenas la implementación de la libreria es un poco enredada y la documentación no es la mejor, pero en python en cuanto a modelos ARIMA es de lo mejor que hay Cuando se introducen parámetros que no se pueden calcular matematicamente por el modelo arima se devuelven errores de 90000000000 en validación y *testing* y las demás variables se retornan en None Parámetros: - train_X -- Arreglo de numpy, datos de entrenamiento - val_X -- Arreglo de numpy, datos de validación - test_X -- Arreglo de numpy, datos de *testing* - train_y -- Arreglo de numpy, observaciones de entrenamiento - val_y -- Arreglo de numpy, observaciones de validación - test_y -- Arreglo de numpy, observaciones de *testing* - n_series -- Entero, el número de time steps a predecir en el futuro - d -- Entero, cantidad de diferenciaciones necesarias para que la serie a predecir sea estacionaria - q -- Entero, parámetro para el componente de media móvil del modelo - n_features -- Entero, el número de *features* con los que se entrena el modelo, también se conocen como variables exogenas - n_lags -- Entero, el número de *lags* que se usaran para entrenar - scaler -- Instancia de la clase MinMaxScaler de la libreria sklearn, sirve para escalar los datos y devolverlos a la escala original posteriormente - last_values -- Arreglo de numpy, últimos valores para realizar la predicción - calc_val_error -- Booleano, indica si se calcula el error de validación, si no se calcula se devuelve None en este campo - calc_test_error -- Booleano, indica si se calcula el error de *testing*, si no se calcula se devuelve None en este campo - verbosity -- Entero, nivel de verbosidad de la ejecución del modelo, entre más alto más información se mostrará el límite es 4 y debe ser mayor o igual a 0 - saved_model -- Booleano, indica si se desea entrenar el modelo o cargar uno guardado. Si True se carga un modelo guardado, si False se entrena un nuevo modelo. - model_file_name -- *String*, nombre del archivo donde se guardará y/o se cargará el modelo - returns -- Booleano, indica si se está trabajando con retornos o no (serie diferenciada). True es que si se trabaja con retornos. Retorna: - rmse -- Flotante, raíz del error medio cuadrático de *testing*; retorna None si calc_test_error es False - rmse_val -- Flotante, raíz del error medio cuadrático de validación; retorna None si calc_val_error es False - test_y -- Arreglo de numpy, observaciones de la particón de *testing* en escala real - y_hat -- Arreglo de numpy, predicciones de la partición de *testing* en escala real - val_y -- Arreglo de numpy, observaciones de la particón de validación en escala real - y_hat_val -- Arreglo de numpy, predicciones de la partición de validación en escala real - inv_yhat[-1] -- arreglo de numpy, predicción de los últimos valores - [valor] -- Flotante, % de acierto en la dirección """ from statsmodels.tsa.statespace.sarimax import SARIMAX from statsmodels.tsa.statespace.mlemodel import MLEResults from numpy.linalg.linalg import LinAlgError import warnings y_hat = [] y_hat_val = [] try: if(not saved_model): # print('training...') verbose = 0 if verbosity < 3 else verbosity - 2 model = SARIMAX(train_X[:, 0], exog=train_X[:, 1:], order=(n_lags, d, q), enforce_invertibility=False, enforce_stationarity=False, dynamic=False) model_fit = model.fit(disp=verbose, iprint=verbose, maxiter=200, method='powell') model_fit.save(model_file_name) final_endogs = np.append(val_X[:, 0], test_X[:, 0], axis=0) final_exogs = np.append(val_X[:, 1:], test_X[:, 1:], axis=0) diff_train_original_model = len(train_X) - model_fit.nobs if(diff_train_original_model > 0): final_endogs = np.insert(final_endogs, 0, train_X[-diff_train_original_model:, 0], axis=0) final_exogs = np.insert(final_exogs, 0, train_X[-diff_train_original_model:, 1:], axis=0) output = model_fit.predict(len(train_X), len(train_X) + len(val_X) + len(test_X) - 1, exog=final_exogs, endog=final_endogs) y_hat_val.extend(output[:len(val_y)]) y_hat.extend(output[len(val_y):len(val_y)+len(test_y)]) if(calc_val_error): tmp = np.zeros((len(y_hat_val), n_features)) tmp[:, 0] = y_hat_val y_hat_val = scaler.inverse_transform(tmp)[:, 0] tmp = np.zeros((len(val_y), n_features)) tmp[:, 0] = val_y val_y = scaler.inverse_transform(tmp)[:, 0] rmse_val = math.sqrt(mean_squared_error(val_y, y_hat_val)) else: rmse_val, val_y, y_hat_val = None, None, None if(calc_test_error): tmp = np.zeros((len(y_hat), n_features)) tmp[:, 0] = y_hat y_hat = scaler.inverse_transform(tmp)[:, 0] tmp = np.zeros((len(test_y), n_features)) tmp[:, 0] = test_y test_y = scaler.inverse_transform(tmp)[:, 0] rmse = math.sqrt(mean_squared_error(test_y, y_hat)) else: rmse, test_y, y_hat = None, None, None last = output[-1] last = last.reshape(-1, 1) Xs = np.ones((last.shape[0], n_lags * n_features)) inv_yhat = np.concatenate((last, Xs[:, -(n_features - n_series):]), axis=1) inv_yhat = scaler.inverse_transform(inv_yhat) inv_yhat = inv_yhat[:, 0:n_series] if(returns): dir_acc = utils.get_returns_direction_accuracy(val_y.ravel(), y_hat_val.ravel()) else: dir_acc = utils.get_direction_accuracy(val_y.ravel(), y_hat_val.ravel()) # train with whole data whole_X = np.append(np.append(np.append(train_X, val_X, axis=0), test_X, axis=0), last_values, axis=0) model = SARIMAX(whole_X[:, 0], exog=whole_X[:, 1:], order=(n_lags, d, q), enforce_invertibility=False, enforce_stationarity=False, dynamic=False) model_fit = model.fit(disp=verbose, iprint=verbose, maxiter=200, method='powell') model_fit.save(model_file_name) else: model_fit = MLEResults.load(model_file_name) rmse = None rmse_val = None test_y = None y_hat_test = None val_y = None y_hat_val = None dir_acc = None except (ValueError, LinAlgError) as exc: print('algo sucedió: ') print(exc) return 9e+10, 9e+10, None, None, None, None, None, 0, None return rmse, rmse_val, test_y, y_hat, val_y, y_hat_val, inv_yhat[-1], dir_acc, model_fit
def model_ada_boost(train_X, val_X, test_X, train_y, val_y, test_y, n_series, n_estimators, lr, max_depth, n_features, n_lags, scaler, last_values, calc_val_error, calc_test_error, verbosity, saved_model, model_file_name, returns): """ Función para crear, entrenar y calcular el error del modelo *ada boost*, también sirve para predecir Este modelo se construye con la libreria sklearn con el algoritmo AdaBoostRegressor y este ada boost se contruye a partir de árboles de decisión Parámetros: - train_X -- Arreglo de numpy, datos de entrenamiento - val_X -- Arreglo de numpy, datos de validación - test_X -- Arreglo de numpy, datos de *testing* - train_y -- Arreglo de numpy, observaciones de entrenamiento - val_y -- Arreglo de numpy, observaciones de validación - test_y -- Arreglo de numpy, observaciones de *testing* - n_series -- Entero, el número de time steps a predecir en el futuro - n_estimators -- Entero, número de árboles que se generaran en el bosque - lr -- Flotante, tasa de entrenamiento del modelo - max_depth -- Entero, profundida máxima del árbol de decisión que se utiliza para construir el *ada boost* - n_features -- Entero, el número de *features* con los que se entrena el modelo, también se conocen como variables exogenas - n_lags -- Entero, el número de *lags* que se usaran para entrenar - scaler -- Instancia de la clase MinMaxScaler de la libreria sklearn, sirve para escalar los datos y devolverlos a la escala original posteriormente - last_values -- Arreglo de numpy, últimos valores para realizar la predicción - calc_val_error -- Booleano, indica si se calcula el error de validación, si no se calcula se devuelve None en este campo - calc_test_error -- Booleano, indica si se calcula el error de *testing*, si no se calcula se devuelve None en este campo - verbosity -- Entero, nivel de verbosidad de la ejecución del modelo, entre más alto más información se mostrará el límite es 4 y debe ser mayor o igual a 0 - saved_model -- Booleano, indica si se desea entrenar el modelo o cargar uno guardado. Si True se carga un modelo guardado, si False se entrena un nuevo modelo. - model_file_name -- *String*, nombre del archivo donde se guardará y/o se cargará el modelo - returns -- Booleano, indica si se está trabajando con retornos o no (serie diferenciada). True es que si se trabaja con retornos. Retorna: - rmse -- Flotante, raíz del error medio cuadrático de *testing*; retorna None si calc_test_error es False - rmse_val -- Flotante, raíz del error medio cuadrático de validación; retorna None si calc_val_error es False - y -- Arreglo de numpy, observaciones de la particón de *testing* en escala real - y_hat -- Arreglo de numpy, predicciones de la partición de *testing* en escala real - y_valset -- Arreglo de numpy, observaciones de la particón de validación en escala real - y_hat_val -- Arreglo de numpy, predicciones de la partición de validación en escala real - last -- arreglo de numpy, predicción de los últimos valores - [valor] -- Flotante, % de acierto en la dirección """ from sklearn.externals import joblib if(not saved_model): # print('training...') from sklearn.ensemble import AdaBoostRegressor from sklearn.tree import DecisionTreeRegressor model = AdaBoostRegressor(DecisionTreeRegressor(max_depth=max_depth), n_estimators=n_estimators, learning_rate=lr) model.fit(train_X, train_y.ravel()) joblib.dump(model, model_file_name) if(calc_val_error): y_valset, y_hat_val, rmse_val = calculate_rmse(n_series, n_features, n_lags, val_X, val_y, scaler, model) else: rmse_val, y_valset, y_hat_val = None, None, None if(calc_test_error): y, y_hat, rmse = calculate_rmse(n_series, n_features, n_lags, test_X, test_y, scaler, model) else: y, y_hat, rmse = calculate_rmse(n_series, n_features, n_lags, test_X, test_y, scaler, model) rmse = None last = predict_last(n_series, n_features, n_lags, last_values, scaler, model, 0) if(returns): dir_acc = utils.get_returns_direction_accuracy(y_valset.ravel(), y_hat_val.ravel()) else: dir_acc = utils.get_direction_accuracy(y_valset.ravel(), y_hat_val.ravel()) else: model = joblib.load(model_file_name) rmse = None rmse_val = None test_y = None y_hat_test = None val_y = None y_hat_val = None dir_acc = None return rmse, rmse_val, y, y_hat, y_valset, y_hat_val, last, dir_acc, model
def model_lstm(train_X, val_X, test_X, train_y, val_y, test_y, n_series, n_epochs, batch_size, n_hidden, n_features, n_lags, scaler, last_values, calc_val_error, calc_test_error, verbosity, saved_model, model_file_name, n_rnn, n_dense, activation, drop_p, returns): """ Función para crear, entrenar y calcular el error del modelo LSTM, también sirve para predecir Este modelo está hecho en Keras solamente tiene dos capas una de LSTM y otra Densa o totalmente conectada, utiliza el optimizador Adam y la función de error es personalizada para darle mayor importancia a los priemros *lags* Parámetros: - train_X -- Arreglo de numpy, datos de entrenamiento - val_X -- Arreglo de numpy, datos de validación - test_X -- Arreglo de numpy, datos de *testing* - train_y -- Arreglo de numpy, observaciones de entrenamiento - val_y -- Arreglo de numpy, observaciones de validación - test_y -- Arreglo de numpy, observaciones de *testing* - n_series -- Entero, el número de time steps a predecir en el futuro - n_epochs -- Entero, número de epocas de entrenamiento - batch_size -- Entero, tamaño de los *bathcs* de entrenamiento - n_hidden -- Entero, número de estados escondidos de la red neuronal LSTM - n_features -- Entero, el número de *features* con los que se entrena el modelo, también se conocen como variables exogenas - n_lags -- Entero, el número de *lags* que se usaran para entrenar - scaler -- Instancia de la clase MinMaxScaler de la libreria sklearn, sirve para escalar los datos y devolverlos a la escala original posteriormente - last_values -- Arreglo de numpy, últimos valores para realizar la predicción - calc_val_error -- Booleano, indica si se calcula el error de validación, si no se calcula se devuelve None en este campo - calc_test_error -- Booleano, indica si se calcula el error de *testing*, si no se calcula se devuelve None en este campo - verbosity -- Entero, nivel de verbosidad de la ejecución del modelo, entre más alto más información se mostrará el límite es 4 y debe ser mayor o igual a 0 - saved_model -- Booleano, indica si se desea entrenar el modelo o cargar uno guardado. Si True se carga un modelo guardado, si False se entrena un nuevo modelo. - model_file_name -- *String*, nombre del archivo donde se guardará y/o se cargará el modelo. - n_rnn -- Entero, cantidad de redes neuronales recurrentes a usar antes de la por default - n_dense -- Entero, cantidad de capas densas a usar antes de la capa densa de salida - activation -- Entero, id de la activación que se quiere usar 0 para tanh, 1 para relu, se pueden agregar más - drop_p -- Flotante, porcentaje de las neuronas a volver 0 en la capa de dropout número entre 0 y 1 - returns -- Booleano, indica si se está trabajando con retornos o no (serie diferenciada). True es que si se trabaja con retornos. Retorna: - rmse -- Flotante, raíz del error medio cuadrático de *testing*; retorna None si calc_test_error es False - rmse_val -- Flotante, raíz del error medio cuadrático de validación; retorna None si calc_val_error es False - test_y -- Arreglo de numpy, observaciones de la particón de *testing* en escala real - y_hat_test -- Arreglo de numpy, predicciones de la partición de *testing* en escala real - val_y -- Arreglo de numpy, observaciones de la particón de validación en escala real - y_hat_val -- Arreglo de numpy, predicciones de la partición de validación en escala real - last -- Arreglo de numpy, predicción de los últimos valores - dir_acc-- Flotante, % de acierto en la dirección - model -- Modelo, instancia de modelo de keras, retorna el modeo entrenado """ n_out = n_series if(not saved_model): #print(batch_size, n_epochs, n_hidden, n_lags) # print('training...') from keras.layers import Dense, Dropout, LSTM, RepeatVector, Reshape, BatchNormalization from keras.models import Sequential from keras.optimizers import Adam from keras import backend as K verbose_dict = {0:0, 1:2, 2:1} activation_dict = {0:'tanh', 1:'relu'} verbose = 0 if verbosity < 3 else min(verbosity - 2, 2) verbose = verbose_dict[verbose] # for training on whole dataset whole_X = np.append(np.append(train_X, val_X, axis=0), test_X, axis=0) whole_y = np.append(np.append(train_y, val_y, axis=0), test_y, axis=0) K.clear_session() model = Sequential() if(n_series == 1): for i in range(n_rnn): model.add(LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) model.add(LSTM(n_hidden, activation=activation_dict[activation])) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(n_out)) else: model.add(LSTM(n_hidden, input_shape=(n_lags, n_features), return_sequences=False, activation=activation_dict[activation])) model.add(RepeatVector(n_out)) for i in range(n_rnn): model.add(LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(1)) model.add(Reshape((n_out,))) loss_func = weighted_mse if not returns else weighted_mse_returns opt = Adam(lr=0.001)#, clipvalue=0.005, decay=0.005) model.compile(loss=weighted_mse, optimizer=opt) history = model.fit(train_X, train_y, epochs=n_epochs, batch_size=batch_size, verbose=verbose, shuffle=False, validation_data=(val_X, val_y)) if(verbosity > 0): plt.figure() plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.suptitle('Training loss') # change window position mngr = plt.get_current_fig_manager() import matplotlib backend = matplotlib.get_backend() if backend == 'TkAgg': mngr.window.wm_geometry("+%d+%d" % (25, 55)) elif backend == 'WXAgg': mngr.window.SetPosition((25, 55)) else: # This works for QT and GTK # You can also use window.setGeometry mngr.window.move(25, 55) y_hat_val = model.predict(val_X) y_hat_test = model.predict(test_X) if(calc_val_error): # for validation rmses_val = [] rmse_val = 0 for i in range(n_out): tmp = np.zeros((len(y_hat_val[:, i].ravel()), n_features)) tmp[:, 0] = y_hat_val[:, i].ravel() y_hat_val[:, i] = scaler.inverse_transform(tmp)[:, 0] tmp = np.zeros((len(val_y[:, i].ravel()), n_features)) tmp[:, 0] = val_y[:, i].ravel() val_y[:, i] = scaler.inverse_transform(tmp)[:, 0] rmses_val.append(math.sqrt(mean_squared_error(val_y[:, i], y_hat_val[:, i]))) rmse_val = np.mean(rmses_val) else: rmse_val = None if(calc_test_error): # for test rmses = [] rmse = 0 for i in range(n_out): tmp = np.zeros((len(y_hat_test[:, i].ravel()), n_features)) tmp[:, 0] = y_hat_test[:, i].ravel() y_hat_test[:, i] = scaler.inverse_transform(tmp)[:, 0] tmp = np.zeros((len(test_y[:, i].ravel()), n_features)) tmp[:, 0] = test_y[:, i].ravel() test_y[:, i] = scaler.inverse_transform(tmp)[:, 0] rmses.append(math.sqrt(mean_squared_error(test_y[:, i], y_hat_test[:, i]))) rmse = np.mean(rmses) else: rmse = None K.clear_session() model = Sequential() if(n_series == 1): for i in range(n_rnn): model.add(LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) model.add(LSTM(n_hidden, activation=activation_dict[activation])) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(n_out)) else: model.add(LSTM(n_hidden, input_shape=(n_lags, n_features), return_sequences=False, activation=activation_dict[activation])) model.add(RepeatVector(n_out)) for i in range(n_rnn): model.add(LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(1)) model.add(Reshape((n_out,))) opt = Adam(lr=0.001)#, clipvalue=0.005, decay=0.005) model.compile(loss=weighted_mse, optimizer=opt) history = model.fit(whole_X, whole_y, epochs=n_epochs, batch_size=batch_size, verbose=verbose, shuffle=False) if(verbosity > 0): plt.figure() plt.plot(history.history['loss']) plt.suptitle('Whole data loss') # change window position mngr = plt.get_current_fig_manager() import matplotlib backend = matplotlib.get_backend() if backend == 'TkAgg': mngr.window.wm_geometry("+%d+%d" % (700, 55)) elif backend == 'WXAgg': mngr.window.SetPosition((700, 55)) else: # This works for QT and GTK # You can also use window.setGeometry mngr.window.move(700, 55) plt.show() model.save(model_file_name) #pats = model.predict(whole_X) #print('rmse total training: ', utils.calculate_rmse(pats, whole_y)) #print('direction accuracy total training: ', utils.get_direction_accuracy(pats, whole_y)) # predict last last = model.predict(last_values) # transform last values tmp = np.zeros((last.shape[1], n_features)) tmp[:, 0] = last last = scaler.inverse_transform(tmp)[:, 0] if(returns): dir_acc = utils.get_returns_direction_accuracy(val_y.ravel(), y_hat_val.ravel()) else: dir_acc = utils.get_direction_accuracy(val_y.ravel(), y_hat_val.ravel()) else: from keras.models import load_model model = load_model(model_file_name, custom_objects={'weighted_mse': weighted_mse}) last = model.predict(last_values) # transform last values tmp = np.zeros((last.shape[1], n_features)) tmp[:, 0] = last last = scaler.inverse_transform(tmp)[:, 0] rmse = None rmse_val = None test_y = None y_hat_test = None val_y = None y_hat_val = None dir_acc = None return rmse, rmse_val, test_y, y_hat_test, val_y, y_hat_val, last, dir_acc, model
def main(): """ Main del proyecto, este archivo no es necesario, puede ser personalizado o incluso crear uno nuevo, este es simplemente el estilo del creador de este proyecto contiene la interacción de un usuario final con el proyecto. Mediante este archivo se leen los datos de un archivo .csv, se inicializan los hyperparámetros para la ejecución se invoca al proyecto para que entrene y realice las predicciones y se grafican los resultados #### Models ids #### # 0 -> LSTM # 1 -> Random Forest....................(only available for 1 time step) # 2 -> AdaBoost.........................(only available for 1 time step) # 3 -> SVM..............................(only available for 1 time step) # 4 -> Arima............................(only available for 1 time step) Se manjean 12 hyperparámetros principales - model -- Entero, el id del modelo que se va a utilizar (ver ids arriba) - parameters -- Booleano, indica si se va a hacer optimzación de parámetros - select -- Booleano, indica si se va a hacer selección de variables - original -- Booleano, indica si se va a entrenar con las variables originales o con las variables seleccionadas, True es con las originales (si select es True este es False automaticamente) - time_steps -- Entero, número de tiempos en el futuro que se van a predecir - max_vars -- Entero, número máximo de variables a ser seleccionadas por el algoritmo de selección de variables, si select es False, este parámetro no importa - verbosity -- Entero, número que indica el nivel de verbosidad de la ejecución, hasta 2 muestra gráficas, de ahí para arriba muestra *logs* de la ejecución - parameters_file_name -- String, nombre del archivo donde se va a guardar o cargar el modelo entrenado, si este parámetro es None, se utilizan los parámetros por *default* - MAX_EVALS -- Entero, número de iteraciones de la optimización bayesiana, si parameters es False este parámetro no importa - saved_model -- Booleano, indica si se desea entrenar el modelo o cargar uno guardado. Si True se carga un modelo guardado, si False se entrena un nuevo modelo. - model_file_name -- String, nombre del archivo donde se va a guardar y/o cargar el modelo entrenado, si saved_model es False este parámetro solo importa para guardar el modelo - returns -- Booleano, indica si se está trabajando con retornos o no (serie diferenciada). True es que si se trabaja con retornos. Hay 1 hyperparámetro adicional que es: - predicting -- Entero, id de la columna dentro del dataframe de la variable objetivo a predecir, para que en el caso que esta no sea la posición 0, se intercambie """ # Parameters model = 0 # id of model to use parameters = 0 # Set to True for performing bayes optimization looking for best parameters select = 1 # set to True for performing feature selection original = 0 # set to True for training with original data (not feature selected) time_steps = 5 # number of periods in the future to predict max_vars = 200 # maximum number of variables for taking in count for variable selection verbosity = 0 # level of logs parameters_file_name = 'parameters/camilo.pars' # 'parameters/default_lstm_%dtimesteps.pars' % time_steps MAX_EVALS = 50 saved_model = False model_file_name = None # 'models/lstm-noSW-prueba.h5' returns = True # 0: algoritmo genetico, 1: simulated annealing, 2: stepwise selection variable_selection_method = 2 # input_file_name = 'data/forecast-competition-complete.csv' # input_file_name = 'data/data_16_11_2018_differentiated.csv' input_file_name = 'data/data_16_11_2018.csv' # input_file_name = 'data/data_returns.csv' dataframe = pd.read_csv(input_file_name, header=0, index_col=0) df = pd.DataFrame() # output_file_name = 'results/salida_' + str(time_steps) + '_periodos.csv' output_file_name = 'results/salida_' + str( time_steps) + '_periodos_SPTR.csv' # choose the feature to predict predicting = 0 cols = dataframe.columns predicting = cols[predicting] cols = set(cols) cols.remove(predicting) cols = [predicting] + list(cols) dataframe = dataframe[cols] out = dataframe.columns[0] mini = min(dataframe.loc[:, out].values) maxi = max(dataframe.loc[:, out].values) rango = maxi - mini p = [] ini = 200 fin = 225 step = 1 # time_steps train, _ = split_data(dataframe.values, ini) predictor = series_predictor.Predictor(dataframe.values, model, original, time_steps, train, cols, parameters, select, max_vars, verbosity, parameters_file_name, MAX_EVALS, saved_model, model_file_name, returns, variable_selection_method) for i in range(ini, fin, step): print(i) train, test = split_data(dataframe.values, i) pred = predictor.predict(train[[-1]]) actual = test[0:time_steps, 0] print('prediction:', pred) print('observation:', actual, end='\n\n') df = df.append(pd.Series([pred]), ignore_index=True) p.append(pred) datos = dataframe.values[ini:fin + min(step * 2, 20)] # datos = dataframe.values[ini-time_steps:fin-time_steps] preds = np.array(p).ravel() tam = min(len(preds), len(datos)) print('real rmse: ', utils.calculate_rmse(datos[:tam, 0], preds[:tam])) if (returns): print('real direction accuracy: %f%%' % (utils.get_returns_direction_accuracy(datos[:tam, 0], preds[:tam]) * 100)) else: print( 'real direction accuracy: %f%%' % (utils.get_direction_accuracy(datos[:tam, 0], preds[:tam]) * 100)) plt.plot(datos[:, 0], label='observations', lw=10, color='red') if (time_steps > 1): for i in range(len(p)): pad = [None for j in range(i * step)] plt.plot(pad + list(p[i])) #, color='blue') else: plt.plot(p, label='predictions') plt.legend() if (returns): plt.plot(np.zeros(len(datos)), color='black') plt.suptitle('Predictions vs Observations', fontsize=16) plt.show() df.columns = [out] df.to_csv(output_file_name)
df_observations = df_observations.loc[201:, list(df_observations.columns)[0]] # change input from string to float df_returns[list(df_returns.columns)[0]] = df_returns[list( df_returns.columns)[0]].apply(convert_to_float) df_values[list(df_values.columns)[0]] = df_values[list( df_values.columns)[0]].apply(convert_to_float) returns_raw = df_returns.values.ravel() returns = transform_from_returns_to_values(df_returns.values.ravel(), bases) values = df_values.values.ravel() observations = df_observations.values # print(returns.shape) # print(values.shape) # print(observations.shape) plt.subplot(2, 1, 1) plt.plot(returns, label='returns', color='red') plt.plot(values, label='values', color='blue') plt.plot(observations, label='observations', color='green') plt.legend() #plt.show() plt.subplot(2, 2, 3) dir_accs = [ utils.get_returns_values_direction_accuracy(observations_raw, returns_raw), utils.get_direction_accuracy(observations, values) ] plt.bar(['returns', 'values'], dir_accs) plt.show()
def train_model(train_X, test_X, train_y, test_y, n_series, n_epochs, batch_size, n_hidden, n_features, n_lags, scaler, verbosity, n_rnn, n_dense, activation, drop_p, returns): n_out = n_series from keras.layers import Dense, Dropout, LSTM, RepeatVector, Reshape from keras.models import Sequential from keras.optimizers import Adam from keras import backend as K verbose_dict = {0: 0, 1: 2, 2: 1} activation_dict = {0: 'tanh', 1: 'relu'} verbose = 0 if verbosity < 3 else min(verbosity - 2, 2) verbose = verbose_dict[verbose] K.clear_session() model = Sequential() if (n_series == 1): for i in range(n_rnn): model.add( LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) model.add(LSTM(n_hidden, activation=activation_dict[activation])) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(n_out)) else: model.add( LSTM(n_hidden, input_shape=(n_lags, n_features), return_sequences=False, activation=activation_dict[activation])) model.add(RepeatVector(n_out)) for i in range(n_rnn): model.add( LSTM(n_hidden, return_sequences=True, activation=activation_dict[activation])) model.add(Dropout(drop_p)) for i in range(n_dense): model.add(Dense(n_hidden)) model.add(Dense(1)) model.add(Reshape((n_out, ))) opt = Adam(lr=0.001) #, clipvalue=0.005, decay=0.005) model.compile(loss=weighted_mse, optimizer=opt) history = model.fit(train_X, train_y, epochs=n_epochs, batch_size=batch_size, verbose=verbose, shuffle=False) y_hat = model.predict(test_X) if (type(y_hat) == list): print(y_hat) rmses = [] rmse = 0 for i in range(n_out): tmp = np.zeros((len(y_hat[:, i].ravel()), n_features)) tmp[:, 0] = y_hat[:, i].ravel() y_hat[:, i] = scaler.inverse_transform(tmp)[:, 0] tmp = np.zeros((len(test_y[:, i].ravel()), n_features)) tmp[:, 0] = test_y[:, i].ravel() test_y[:, i] = scaler.inverse_transform(tmp)[:, 0] rmses.append(math.sqrt(mean_squared_error(test_y[:, i], y_hat[:, i]))) rmse = np.mean(rmses) if (returns): dir_acc = utils.get_returns_direction_accuracy(test_y.ravel(), y_hat.ravel()) else: dir_acc = utils.get_direction_accuracy(test_y.ravel(), y_hat.ravel()) return rmse, test_y, y_hat, dir_acc, model