Análisis técnico de mercados financieros basado en técnicas de inteligencia artificial Angel Pina Canelles Capıtulo 3: Aspectos Técnicos 3.1. Software DesarrolladoPara la realización de este trabajo ha sido necesario el desarrollo de un nuevo software específico que realizará los procesos descritos anteriormente. Este, desarrollado también como parte de este trabajo, ha sido realizado en lenguaje Java con el soporte de determinadas librerías especializadas. En las siguientes subsecciones se detallan las librer ́ ıas externas utilizadas, los módulos desarrollados, la estructura del software y finalmente se muestra la interfaz de usuario y funcionamiento.
3.1.1. Librerías UtilizadasPara el desarrollo del software se han empleado una serie de librerías externas para realizar las funcionalidades técnicas cuya implementación quedaba fuera de los objetivos de este trabajo. Así, las implementaciones relacionadas directamente con, por ejemplo, las redes neuronales o el algoritmo del análisis principal de componentes, se han delegado en librerías conocidas de aprendizaje computacional u otros ámbitos, que se detallan a continuación. Encog ([8]): Encog es una librer ́ ıa especializada de aprendizaje computacional, que implementa en el lenguaje Java la lógica y algoritmos de gran cantidad de técnicas de inteligencia artificial, como redes bayesianas o support vector machines. En particular, nosotros utilizaremos su implementaci ́ on de redes neuronales para nuestro software. Para ́ estas, incluye gran cantidad de algoritmos de entrenamiento, y otras funcionalidades adicionales como el almacenamiento y recuperación de redes ya entrenadas. WEKA ([9]): WEKA es una aplicación muy conocida de aprendizaje computacional, principalmente utilizada para minería de datos, también escrita en Java. Fue desarrollada por la Universidad de Waikato (Nueva Zelanda) y se distribuye bajo licencia GNU General Public. Aunque el software en sí´ı constituye una aplicación completa con interfaz de usuario, nosotros utilizamos directamente sus libros´ıas, que contienen los algoritmos del análisis principal de componentes, y delegamos tambi´en en ella algunas tareas menores como la normalizaci´on. Apache Commons Math ([10]): Es una librería escrita en Java de matemáticas y estadística que incluye muchas funciones no disponibles directamente en el lenguaje Java. En nuestro caso, utilizaremos de ella la implementación del ajuste por m´ınimos cuadrados ponderado. Jmathplot ([11]): Es una conocida librería´ıa open source de uso de gráficos en Java. Proporciona funcionalidad para mostrar gráficos de diversos tipos en 2D y 3D de forma sencilla. En nuestro caso la utilizaremos para la visualización de gráficas y resultados, especialmente para la funcionalidad de nuestro software relacionado con la monitorización y obtención de estad ́ ısticas.
3.1.2. Módulos Desarrollados Además, introducimos aquí´ı los módulos que han sido desarrollados y pueden ser entendidos de forma independiente, para facilitar la comprensión de la estructura global presentada en la sección siguiente. Estos son:
Comunicación con bases de datos Las bases de datos de Talentum se encuentran en un varios servidores propios, a los que nos conectaremos utilizando JDBC (Java Database Connectivity, [14]), pudiendo escribir nuestras consultas en SQL. Por tanto, necesitábamos conectarnos a diversas bases de datos en distintos host para obtener gran cantidad de datos diferentes (históricos del robot, datos del mercado y operaciones en tiempo real, etc.). Por ello, implementamos una primera clase con la funcionalidad básica de comunicación con la base de datos, de la que heredan otras clases espec ́ ıficas que refinan su comportamiento para los datos que utilizar ́ a. Además, para algunas funcionalidades, en general aquellas que tienen que ver con la persistencia de los datos de la propia aplicación se decidió no utilizar estas bases de datos. En su lugar, se implementó una clase que utilizaba como medio para guardar datos un fichero de texto de la que heredaron otras clases para datos espec ́ıficos: Información de los ficheros y casos de pruebas introducidos, información de las redes entrenadas, estado ́ısticas de ejecución, alimentación y recuperación de las propias redes neuronales, etc. De esta forma evitaremos sobrecargar las bases de datos de Talentum con más información, y a la vez hacer el programa mucho más portable, lo que nos resultaba útil por ser un desarrollo experimental. También se han almacenado en ficheros (.csv) la información de los históricos del mercado, de los que necesitamos gran cantidad de información, de forma que su acceso fuera mucho más rápido.
Módulo de tratamiento de históricos y casos de prueba Como la lógica de procesamiento del histórico de operaciones para obtener finalmente los casos de prueba era demasiado compleja, decidimos extraerlo en un módulo aparte. Así, en clases separadas se encuentra recogida la lógica de lectura de los históricos y su combinación con la información del histórico del mercado, la aplicación del análisis principal de componentes, y la normalización final. Hay que tener en cuenta que este modelo no solo debe permitir realizar el procesamiento antes de entrenar la red, sino que además debe guardar la información que necesite para aplicar el mismo procedimiento con los datos que queramos introducir en tiempo real en esta misma red. Es decir, debe aplicarles a los datos nuevos el análisis principal y la normalización con los mismos parámetros que utilizó para obtener los casos de prueba con los que entrenamos la red.
Módulo de redes neuronalesToda la lógica relacionada con las redes neuronales también fue encapsulada. En particular la l ́ ogica de creación de las mismas, su entrenamiento, ejecución y persistencia, se encuentran en este módulo. Además, proporciona una fachada que encapsula las peculiaridades propias de la librería que estamos utilizando para estas funciones, Encog.
Módulo de fiabilidad y control de errores Para implementar la funcionalidad de fiabilidad y control de errores teníamos varias estrategias disponibles, y es posible que unas funcionan mejor que otras en algunos casos, por lo que era interesante tener disponibles varias. Por ello, toda la lógica relacionada se encapsuló en otro módulo, que implementa principalmente el patrón Strategy. Este proporciona una interfaz con las operaciones únicamente de inicialización, añadiendo un nuevo resultado para actualizar el error y obtener el error esperado en base a una predicción.
3.1.3. Estructura General El software se puede dividir en 4 partes, diferenciadas tanto a nivel de estructura de clases como a nivel de interfaz y utilización. Las dos primeras coinciden en funcionalidad con las dos primeras fases expuestas en la sección 2.2, la tercera corresponde a la tercera y cuarta fase, y la cuarta parte corresponde a la obtención y visualización de estado´ısticas de ejecución de las redes. Es decir, las cuatro partes son: Procesamiento de los datos. Entrenamiento de las Redes Neuronales. Ejecución de las Redes y Monitorización. Visualización de estadísticas.
Además, todo el software ha sido desarrollado siguiendo la arquitectura de Modelo Vista-Controlador (MVC), por lo que los elementos del modelo seguirán en la ruta modelada.*, los de la vista la ruta view.* y los del controlador la ruta controller.*. Aunque existe cierta discusión al respecto, en nuestro caso consideraremos las clases relacionadas con las bases de datos como parte del modelo. La estructura del software de cada una de las secciones se detalla a continuación.
Procesamiento de Datos Contiene toda la lógica y funciones relacionadas con el proceso seguido desde que el usuario quiere introducir un nuevo robot en el sistema hasta que obtenemos un conjunto de casos de prueba que nos permitan entrenar una red para el mismo. As ́ ı, implementa la lectura de históricos de operaciones, la obtención de datos del histórico del mercado, la aplicación del análisis principal de componentes, la normalización de los datos... etc. Adem´as, permite almacenar tanto los ficheros en cada una de las etapas como los casos de prueba procesados, junto con toda su información relacionada (´ındice al que se refieren, datos que se han utilizado para modelizar la situación del mercado, etc.) para su uso en otras etapas, en la sesión actual o en otra posterior. Recordemos que esta parte del software también debe permitir el procesamiento de nuevos datos en tiempo real, para poder introducirlos en la red una vez puesta a funcionar. En la figura 3.1 podemos encontrar un diagrama de clases de esta parte. El controlador principal es DataController, y la clase principal de la vista es Data Controller Viewer. La clase DataFiles Table hereda de Abstract Table ([13]) para mostrar la información de todos los ficheros de datos del sistema. De esta clase heredan también las clases de las tablas de los otros apartados. La clase Backtest Factory nos proporciona los históricos de operaciones de cualquier robot, y la clase InputFile Factory encapsula la lógica de procesamiento de datos, delega la l´ogica de preparación de los casos de prueba sin preprocesar en File Preparer, la aplicaci´on del an´alisis principal de componentes en File Reducer y la de normalización en File Normalizer. El resultado de esta fase es un fichero de casos de prueba, cuyo estado de procesamiento y otros atributos se modelan en DataFile. DataFiles Database es, por tanto, la clase que implementa la lógica de persistencia de estos datos.
Entrenamiento de las Redes Contiene toda la lógica y funciones relacionadas puramente con las redes neuronales. Es decir, realiza el proceso principal desde el procesamiento de los casos de prueba hasta la obtención de la nueva red neuronal. Además, contiene la lógica puramente de ejecución de las redes en tiempo real (recibe la entrada y devolver la salida, no la controla ni interpreta). Por tanto, esta parte engloba toda la l ́ ogica de creación de redes, entrenamiento, ejecución, test y validación, y permite almacenarlas y recuperarlas en el mismo estado en una sesión posterior. Podemos encontrar un diagrama de clases de todo ello en la figura 3.2. En ́ el, Network Controller es el controlador principal, y Train Network Controller Viewer es la clase principal de la vista. De nuevo, Network File Table es una tabla que muestra la información ́ on de las redes en nuestro sistema, Network File representa esta información, y Networks Database almacena tanto la información como las propias redes. Adem ́as, Divided Supervised Sets permite dividir los casos de prueba convenientemente en entrenamiento, validación y test, y unas clases auxiliares, Network Training Result y Network Test Result agrupan los datos de resultados de los procesos de entrenamiento y test de las redes, respectivamente.
Figura 3.1: Diagrama de clases de Procesamiento de Datos.
Figura 3.2: Diagrama de clases de Entrenamiento de las Redes. Ejecución de las Redes y Monitorización Contiene las clases y lógica que permiten la ejecución del robot en tiempo real, y el control de los mismos. Es decir, desde la obtenci ́ on de la nueva red neuronal hasta el final del proceso, con esta red funcionando y facilitando sus datos a Zeus. Para ello, contiene la modelización de la red en ejecución, el acceso a las bases de datos para obtención de información ́ on del mercado en tiempo real, la consulta de las operaciones realizadas por cada robot en cada momento... etc. También contiene las clases relacionadas con la fiabilidad, y la comunicación con Zeus. Esta comunicación se realiza a través de una base de datos en la que nuestro sistema almacena sus predicciones sobre los robots en cada momento, que el sistema Zeus leerá cuando necesite hacer uso de ella. El diagrama de clases de esta sección se encuentra en la figura 3.3. De nuevo, Running Network Controller es el controlador principal, y RunNetworksControllerViewer la clase principal de la vista, con Running Networks Tabla la tabla que muestra la información principal. La modelización de la red en ejecución se realiza mediante la clase Running Network, que tiene asociada una red neuronal que es la que realmente realiza las operaciones y proporciona los resultados, y una clase que contiene el control de la fiabilidad para esa red. Por otra parte, Sets Control Database es la clase que almacena la información de nuestras predicciones y fiabilidad en la base de datos para ser usada por Zeus, y Signals Database recibe las operaciones realizadas por nuestros robots en tiempo real. Por último, recordemos que necesitamos datos en tiempo real del mercado, para lo que delegamos en Data Controller y su clase RealTime Market Facade.
Visualización de Estadısticas Por último, esta parte implementa algunas funcionalidades de visualización de datos y seguimiento en tiempo real de la ejecución de nuestro software. Permite obtener gráficas con las predicciones de nuestras redes en un momento determinado, así´ı como ver, para cada operación que hubieran realizado los robots sin nuestro sistema, si la hemos realizado o no, cuál era nuestra predicción y fiabilidad en ese momento, y el resultado final que ha tenido.
Figura 3.3: Diagrama de clases de Ejecución de las Redes. Además, mantiene registro de todos estos datos para su posterior consulta en ficheros de texto. Podemos encontrar este último diagrama de clases en la figura 3.4. Una vez m´ás, Stats Controller es el controlador principal y StarViewer la clase principal de la vista, mientras que Operations Table es la tabla en la que se muestra toda la información de las operaciones de los robots, que es obtenida de Signals Database y de sus registros internos de las predicciones realizadas. Por último, Network Plot permite mostrar la gráfica de predicciones de una red concreta en un intervalo de tiempo determinado, información que es guardada en StatFileResults. PlotUtils es una clase auxiliar que maneja la creación de gráficas.
3.1.4. Interfaz de UsuarioLa interfaz de usuario del software consta de un menú principal inicial, y 4 paneles de control, cada uno de ellos correspondiente a una parte principal del software descrita en la sección anterior. Así, el menú inicial, que se muestra en la figura 3.5, permite abrir dichos paneles de control. En ellos es en los que se realiza la lógica real de uso de la aplicación.
Manage DataSi elegimos la opción “Manage Data”, se despliega´a el panel de la figura 3.6 que permite añadir nuevos robots con su histórico de operaciones y procesarlos hasta obtener los casos de prueba. As´ı, este panel provee funciones para: a˜nadir nuevos robots al sistema, elegir las variables que utilizaremos para modelar la situación del mercado (que ser´a la entrada de nuestra red), procesar el histórico de acuerdo a estos datos, reducir su dimensionalidad utilizando el análisis de componentes principales, y normalizarlos. Finalmente, tendremos como resultado los casos de entrenamiento que utilizaremos para generar la red neuronal asociada al robot.
´ Figura 3.4: Diagrama de clases de Visualización de Estadísticas.
Figura 3.5: Menú Principal de la aplicación.
Figura 3.6: Panel de Procesamiento de Datos. Administrate NetworksPor otra parte, si en el menú principal elegimos “Administrate Networks” se desplegará el panel de entrenamiento de redes, que se encuentra en la figura 3.7. Este utiliza ́ los ficheros de casos generados en la etapa anterior para obtener nuevas redes. Para ello, permite las operaciones de crear una nueva red, elegir su topolog ́ ıa manualmente o dar una lista de posibles topolog ́ ıas, entrenarlas con distintos par ́ ametros y evaluar el resultado. Así, la tabla de este panel muestra toda la información elegida para la red, así como un resumen de sus resultados de entrenamiento y test.
Figura 3.7: Panel de Entrenamiento de Redes. Run NetworksEl tercer panel, desplegado al elegir “Run Networks” permite poner las redes entrenadas anteriormente en ejecución. Tras esto, automáticamente haŕan predicciones sobre su robot asociado que estar ́a ejecut ́andose en mercado real, y las almacenarán en una base de datos para que puedan ser consultadas por un agente externo. Podemos encontrar una imagen de este panel en la figura 3.8. Como podemos ver, incluye una tabla en la que se muestran los robots en ejecución, sus últimas predicciones y su fiabilidad, e información sobre si su robot asociado está operando. Además, permite activar y desactivar las redes en cualquier momento.
View Stats Por último, al pulsar “View Stats” se despliega el cuarto panel, que contiene varias opciones de visualización de estadísticas. Por ejemplo, podemos consultar las operaciones realizadas por los robots en un intervalo dado, o una gráfica con las predicciones de una red concreta en un cierto periodo de tiempo. Ası, incluye una tabla que muestra las ´últimas operaciones realizadas con informaci´on como si nuestro sistema la realizó o no, y cuál era la predicci´on y fiabilidad en ese momento, y opciones para el filtrado de ´estas y la visualización de gráficas sobre las predicciones de una red concreta.
3.2. Detalles Técnicos del Entrenamiento de Redes 3.2.1. El Problema del Overfitting Como se expone en la sección 2.1.2, el proceso de entrenamiento consiste en ajustar los parámetros de la red para que resuelva los casos de prueba conocidos, esperando que así sea capaz de generalizar aquellos que no lo son. El problema que se plantea consiste en que la red puede dar las salidas correctas para todos los casos de prueba, y dar salidas muy alejadas de las correctas para aquellos casos para los que no han sido entrenados. Uno de los posibles motivos de que ocurra esto es que la red ha quedado entrenada demasiado específicamente para resolver los casos concretos de entrenamiento, y por ello no es capaz de general los demás casos. A este problema se le conoce como overfitting o sobreentrenamiento. Los algoritmos de entrenamiento de redes ajustan en sucesivas etapas los parámetros de las neuronas para reducir el error producido en la predicción de los casos. Cada una de las iteraciones que se realizan utilizando una vez cada caso de entrenamiento se denomina epoch. Así, si ejecutamos el algoritmo de entrenamiento durante demasiados epochs, tendremos que la red se ajustará bien a los casos que utilizamos para su entrenamiento, pero fallaría al generalizar el problema con casos nuevos. Sin embargo, si lo ejecutamos durante demasiados días, la red no aprenderá el problema correctamente. Para resolver este problema, y poder conocer cuándo debemos finalizar el entrenamiento, debemos saber cuándo la red empieza a dar peores resultados para los casos para los que no la estamos entrenando. Para ello, inicialmente se divide el conjunto de casos que tenemos destinados al entrenamiento en dos subconjuntos: El conjunto de casos de training y el de validación. Así, el algoritmo que ajusta los pesos de las neuronas en base a ciertos casos utilizar´a ´únicamente los casos de training, y utilizaremos los casos de validación para detectar cuándo debemos detectar el proceso. Normalmente la división en los subconjuntos de training y validación se realiza utilizando un 10 ´o 20 % de casos aleatoriamente elegidos para validación, y los restantes para entrenamiento. Al estar entrenando la red para esos casos, el error que cometemos ajustando los casos de training decrece con el tiempo. Sin embargo, al no estar utilizando para el entrenamiento los casos de validación, tenemos que la red se comportará con estos de la misma forma que lo haría para los casos cuya salida correcta no conocemos, que son los que queremos resolver. Por tanto, esperamos que el error que cometa en estos ´últimos decrece inicialmente con cada epoch, mientras la red se ajusta correctamente al problema, y se incremente conforme la red se ajusta demasiado espec´ıficamente para los casos de training, fallando al generalizar el problema. Puede verse un ejemplo de la evolución esperada de los errores de training 1 y validación en la figura 3.10. Idealmente, detendremos el proceso cuando la red ya haya aprendido el problema y comience a sobre ajustarse a los casos de entrenamiento, por lo que normalmente nuestro criterio de detección será el incremento en el error de validación.
3.2.2. El Proceso Completo de Entrenamiento Aunque en otras secciones del trabajo se da una visión general bastante completa del proceso de entrenamiento, en esta sección expondremos los detalles técnicos que no quedan recogidos en dicha visi ́ on general. Recordemos que el proceso general se divide en dos fases: En una primera hacemos experimentos con diversas redes entrenadas siguiendo diferentes topolog ́ ıas, y elegimos aquella que consideramos mejor, y en una segunda fase entrenamos una nueva red con estas características. Sin embargo, como hemos visto en la sección anterior, para evitar el problema del overfitting debemos tener un criterio de detención del entrenamiento efectivo. En la primera fase utilizaremos el procedimiento descrito, consistente en dividir los casos disponibles para el entrenamiento en dos subconjuntos, de training y de validation, y utilizar el pri mero para ajustar los par ́ametros y el segundo para detectar cuando empieza a producirse overfitting. Además, tenemos que hacer varios experimentos para cada red, normalmente 10 ́ o 20, y queremos que ́ estos cubran la mayor cantidad de situaciones posibles. Para ello, en lugar de utilizar siempre la misma división en casos de training y validación, la cambiaremos en cada experimento para asegurar que todos los casos se han utilizado para training y para validación la misma cantidad de veces. Para ello, utilizamos un procedimiento conocido como K-cross validation, que consiste en dividir el conjunto de entrenamiento en K partes o pliegues, y utilizar en cada experimento uno de ellos para validación, y los K − 1 restantes para entrenamiento. As´ı, si queremos realizar 10 experimentos para cada topolog´ıa y utilizamos 10-cross validation, tenemos que utilizamos un 10 % de los datos para validación, y que todos los casos se usan una ´única vez para este subconjunto, y 9 para el de entrenamiento. Por otra parte, de la segunda fase obtendremos la red que utilizaremos posteriormente, por lo que querr´ıamos utilizar todos los casos posibles para su entrenamiento, pero entonces tendrá´ıamos que emplear otro método de detención, puesto que ya no utilizar´ıamos conjunto de validation. Este nuevo criterio de detención consiste en calcular el número medio de epochs que se produjeron hasta la detención del entrenamiento en los experimentos realizados para esta topología en la primera fase. Así, podemos utilizar todos los datos disponibles para entrenamiento para ajustar los parámetros, sin tener que dividirlo en los subconjuntos de training y validación. Además, existe en realidad otra etapa, que en el resto del documento tan sólo se nombra brevemente, denominada fase de test. El objetivo de esta etapa es obtener una estimaci´on de c´omo funcionar´a la red reci´en entrenada con datos nuevos que no han sido usados ni para el entrenamiento ni para la elecci´on de la topología. Para ello, de nuestro conjunto total original de casos de prueba, se suelen reservar un 20 ´o 30 % de los datos para esta fase. Así, podemos utilizar estos datos no vistos para ejecutar la red, y calcular medidas del error para ́ este. Estos errores serán presumiblemente similares a los que tendremos cuando ejecutemos la red para casos nuevos reales. Para concluir, es relevante aclarar que para la implementación del software hemos utilizado un tipo de redes neuronales conocidas como Multi Layer Perceptron (MLP). Por último, como función de activación (una función empleada internamente en la red neuronal en las conexiones entre neuronas) hemos utilizado la tangente hiperbólica.
3.3. Análisis de Componentes PrincipalesEl An ́ alisis de Componentes Principales es un algoritmo de reducción de datos que transforma un conjunto de variables posiblemente correladas en otras linealmente incorreladas. Para ello, aplica una transformación ortogonal, y las variables resultantes se denominan componentes principales. Además, veremos que las componentes principales resultantes quedan ordenadas según su varianza. Antes de describir el algoritmo del análisis principal de componentes introducimos un resultado previo, que constituye la parte central del mismo. Este resultado, bastante conocido en matemáticas, es el cálculo del cociente de Rayleigh de una matriz sim ́ etrica. En primer lugar, consideremos un conjunto de n puntos xj, j = 1, ..., n con xn ∈ Rm, representados como una matriz m × n X = [x1, ..., xn]. Definimos el problema de maximizar la varianza como el de encontrar una dirección u ∈ Rn tal que la varianza de la muestra uT X = (uT x1, ..., u xn) sea m ́ axima. Este problema puede ser visto también cómo encontrar el vector u tal que la varianza de los puntos de la muestra proyectados sobre la recta que pasa por el origen y tiene dirección u es m ́ máxima. Esto puede expresarse formalmente como:
((xj − x¯)T u)2 O equivalentemente: m´ax u:||u||2=1 1 n Xn j=1
u:||u||2=1uTΣu m´ax Con Σ = 1 nP j=1(xj−x¯)(xj−x¯)T La matriz de covarianzas. Este problema, que como ya hemos comentado consiste en el cálculo del cociente de Rayleigh de una matriz sim ́ etrica, tiene soluciones conocidas. Para su resolución, basta con diagonalizar la matriz de covarianzas Σ y escoger como direcci ́ on u el vector propio correspondiente al mayor valor propio. Como hemos adelantado, el algoritmo del análisis de componentes principales se basa en la resolución del problema anterior. Su ejecución consiste simplemente en tomar la dirección para la muestra que maximiza la varianza (conforme acabamos de ver) y proyectar la muestra sobre el subespacio ortogonal a esta dirección. De esta forma, todas las muestras proyectadas sobre el subespacio ortogonal son evidentemente ortogonales a la que acabamos de tomar, y por lo tanto son incorreladas. Interpretando sucesivamente este método obtenemos todas las componentes principales, cumpliendo además que están ordenadas según su varianza. Evidentemente, el número de componentes principales (no nulas) es siempre menor o igual que el número original de variables. Además, podemos entender la varianza de las componentes como la “cantidad de información que contienen”, y por tanto las tendrá´ıamos ordenadas según ese criterio. Por ello, este método suele emplearse para reducir la dimensionalidad de nuestros datos. Es decir, para descartar aquellas componentes que tienen menos información para reducir nuestro número de variables de entrada. [5] Más concretamente, utilizaremos que la varianza total de la muestra es la suma de las varianzas de las componentes, y esta es precisamente la traza de la matriz de covarianzas. Por tanto, si Σ es la matriz de covarianzas y ∆ es esta misma matriz diagonalizada (Σ = U∆UT), entonces la varianza total es precisamente: T rΣ = T r(U∆UT) = T r(UTU∆) = T r∆ = λ1 + ... + λn Es decir, la suma de los valores propios de la matriz de covarianzas. Por tanto, si proyectamos nuestra muestra sobre las direcciones dadas por los primeros k valores propios, tenemos que la varianza total del subespacio es λ1 + ... + λk. Pero estas direcciones son, precisamente, las primeras k componentes principales. [7] As´ı, si queremos mantener, digamos, el 95 % de la varianza, bastar´ıa con que la proporción entre la varianza total original y la varianza de la muestra proyectada en el subespacio fuera 0.95, es decir: λ1 + ... + λk λ1 + ... + λn>= 0,95 Esta reducción es útil, por ejemplo, para aumentar el rendimiento de cálculo del software que se utilizará en dichas entradas. Además, normalmente mejora incluso la capacidad de este de generalizar un problema dado, debido a que ya habremos eliminado parte de la información redundante o no útil. Normalmente, este método nos permite reducir sustancialmente el número de variables de entrada a la vez que mantenemos el 95 ́ o incluso el 99 % de la varianza.
3.4. Tests EstadísticosLos tests estad ́ ısticos de hipótesis son un método de Inferencia Estad ́ ıstica para contrastar la fiabilidad de un resultado experimental. Cuando se realiza cualquier experimentación siempre existe la posibilidad de que los resultados, favorables o no, hayan sido debidos al azar, cuando en realidad el resultado con mayor probabilidad era el contrario. Por ejemplo, si estamos comparando dos m ́etodos y al realizar una cierta cantidad de expe rimentos, un m ́etodo parece mejor que otro, es posible que esto solo sea por los resultados de ese conjunto de experimentos aleatorios concretos, cuando en realidad si pudiéramos realizar suficientes experimentos el resultado ser ́ıa el contrario. Los tests estad ́ ısticos nos permiten controlar la probabilidad de equivocarnos haciendo estas consideraciones. Antes de explicar los tipos de tests estad´ısticos e introducir con especial profundidad aquellos que utilizaremos en este trabajo concreto, definimos algunos conceptos previos: Definición 3.4.1. Definimos la hipótesis nula como aquella hipótesis que queremos contrastar, mientras que la hipótesis alternativa es aquella contra la que queremos contrastar. Definición 3.4.2. Sea X una variable aleatoria, se dice que el vector aleatorio de dimensión n, (X1, ..., Xn) es una muestra aleatoria simple (m.a.s.) de tama ̃no n de X, si para cada variable Xj ́esta sigue la misma distribución que X y las variables Xj son independientes entre s´ı. [6] Es decir, tenemos que si X es la variable aleatoria que representa nuestro experimento, una muestra aleatoria simple puede ser vista como una sucesi´on de experimentos de X, que cumplen ser independientes entre s´ı (esto es, que el resultado de una de las repeticiones del experimento no influye en el resto). A continuaci´on, como definiciones relativas directamente al contraste de hipótesis, tenemos las siguientes: Definición 3.4.3. Denominamos error de tipo I a la probabilidad de rechazar la hipótesis nula cuando es verdadera, y error de tipo II a la probabilidad de aceptarla cuando es falsa. Cuando queremos realizar un contraste de hipótesis, se debe fijar cual es el mayor error de tipo I que estamos dispuestos a cometer, y con ́ este fijo buscamos un contraste que minimice el error de tipo II. A este primer error se le suele denominar α, y al segundo β. Normalmente se dice ̃nan los contrastes de forma que la probabilidad α (de rechazar la hip ́otesis nula cuando es verdadera) sea el 5 % (0.05). A la variable α también se le conoce como nivel de significación del test. Veremos a continuación dos definiciones adicionales antes de pasar a estudiar el contraste que utilizaremos en nuestro trabajo: Definición 3.4.4. Sea (X1, ..., Xn) una m.a.s. de X, llamaremos estad´ıstico a cualquier vector aleatorio (k-dimensional) h(X1, ..., Xn), donde x : Rn− > Es una funci´on medible Borel. Definición 3.4.5. Sea X una variable aleatoria con distribuci ́on Fρ con par ́ametro ρ, y sea X = (X1, ..., Xn) una m.a.s. de X, se dice que el intervalo (i(X), s(X)) es un intervalo de confianza al nivel 1 − α, para el par ́ametro ρ si P(i(X) ≤ ρ ≤ s(X)) ≥ 1 − α Es decir, un intervalo de confianza es un intervalo obtenido a partir de la más. que cumple que, si la variable aleatoria sigue una distribución determinada Fρ, la probabilidad de que ρ se encuentre en ese intervalo es mayor que 1 − α. Una vez introducidos estos conceptos y definiciones, expondremos el proceso general de realización ́ on de un test estad ́ ıstico y finalmente lo completamos para explicar el test concreto utilizado en este proceso, conocido como test. El proceso general de realización de un test estadístico es el siguiente: Se estudia el problema y se establecen las hipótesis nula y alternativa. Establecemos las asunciones para la muestra estudiada. Por ejemplo, las distribuciones de ́ estas o si son independientes. Se decide el test a utilizar, y en consecuencia el estadístico T. Se elige el nivel de significación α. Se calculan las regiones críticas correspondientes al estado´ıstico y al nivel de significación α. Se calcula el valor tobs del estad´ıstico T para los resultados observados de los experimentos. Si el valor observado tobs se encuentra en la región cr´ıtica, rechazamos la hipótesis, y la aceptamos en caso contrario.
El procedimiento concreto de realización del test depende principalmente, como hemos comentado, de la hip ́ otesis que queramos contrastar y de la distribución ́ on de los experimentos. En nuestro caso, utilizaremos un test para comparar los resultados arrojados por redes neuronales de distintas configuraciones, para elegir con cual quedarnos. El objetivo ser ́ a decidir si entre dos redes distintas existe significancia estad ́ ıstica de que una de ellas proporciona mejores resultados que la otra. Es decir, lo que querremos saber ser ́ a sí podemos asegurar que las medias de los resultados de una y otra son distintas. Por tanto, nuestra hipótesis nula sería que las medias son iguales, y la hipótesis alternativa que son distintas. El procedimiento y estadísticos concretos constituyen resultados bien conocidos, que pueden consultarse por ejemplo en [6] . As´ı, el estado´ıstico que utilizaremos es el siguiente: t =X¯1 − X¯2
sX1X2· q 2 n (3.1)
donde X1 y X2 son las medias de las dos muestras experimentales, y r1
sX1X2 = 2(s2X1 + s2X2)
siendo s2X1y s2X2son los estimadores de las varianzas de las muestras, es decir, s2X = Pn i=1(xi−x¯)2 n Finalmente, tenemos que el intervalo de confianza, que tambi´en es un resultado cono
cido, es: (X¯1 − X¯2 − t1− α2S, X¯1 − X¯2 + t1− α2S) (3.2)
Así, nuestro procedimiento final consiste simplemente en calcular la observación del estad´ıstico t seg´un 3.1, y comprobar si se encuentra en el intervalo dado por 3.2. Si es así, aceptaremos la hipótesis nula, es decir, que no podemos distinguir sus medias, y en caso contrario la diferencia entre ellas será´a estas´ısticamente significativa.
3.5. Medidas de Error y Fiabilidad Tras la implementación del primer prototipo de nuestro sistema, que no incluía un sistema de control de errores sino que ́ únicamente emiten ́ ıa las predicciones, pusimos a funcionar el software para evaluar sus resultados preliminares. Concluimos que las redes eran capaces de predecir bastante bien los resultados de los robots en “las circunstancias más normales”, esto es, la mayor parte del tiempo, pero que sin embargo hab´ıa semanas en las que se encadenaban varias operaciones en las que las redes fallaban sus predicciones, provocando pérdidas importantes y un empeoramiento sustancial de la eficacia de nuestro sistema. Por ello, procedimos a diseñar e implementar un elemento “externo” a las redes que evaluará su eficacia a muy corto plazo. Estudiando los resultados, vimos que los periodos en los que la red pasaba de actuar razonablemente bien a actuar mal eran muy cortos, cambiando de una semana a la siguiente. Por ello, necesitábamos cambiar el error estimado de forma muy rápida, basándonos sobre todo en las últimas predicciones. Es decir, utilizando principalmente en los resultados de las últimas 3 o 4 operaciones, tenemos que estimar el grado de fiabilidad de la predicción que nos da la red en el momento actual. Cuando en un principio se planteó el desarrollo de un sistema de estimación de errores, una de las soluciones que se planteó fue utilizar técnicas de Inferencia Estadística, empleando intervalos de confianza. Sin embargo, debido a la limitación de basarnos casi únicamente en las últimas 3 o 4 operaciones, esta aproximación era inviable. Necesitábamos otra aproximación que nos permitiera obtener conclusiones con muy pocos datos, y no como un promedio a largo plazo. Nuestro objetivo en esta sección es, por tanto, exponer el desarrollo que nos llevó al sistema actual de estimación del error para las predicciones de beneficio de una red neuronal, basándonos únicamente en sus resultados en las últimas 3 o 4 operaciones. Esto permitirá a quien utiliza esta predicción juzgar mejor su decisión de elegir unos u otros robots en función del riesgo que esté dispuesto a correr. Por ejemplo, si la predicción es que ganar´a poco y el error que esperamos es grande, es poco probable que se quiera utilizar este robot, mientras que si la predicción es que ganar´a mucho y tenemos un error esperado moderado, s´ı es probable que queramos dejarlo operar. Para ello, se plantearon dos aproximaciones iniciales partiendo de dos ideas básicas distintas, y tras cierta reflexión, resultaron ser de alguna forma similares a casos concretos de una solución más general, que exponemos en último lugar. Partimos de una variable R que refleja el valor real del beneficio que obtiene el robot al realizar una cierta operación, y una variable P que nos da el valor predicho por nuestra red. Evidentemente, el valor de R nos resulta desconocido, y lo que queremos es establecer alguna relación entre ellos, que ser ́ a nuestra medida del error cometido. Una primera aproximación planteada consiste en expresar el error cometido como un sumando, es decir, suponer que la funci ́on P aproxima a R salvo un determinado error que ser ́a la diferencia entre ambas: R = P + con la función que queremos estimar, y despejando tenemos que = R − P. Dado que queremos utilizar los ´últimos 3 ´o 4 valores para estimar nuestro error, podríamos simplemente tomar el promedio del valor absoluto de esta resta para esos valores, y utilizarlo como estimación del error de la predicción siguiente. Es decir, poder´ıamos definir P4
err = i=1 ei y estimar que dada una nueva predicción P, el valor de R estar´a en el intervalo [P − err, P + err], por lo que es probable que el resultado de la operación será R > P − error. Así, una posible estrategia sería elegir aquellos robots con mayor valor para Perr, o aquellos tales que P −err > 0. Esta estrategia básica se puede mejorar estableciendo este umbral de forma más adecuada. Para ello, podemos simular los resultados que habr ́ ıamos obtenido para un intervalo de tiempo pasado determinado en el caso de utilizar esta estrategia con distintos umbrales, y finalmente quedarnos con aquel que proporcione mejores resultados. Además, podemos mejorar la forma de calcular errores, puesto que utilizando el promedio de las 4 ́ últimas operaciones, damos la misma importancia a la primera que a la última operación que consideremos, y a partir de esa no tenemos en cuenta ninguna otra. Parece más razonable que el peso de cada operación en la estimación final sea proporcional a su antigüedad. Para ello, cada vez que recibamos una nueva operación a tener en cuenta, disminuimos el peso que tenían las anteriores y añadimos esta última con mayor importancia. As´ı, si eren es el error que ten´ıamos en un momento dado y nos llega otro resultado a tener en cuenta, el nuevo error errn+1 se calcular´a segun: 0 = α · + (1 − α) · n Con un 0 < α < 1 adecuado. Este α determina cómo se reparte el peso entre las operaciones anteriores. Cuanto mayor sea, más importancia daremos al nuevo resultado que acabamos de recibir, y que por tanto ser ́ a el más reciente. Este α puede determinarse con el mismo procedimiento que expusimos para elegir el umbral anterior: Basta seleccionar varios posibles valores, simular que hubiera ocurrido en un intervalo de tiempo pasado, y elegir aquel valor de α que maximice nuestras ganancias. Con la implementación de esta primera aproximación ya se producirían mejoras significativas, aunque el segundo planteamiento expuesto a continuación daba resultados incluso mejores. La idea consiste en utilizar un factor multiplicativo en lugar de uno aditivo, como hacen el método anterior. De esta forma, suponemos que P determina R excepto por un determinado factor f por el que viene multiplicado. As´ı, en este caso podemos expresar R como: R = P · f Y de igual forma que antes, podemos despejar f seg ́ un f =RP, obteniendo un valor del mismo para cada resultado que tengamos. A continuación, de forma análoga al método anterior, podemos obtener un valor F que constituya un promedio ponderado de los factores f de los resultados pasados. Así, podemos utilizarlo para estimar el error esperado, asumiendo que dada una predicción nueva P0, el resultado que esperamos ser ́ aproximadamente R0 = P0·F. Con ello, una estrategia básica podr ́ ıa ser elegir aquellos robots para los que nuestra predicci ́ on sea P · f > U con U un umbral adecuado. Pero como hemos adelantado al principio, planteados de la manera adecuada, los dos métodos anteriores son en realidad similares a casos particulares de un m ́etodo ḿas general. La clave para ver la generalización consiste en imaginar los valores de P y R como puntos (P, R) en el plano, y plantear el problema como el de aproximar estos puntos mediante una recta. De esta forma, el primer método, en el que tratábamos de ajustar R por P + , consiste en realidad en un ajuste según una recta con pendiente 1 y ordenada en el origen . Por otra parte, el segundo método, ajustar R por P · f consiste en realidad en ajustar los puntos a una recta con pendiente f que pasa por el origen. Por ello, el método general que resulta lógico plantearse a continuación es precisamente el ajuste de mínimos cuadrados, en el que aproximamos una serie de puntos en el plano por una recta. Esta recta será aquella que minimice la suma de los cuadrados de las diferencias entre los valores de nuestro ajuste y los reales. Además, para continuar con la idea de darle más importancia a las operaciones más recientes, emplearemos el método algo más complejo del ajuste de m´ınimos cuadrados ponderado. Esta variación del método permite ajustar el peso que tendrá cada punto en el cálculo del error que queremos minimizar. Utilizaremos como peso para los puntos αn, con n el número de operaciones entre la actual y aquella a la que se refiere el punto. Este α puede ajustarse de la misma forma que en los métodos anteriores. Finalmente, obtendremos una recta y = mx + n que ajuste estos puntos, por lo que podemos estimar que el valor real que obtendremos de una operaci´on con predicci´on P ser´a R = P ·m+n. As´ı, una posible estrategia ser´ıa elegir aquellos robots cuya predicción cumpla que P · m + n > U para U un umbral ajustado. Por último, es importante resaltar que cada red tiene su propia fiabilidad y ajuste del error independiente, y que por tanto deben calcularse por separado. Esto es así debido a que hay situaciones en las que unas redes pueden funcionar muy bien y otras muy mal, y en general ni las redes ni los robots tienen porqué estar relacionadas entre sí. Con estos métodos establecemos un nuevo filtro que controla a la propia red, que a su vez supervisa los robots operando a mercado, y la mejora es realmente sustancial, en especial con el segundo y tercer método. Los resultados del sistema tras la implementación del método final anterior se exponen en la sección 4.2.
NotasPara evitar ambigüedades y aunque pueda estar claro por el contexto, nos referiremos por conjunto de entrenamiento al total de casos destinados a este proceso, y por conjunto de training (en inglés) al subconjunto de ´este que se utiliza para ajustar los par´ametros de la red durante el proceso.
|