示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
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)
示例#6
0
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