scieee AI-readable full text Open interactive document viewer

Estimación recursiva de niveles RSS dinámicos mediante crowdsourcing y métodos kernel, en Python

Vela Calderón, Daniel

Abstract

Es bien sabido que el conocimiento de las comunicaciones inalámbricas supone uno de los principales esfuerzos a lo largo de la carrera de un ingeniero en telecomunicaciones. Se trata de un campo tan usado en la actualidad pero a la vez tan cambiante que hace que todo ingeniero dedicado a esta especialidad se encuentre en continua formación. Hoy en día, y desde hace algunos años, se está explorando cada vez con una mayor frecuencia la introducción del aprendizaje máquina, mayormente conocido como machine learning (ML), en este importante campo dentro de las comunicaciones. Este proyecto evalúa la aplicación de cierto algoritmo de ML en un escenario concreto con el fin de estimar la señal recibida en distintos puntos de dicho escenario, a partir de la información proporcionada por sensores de bajo coste cuyas medidas tienen una precisión muy baja. Las características del escenario de aplicación del algoritmo así como el modelo de propagación de señal que permite calcular la intensidad de campo recibido en los puntos del espacio son dos de los aspectos más interesantes en este proyecto. Para finalizar el apartado teórico, se mostrará las implicaciones y las consideraciones principales que tiene el algoritmo de ML seleccionado en este escenario. Aparte del aspecto teórico, este trabajo incluye una gran aportación desde el punto de vista de la programa ción de las ecuaciones teóricas. Se trata de un capítulo muy importante ya que realiza una asociación entre las ecuaciones teóricas y el lenguaje de programación usado. Además, dentro de este apartado se potencia el uso de librerías ya realizadas previamente con el fin de facilitar la aplicación del algoritmo de ML usado en este escenario. Estas librerías son presentadas y analizadas a lo largo del mencionado capítulo. Por último, este trabajo muestra las prestaciones del algoritmo de ML implementado a partir del cálculo del error entre las estimaciones realizadas y los valores de campo teóricos. A lo largo de la memoria se incluyen los aspectos más interesantes de las simulaciones así como los resultados obtenidos con el fin de valorar la fiabilidad y eficacia del algoritmo en este escenario concreto.

Full text

Proyecto Fin de Carrera Ingeniería de Telecomunicación Formato de Publicación de la Escuela Técnica Superior de Ingeniería Autor: F. Javier Payán Somet Tutor: Juan José Murillo Fuentes Dep. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2013 Trabajo Fin de Máster Máster Universitario en Ingeniería de Telecomunicación Estimación Recursiva de Niveles RSS Dinámicos Mediante Crowdsourcing y Métodos Kernel en Python Autor: Daniel Vela Calderón Tutor: Juan José Murillo Fuentes Dpto. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 Trabajo Fin de Máster Máster Universitario en Ingeniería de Telecomunicación Estimación Recursiva de Niveles RSS Dinámicos Mediante Crowdsourcing y Métodos Kernel en Python Autor: Daniel Vela Calderón Tutor: Juan José Murillo Fuentes Catedrático Universidad Dpto. Teoría de la Señal y Comunicaciones Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 Trabajo Fin de Máster: Estimación Recursiva de Niveles RSS D inámicos Mediante Crowdsourcing y Métodos Kernel en Python Autor: Daniel Vela Calderón Tutor: Juan José Murillo Fuentes El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores: Presidente: Vocal/es: Secretario: acuerdan otorgarle la calificación de: El Secretario del Tribunal Fecha: Agradecimientos El guardar un espacio para agradecimientos siempre me ha parecido una de las mejores prácticas que se pueden realizar en torno a cualquier trabajo. Es por ello que me gustaría emplear este apartado para agradecer el esfuerzo que han realizado ciertas personas con el fin de que este trabajo, así como el resto de la titulación que enmarca a este proyecto, haya podido salir adelante satisfactoriamente. Primeramente me gustaría agradecer al tutor de este proyecto, Juan José Murillo Fuentes por su ayuda a lo largo de los meses de duración del trabajo. Destaco en este punto la amabilidad mostrada, especialmente durante los primeros meses de la crisis sanitaria originada por el COVID-19. A pesar de no ser tiempos fáciles, Juan José siempré mostró la atención necesaria para que el trabajo se pudiera realizar dentro de los plazos marcados inicialmente. En este párrafo me gustaría mencionar a otros dos profesores, Juan Antonio Becerra Gónzalez e Hipólito Guzmán Miranda, por su ayuda y confianza depositada durante mis años de estudio. Sus consejos siempre fueron recibidos desde la absoluta admiración que tengo hacia ellos. Por otro lado, agradezco a aquellos compañeros de clase los cuales después de tantos años han llegado a convertirse en amigos . Entre ellos, destaco a Guillermo Palomino, Abraham Pérez, Diego López e Ildefonso Jiménez por su cercanía en estos años de estudio. He aprendido mucho de todos ellos y estoy convencido de que tendrán una exitosa carrera profesional por delante. Por último, me gustaría agradecer a mis padres, Diego y M ª Carmen por ser dos pilares tan fundamentales de mi vida, a mi hermano mayor Diego por su ejemplo y a mis dos hermanas pequeñas, Miriam y Ester por su enorme paciencia conmigo. No me quiero olvidar tampoco de aquellos amigos que han estado continuamente apoyándome y creyendo en mi y en mis capacidades y de entre los cuales, destaco a Abi, Dani, Miguel y Ana. A todos vosotros, muchas gracias. Daniel Vela Calderón Alumno del Máster Universitario en Ingeniería de Telecomunicación Sevilla, 2021 I Resumen Es bien sabido que el conocimiento de las comunicaciones inalámbricas supone uno de los principales esfuerzos a lo largo de la carrera de un ingeniero en telecomunicaciones. Se trata de un campo tan usado en la actualidad pero a la vez tan cambiante que hace que todo ingeniero dedicado a esta especialidad se encuentre en continua formación. Hoy en día, y desde hace algunos años, se está explorando cada vez con una mayor frecuencia la introducción del aprendizaje máquina, mayormente conocido como machine learning (ML), en este importante campo dentro de las comunicaciones. Este proyecto evalúa la aplicación de cierto algoritmo de ML en un escenario concreto con el fin de estimar la señal recibida en distintos puntos de dicho escenario , a partir de la información proporcionada por sensores de bajo coste cuyas medidas tienen una precisión muy baja. Las características del escenario de aplicación del algoritmo así como el modelo de propagación de señal que permite calcular la intensidad de campo recibido en los puntos del espacio son dos de los aspectos más interesantes en este proyecto. Para finalizar el apartado teórico, se mostrará las implicaciones y las consideraciones principales que tiene el algoritmo de ML seleccionado en este escenario. Aparte del aspecto teórico, este trabajo incluye una gran aportación desde el punto de vista de la programación de las ecuaciones teóricas. Se trata de un capítulo muy importante ya que realiza una asociación entre las ecuaciones teóricas y el lenguaje de programación usado. Además, dentro de este apartado se potencia el uso de librerías ya realizadas previamente con el fin de facilitar la aplicación del algoritmo de ML usado en este escenario. Estas librerías son presentadas y analizadas a lo largo del mencionado capítulo. Por último, este trabajo muestra las prestaciones del algoritmo de ML implementado a partir del cálculo del error entre las estimaciones realizadas y los valores de campo teóricos. A lo largo de la memoria se incluyen los aspectos más interesantes de las simulaciones así como los resultados obtenidos con el fin de valorar la fiabilidad y eficacia del algoritmo en este escenario concreto. III XÍndice 4.3 GPR aplicado en este escenario 26 4.3.1 Campo constante a lo largo del tiempo 26 4.3.2 Campo variante a lo largo del tiempo 28 4.4 Variación de la potencia transmitida a lo largo del tiempo 28 5 Python e implementación de GPR 31 5.1 Librerías usadas 31 5.1.1 Librería GPy 32 5.1.2 Mejora de la librería GPy 33 5.2 Entorno Virtual 34 6 Código desarrollado 39 6.1 Presentación de las clases 39 6.1.1 Class Flags 39 6.1.2 Class Variables 40 6.1.3 Class setup 40 6.1.4 Class aditional_functions 41 Function calculate_sample_shadow 42 Function estimate_tx_pos 42 Function alpha_beta_estimation 43 6.1.5 Class algoritmos 45 Function algoritmo_GPStatic 46 Function algoritmo_GPRecursive 49 6.1.6 Class gráficas 51 6.2 Fichero principal 51 6.3 Código desarrollado para sparse GP 52 7 Simulaciones y resultados obtenidos 53 7.1 Robustez de valores estimados 53 7.2 Estimación de campo recibido 54 7.2.1 Campo estático 54 Obtención de figuras 57 7.2.2 Campo dinámico 57 Obtención de figuras 58 7.2.3 Sparse GP 58 Obtención de figuras 59 7.3 Variación de la potencia transmitida a lo largo del tiempo 60 8 Conclusiones y trabajos futuros 61 8.1 Conclusiones 61 8.1.1 Conversión del Código 61 8.1.2 Aprendizaje ML 62 8.2 Trabajos futuros 62 Apéndice A Código correspondiente al script usado para obtener las figuras de la Sección 7.2 63 Índice de Figuras 69 Índice de Tablas 71 Índice de Códigos 73 Bibliografía 75 Notación A>Transpuesto de A A−1Inversa de la matriz A AHTranspuesto y conjugado de A A∗Conjugado enúmero e ejxExponencial compleja ej2πxExponencial compleja con 2π e−jxExponencial compleja negativa e−j2πxExponencial compleja negativa con 2π CXY covarianza de dos variables aleatorias reales XeY RXY correlación de dos variables aleatorias reales XeY ρXY Coeficiente de correlación de las variables aleatorias reales X eY FX(·)Función de distribución de la variable aleatoria X fX(·)Función densidad de probabilidad de la variable aleatoria X Pr(A)Probabilidad del suceso A E[X]Valor esperado de la variable aleatoria X σ2 XVarianza de la variable aleatoria X ∼fX(x) Distribuido siguiendo la función densidad de probabilidad fX(x) NmX,σ2 X Distribución gaussiana para la variable aleatoria X, de media mXy varianza σ2 X InMatriz identidad de dimensión n diag(x)Matriz diagonal a partir del vector x diag(A)Vector diagonal de la matriz A MSE Minimum square error xi,i=1,2,...,nElementos i,de1an, del vector x ⩽Menor o igual ⩾Mayor o igual a bFracción con estilo pequeño, a/b ∆Incremento CxMatriz de covarianza de x RxMatriz de correlación de x XI 1 Introducción La ciencia es una forma de pensar, mucho más que un cuerpo de conocimientos. Carl Sagan A lo largo de este capítulo se va a llevar a cabo una introducción del proyecto realizado como Trabajo Fin de Máster. Es bien sabido que las comunicaciones inalámbricas han crecido de manera muy significativa en los últimos años, siendo por tanto el uso del espectro y la detección de las comunicaciones llevadas a cabo sobre determinadas frecuencias, dos de los campos más estudiados en telecomunicaciones. A lo largo de las próximas secciones se profundizará más en estos dos puntos. Además, se presentará la importancia que tiene actualmente el Machine Learning en las telecomunicaciones, así como en otros aspectos de la ingeniería actualmente. Finalmente, se lleva a cabo una breve introducción del trabajo realizado de una manera más específica, así como una presentación de los distintos capítulos que forma esta memoria. 1.1 Uso eficiente del espectro radioeléctrico Aunque este trabajo está centrado en el segundo de los campos mencionados anteriormente, es necesario invertir algunas líneas presentando peculiaridades acerca del primero debido a su importancia en las telecomunicaciones. El espectro radioeléctrico es un recurso limitado y costoso por lo que se han invertido numerosos esfuerzos para poder explotar este recurso de la manera más eficiente posible. Las comunicaciones inalámbricas han formado parte de la rutina de los seres humanos desde hace algunos años, y actualmente no se podría concebir una sociedad desarrollada sin este tipo de comunicaciones. Es por ello que la demanda a la hora de acceder a este recurso se ha visto multiplicada en los últimos años, surgiendo de esta manera técnicas que han ido evolucionando a lo largo del tiempo y que han facilitado el acceso a este recurso de una manera eficiente. Por nombrar algunas de esta técnicas destaca la llamada spatial spectrum usada en comunicaciones de televisión digital terrestre [ 1 ] o la diversidad especial usada en comunicaciones móviles [ 2 ]. Aunque se podría profundizar más en estas técnicas y en otras muchas que ayudan a la explotación del espectro radioeléctrico, se ha querido únicamente mencionar alguna de ellas con el fin de dar importancia a la utilización eficiente de este limitado recurso. 1.2 Detección frecuencial o Spectrum Sensing El término anglosajón con el que se refiere a este campo recibe el nombre de spectrum sensing, y adquiere una gran importancia cuando se quiere estudiar la distribución de las señales de radiofrecuencia dentro de un área específica. De esta manera se pueden tener numerosas emisiones en distintas frecuencias sin interferir unas con otras [ 3 ]. De entre las numerosas técnicas que existen actualmente para spectrum sensing, se encuentran aquellas que están basadas en medidas proporcionadas por un conjunto de sensores [ 4 ]. Por tanto, la precisión de las medidas proporcionadas por estos sensores es crucial para una correcta distribución frecuencial. Este proyecto está centrado en la estimación de campo recibido a partir de la información proporcionada por una serie de sensores, y es por ello que la utilidad de este trabajo se puede centrar en la ayuda a estas técnicas de spectrum sensing al proporcionar una estimación precisa de campo recibido. 1 2Capítulo 1. Introducción La estimación de campo recibido a partir de sensores requiere en muchas ocasiones de una infraestructura en la cual los sensores están estratégicamente localizados a lo largo del área en la cual se quiere llevar a cabo una distribución espectral. Esta situación, además de poco realista, conlleva una inversión muy grande de dinero cuando estos sensores proporcionan medidas muy precisas ya que son dispositivos con precios muy elevados. Con el fin de encarar esta situación, apareció la técnica del crowdsourcing en la que los sensores usados son dispositivos los cuales proporcionan medidas menos exactas, pero cuyo precio decae considerablemente. Se pudo demostrar como a partir de la utilización esta técnica los resultados obtenidos son igualmente válidos provocando además una considerable reducción del dinero invertido [ 5 ]. Se trata de una técnica especialmente usada en campos como la localización interior gracias a comunicaciones vía WiFi [6]. El spectrum sensing no es la única técnica en la que las medidas proporcionadas por una serie de sensores (no necesariamente usando crowdsourcing) adquieren una gran importancia. Aplicaciones como el seguimiento de individuos o vehículos en interiores o exteriores [ 7 , 8 ], el cálculo de distancias [ 9 ] o la navegación 3D a través de un interior [ 10 ], son sólo algunos de los campos en los que destaca la estimación de señal recibida. 1.3 Machine Learning Para la estimación de campo recibido en un punto a partir de la información proporcionada por una serie de sensores se pueden usar técnicas de machine learning (ML). Las predicciones a partir de ML comenzaron a finales de los años cincuenta pero son especialmente importantes en la actualidad por su aportación a la sociedad en campos como la seguridad o los medios de comunicación entre otros, provocando de esta manera un incremento del bienestar en sociedades desarrolladas. Estas técnicas están basadas en modelos basados en datos, en los que el propio modelo aprende a partir de entradas y estima la salida basándose en la información proporcionada por las entradas. La predicción a partir de algoritmos de ML permite obtener resultados más fiables respecto a los que una persona podría proporcionar. De acuerdo a algunos estudios [ 11 ], un ser humano necesitaría de 536 días para poder procesar lo equivalente a 1TB de memoria, y al final de esos días, no sería capaz de recordar ni la mitad de la información. Los sistemas de computación actuales están preparados para procesar esa cantidad de memoria en sólo algunos segundos, y además tienen la ventaja de que un mayor número de muestras implica una mayor precisión en las predicciones. No sólo en la capacidad de almacenamiento, sino en otros aspectos como la velocidad o la veracidad de las predicciones los ordenadores ofrecen mejores prestaciones que los seres humanos [ 12 ]. Por todo ello, los algoritmos de ML son altamente usados actualmente, gracias a la irrupción del big bata, entre otros factores. La capacidad de aprender gracias a grandes cantidades de datos se ha visto potenciada una vez las técnicas de big data eran capaces de proporcionar esta cantidad ingente de información necesaria para una estimación precisa. La gráfica mostrada en la Figura 1.1 muestra de una manera clara como la aparición del big data ha provocado un considerable aumento en el uso de algoritmos de ML. Es por ello que los algoritmos de ML están experimentando una "segunda juventud". Figura 1.1 Crecimiento del ML (azul) y Big Data (rojo) en los últimos años [13]. Se podría escribir mucho acerca de la enorme variedad de algoritmos de ML que existen en la actualidad, y es por ello que una correcta decisión es crucial para conseguir el objetivo buscado de manera satisfactoria. En [ 14 ] se muestra una especie de diagrama de flujo que ayuda a la decisión del mejor algoritmo posible 1.3 Machine Learning 3 basándose en parámetros como el número de muestras, gasto computacional requerido, precisión en la predicción... En lo que resta de sección se van a presentar tanto los problemas que son capaces de resolver las técnicas de ML, como los algoritmos que son usados con mayor frecuencia en la actualidad. 1.3.1 Problemas Entre los problemas destacan los descritos a continuación: •Regresión : La dinámica de este tipo de situaciones es muy simple y está basada en encontrar una función f, obtenida a partir de una serie de entradas x, que proporciona una salida y, la cual puede ser un valor particular o un conjunto de valores. Es por ello que para resolver este tipo de problemas será necesario enfocarse en la búsqueda de medidas o cantidades específicas [15]. •Clasificación : Estos problemas aparecen constantemente en campos como el reconocimiento por voz o clasificación de documentación, entre otros, y su propósito final es muy fácil de entender ya que se trata de situaciones en las que es necesario separar y categorizar un set de datos en múltiples clases las cuales pueden ser etiquetadas [16]. •Agrupación : El fin último de este tipo de problemas es muy parecidos al de las situaciones de clasificación, pero con la diferencia de que en estos casos las agrupaciones o clases no están "preetiquetadas". Es por ello que será necesario hacer uso de técnicas que estén preparadas para buscar algún tipo de relación entre muestras pertenecientes a un set de datos. Están basadas en medidas previas y en patrones o reglas que deberían de repetirse por lo que son problemas a resolver en muchos campos. Entre otros, el web mining o la bio-informática [17]. •Detección de anomalías : En muchas ocasiones es necesario partir de un set de datos y encontrar aquellos que se diferencian significativamente del resto. Estos datos se suelen relacionar con eventos especiales y son problemas que aparecen regularmente en campos como el fraude fiscal o las negligencias médicas. La identificación de estos datos anómalos o extraños es una labor complicada ya que puede ser provocada por un evento especial o por causa del mismo modelo [18]. 1.3.2 Técnicas Las técnicas presentadas a continuación fueron desarrolladas con el fin de encontrar las soluciones a los problemas descritos anteriormente: •Procesos gaussianos : Esta técnica, la cual será presentada a lo largo de esta memoria, forma la base para entender el algoritmo usado en este trabajo. En un proceso gaussiano, las muestras son generadas a partir de una función media y una función de covarianza y es una técnica usada fundamentalmente en regresión y clasificación. •Algoritmos basados en árbol de decisión : Son técnicas que usan la matemática y la estadística para formar una estructura en forma de árbol que ayuda a la toma de decisiones. Existe un gran número de cuestiones que los desarrolladores de estos algoritmos tienen que responder antes de proceder a usarlos como son: ¿Cuál es el coste computacional de elegir un camino en el árbol u otro?¿Hasta cuando se puede seguir dividiendo los caminos?¿Sobre qué parámetros descansa la decisión final: tiempo de computación, riesgo...? [19]. •Redes neuronales : A pesar de que pueda parecer un término muy actual, la primera red neuronal artificial data del año 1959, la cual estaba basada en un modelo para eliminar los ecos producidos en una comunicación por teléfono [ 20 ]. En la actualidad, es una técnica usada en muchos campos del "día a día" de la sociedad como puede ser la economía o la medicina. Está basado en el funcionamiento del cerebro humano, en el que tanto las neuronas como sus conexiones son emuladas a partir de capas y enlaces, formando diagramas de grafos. La estructura diseñada es el aspecto clave en este tipo de algoritmos [21]. •Algoritmos para la reducción de dimensión : El decremento del número de dimensiones da lugar a una serie de ventajas como pueden ser la reducción del gasto computacional o la reducción de la memoria usada. Algunos algoritmos más complejos dentro de este campo son capaces de encontrar no solo información redundante, sino también aquellas muestras que son especialmente relevante dentro del set de datos [22]. 4Capítulo 1. Introducción •Aprendizaje profundo : Más conocido por su término anglosajón -Deep Learning (DL)-, siempre ha estado muy ligado al ML. Estos algoritmos están basados en las ya mencionadas redes neuronales y son usados actualmente en múltiples campos como puede ser el procesamiento digital de imágenes en medicina, reconocimiento facial... La vida en este siglo no se podría concebir sin la explosión de este fenómeno: El reconocimiento facial de los móviles actuales o el reconocimiento por voz que usan Siri oAlexa están basados en algoritmos de DL [23]. •Support Vector Machine (SVM) : Se trata de una técnica usada ampliamente en clasificación aunque también puede ser usada en regresión. Básicamente esta técnica pretende encontrar un hiper-plano que consiga clasificar las muestras proyectadas en un espacio de dimensión mayor[24]. 1.4 Ubicación y organización del trabajo Una vez se han introducido de una forma muy general todos los campos que de alguna forma rodean a este proyecto, se va a presentar la ubicación del trabajo dentro de estos campos así como la organización y estructura de esta memoria. 1.4.1 Ubicación Como se detallará a lo largo de esta memoria, este trabajo está basado en la estimación de señal recibida a partir de la información proporcionada por sensores, la cual no es especialmente precisa, y es por ello que este trabajo se encuentra principalmente ubicado dentro del campo de la estimación espectral o en inglés Spectral Stimation (SS). Como se ha comentado anteriormente, el incremento de las comunicaciones inalámbricas ha provocado una creciente necesidad en los ingenieros de telecomunicaciones de estimar la utilización del espectro de la manera más exacta posible. Es por ello que este trabajo presenta una técnica para llevar a cabo dicha estimación a partir de sensores de bajo coste. El segundo campo presentado anteriormente en el que se ubica este proyecto es el del machine learning ya que para la estimación de la señal recibida a partir de los sensores, se ha usado una técnica de ML. De entre los múltiples algoritmos presentados, este trabajo se encuentra dentro del primero, el cual se trata de algoritmos de ML para regresión . Mas específicamente, el método usado para la estimación de señal recibida está basado en procesos gausianos, o en inglés, Gaussian orocesses for regression (GPR). Tanto el método de propagación usado, como el desarrollo matemático en el que está basado la estimación de señal a partir de GPR, son presentados a lo largo de esta memoria, cuya organización se presenta a continuación. 1.4.2 Organización del trabajo Se aprovechará este apartado para presentar la estructura en la que está divida esta memoria con el fin de ubicar al lector y hacer más sencilla su lectura. En el próximo capítulo se va a presentar la motivación y objetivo de este trabajo. Una vez finalizado este capítulo se pasará a presentar los fundamentos matemáticos en los que está basado la técnica de GPR. Una vez entendidos los conceptos básicos, se pasará a detallar el artículo en el que está basado este proyecto. Aspectos como el modelo de propagación o los errores y consideraciones que se tienen que tener en cuenta son presentados en este capítulo. Finalizada la presentación de la base matemática, se mostrará los entornos de programación usados, así como las particularidades del código desarrollado. La simulación y análisis de los resultados se presentarán en un capítulo posterior antes de finalizar con las conclusiones y los trabajos futuros. 2 Motivación y objetivos Para mí, nunca ha habido una mayor fuente de honores terrenales o distinción mayor que la conexión con los avances de la ciencia. Isaac Newton Una vez finalizada la introducción de la memoria, se va a presentar en este capítulo tanto las causas que han motivado al autor de esta memoria a llevar a cabo este proyecto así como los objetivos buscados durante la realización del mismo. Se considera importante introducir este capítulo en la memoria final ya que ayuda a entender el por qué de la realización de este trabajo. 2.1 Motivación Esta sección, junto con algunas partes del capítulo de conclusiones, son las dos únicas situaciones en las que voy a dar mi opinión o punto de vista, y es por lo que en ocasiones se puede producir un cambio en los tiempos verbales de la redacción, los cuales pueden pasar a la primera persona del singular. Entrando en contenido, la principal causa que motivó la realización de este proyecto por mi parte reside en el desconocimiento que tenía hasta el momento de la elaboración del mismo, de las técnicas y algoritmos de machine learning que existen en la actualidad. Consideraba, que después de seis años de estudio, había adquirido conocimientos en muchos campos importantes pertenecientes a las telecomunicaciones, pero no había entrado nunca en este amplio sector. Además, la imposibilidad de cursar la única asignatura dedicada exclusivamente al ML en el máster, hizo que contactara con el tutor de este proyecto con el fin de poder realizar un trabajo el cual me acercase al mundo del ML. Por mi parte, era consciente de la importancia que tienen estas técnicas en la actualidad, no sólo en el ámbito de las telecomunicaciones, sino en otros muchos aspectos de la sociedad actual. Es por ello que no quería terminar mi etapa de formación sin tener un acercamiento a este campo, ya que lo considero parte de la formación básica en una titulación de ingeniería de telecomunicaciones. En este punto me gustaría agradecer de nuevo al tutor de este proyecto, Juan José Murillo Fuentes, por brindarme la oportunidad de trabajar en este proyecto y por la ayuda proporcionado durante la realización del mismo. Por otro lado, si se lleva a cabo un análisis de las referencias usadas para la realización del capítulo de introducción, se puede observar como todas ellas están basadas en artículos realizados entre 2017 y 2020 , lo que muestra la gran importancia que tiene el ML en la actualidad. Un estudio llevado a cabo por la prestigiosa revista forbes [ 25 ], muestra de manera práctica y a través de gráficos la importancia que tiene el ML en los distintos ámbitos de la sociedad actual: economía, ingeniería, marketing... En las Figuras 2.1 y 2.2 se muestran dos de los gráficos presentados en dicho estudio donde se aprecia de manera clara la dependencia que ya se tiene en muchos ámbitos de las técnicas de ML. Me gustaría destacar sobre todo la Figura 2.1, en la que se muestra como los algoritmos de ML son especialmente cruciales en las telecomunicaciones actualmente, lo que viene a reforzar mi propuesta de introducir el machine learning en la formación básica de un ingeniero de telecomunicaciones. Soy por tanto consciente de las ventajas competitivas que supone tener conocimientos dentro de este sector y cómo esta formación, aunque sea de manera introductoria, me puede abrir numerosas oportunidades a lo largo de mi carrera profesional. Ésta ha sido por tanto mi mayor motivación. 5 6Capítulo 2. Motivación y objetivos Figura 2.1 Importancia por sector industrial [25]. Figura 2.2 Importancia por función [25]. 2.2 Objetivos 7 2.2 Objetivos A raíz de lo comentado anteriormente, queda claro que el objetivo buscado a la hora de realizar este proyecto es principalmente llevar a cabo un acercamiento a una de las técnicas de ML más usadas en telecomunicaciones. Como también se ha mencionado, la base desde la que se partía era nula, por lo que cualquier aprendizaje que se haya podido llevar a cabo a lo largo de la realización de este proyecto es positivo. Debido principalmente a la falta de background dentro de este campo, la complejidad del trabajo no es especialmente elevada a ojos de un experto en ML, pero para alguien que está empezando su andadura en estas técnicas, supone un reto el cual se revisará si ha sido superado satisfactoriamente o no en el apartado de conclusiones. Dejando a un lado los objetivos a nivel personal, el fin último de este trabajo a nivel técnico se puede resumir en algunas líneas. Este proyecto está basado en un estudio realizado previamente por investigadores de la Universidad de Sevilla [ 34 ] (más adelante en la memoria se dedica un capítulo a presentar dicho estudio), el cual usaba el lenguaje de programación MATLAB para llevar a cabo la implementación de las ecuaciones matemáticas a nivel de simulación. El objetivo planteado por el tutor de este proyecto fue por tanto convertir el código desarrollado a un lenguaje de programación de software libre como puede ser Python, y usar librerías y entornos de libre acceso. Personalmente, y como defensor de los medios que ayudan a compartir los conocimientos software de manera gratuita, me pareció una gran idea. Las particularidades del código desarrollado serán presentadas en algún capítulo posterior en esta memoria, así como la introducción a las librerías que han sido utilizadas y que incluyen los algoritmos de GPR. Además, es bien sabido que actualmente el lenguaje de programación Python se encuentra en la lista de los más usados en mucho de los campos principales de la ingeniería, pero específicamente se trata de un lenguaje muy usado en aplicaciones de ML. Por tanto, no se concibe un aprendizaje sobre ML sin la adquisición al mismo tiempo de los conceptos de Python aplicados a ML. Por último, se propone como mejora al estudio original la utilización de técnicas para reducir la complejidad y el tiempo de ejecución de las simulaciones. 2.2.1 Problema a resolver Ya con los objetivos del trabajo bien definidos cabe preguntarse, ¿en qué consiste ese estudio realizado previamente?, el código convertido a Python, ¿qué tipo de acciones realiza?. Básicamente, y como ya se ha comentado de pasada en un capítulo anterior, en este trabajo se pretender realizar una estimación de campo recibido en distintos puntos o nodos de un cierto grid, a partir de la información proporcionada por sensores de bajo coste. Estos sensores pueden ser terminales de usuario u otro tipo de dispositivo electrónico que requiera de comunicación inalámbrica. Además, tanto la posición del transmisor como de los sensores es desconocida, esto es, será necesario llevar a cabo un proceso previo en el que se estimen estas posiciones. Las ecuaciones matemáticas deducidas para llevar a cabo la estimación del campo recibido usando un proceso gaussiano para regresión (GPR) son presentadas a lo largo de esta memoria, así como su implementación a nivel de código y las simulaciones y resultados obtenidos. 14 Capítulo 3. Procesos Gaussianos para Regresión La función a aprender en este ejemplo es un seno, por tanto se va a generar algunas muestras de entrenamiento con el fin de forzar a la salida de las funciones a pasar por estas muestras. Únicamente implementando en el código las fórmulas especificadas en esta sección, especialmente las Ecuaciones (3.21) y (3.22) , se obtienen unos resultados que se muestran en la Figura 3.2 donde se incluyen tres posibles salidas o predicciones. De esta forma, en dicha imagen se aprecia de manera clara como las tres funciones obtenidas a posteriori (amarillo, azul y verden) pasan por las muestras de entrenamiento (marcadas como un cuadrado azul) obtenidas a partir de la función original (negro a rayas) incrementando la precisión de la estimación en esos puntos, y en los cercanos a estos. En los intervalos intermedios, donde no hay muestras de entrenamiento, el algoritmo no sabe cómo proceder por lo que la salida es directamente la función a priori. Un aspecto interesante se aprecia en la media de la predicción (roja a rayas), la cual es cero en los tramos donde no hay muestras de entrenamiento ya que se especificó en las consideraciones a priori (Ecuación (3.24) ) que la información sobre la media era nula. −15 −10 −5 0 5 10 15 −3 −2 −1 0 1 2 3 Tres muestras obtenidas a partir de la probabilidad a posteriori Figura 3.2 Obtención de muestras para función a posteriori (Ecuación (3.22)). 3.3 Consideraciones adicionales sobre GPR Todo lo comentado a lo largo de la secciones anteriores corresponde únicamente con una breve introducción acerca de los procesos gaussianos aplicados a la regresión. Se podría invertir un tiempo mucho mayor en presentar más detalles desde el punto de vista matemático o estadístico, pero se considera que está fuera de los límites correspondientes al alcance de este trabajo. Sin embargo, algunas consideraciones especiales sobre GPR se detallan a lo largo de esta sección, ya que se trata de conceptos que son convenientes de estudiar debido a su aparición en el desarrollo de este proyecto. 3.3.1 Muestras con ruido En una situación real, las muestras de entrenamiento no son salidas de una función objetivo como tal, sino que se encuentran influenciadas por un ruido que modifica su valor original. Con el fin de mostrar el caso más simple, se considera un ruido gaussiano cuyas muestras son independientes e idénticamente distribuidas. Por tanto, la probabilidad a priori de las muestras viene marcada por una covarianza: cov(yp,yq) = k(xp,xq)+ σ2δpq (3.25) Teniendo en cuenta que δpq es una delta de Kronecker, el ruido en las muestras provoca la aparición de una matriz diagonal la cual modela este ruido. Por tanto, la función densidad de probabilidad conjunta quedaría como sigue: f f∗∼N0,K(X,X)+σ2I K(X,X∗) K(X∗,X)K(X∗,X∗) (3.26) 3.3 Consideraciones adicionales sobre GPR 15 Procediendo de igual forma que para el caso de las muestras sin ruido, la función densidad de probabilidad condicionada obtenida a partir de la conjunta sería: f∗|X∗,X,f∼N(µ∗,Σ∗)(3.27) donde: µ∗=K(X∗,X)[K(X,X)+σ2I]−1f(3.28) Σ∗=K(X∗,X∗)−K(X∗,X)[K(X,X)+σ2I]−1K(X,X∗)(3.29) Aunque parece un cálculo muy sencillo, tiene numerosas implicaciones que pueden verse en [ 29 ]. De una manera práctica, y con el fin de modelar las muestras con ruido, únicamente hay que añadir la potencia, σ2 , de ruido a la predicción de la varianza. 3.3.2 Hiperparametrización Si se analiza de manera exhaustiva el código 3.1 (lo cual no es un trabajo muy exigente debido a la simplicidad del mismo), se puede observar como uno de los argumentos que aparecen en la llamada a la función kernel en la línea 2 no ha sido estudiado. Se trata del argumento param y no es más que uno de los hiperparámetros del kernel. El kernel de un proceso gaussiano puede verse como un parámetros fijo, pero también como una función variable cuyos hiperparámetros ayudan a encontrar el mejor kernel de acuerdo a las muestras o escenario en el que se aplique. En el ejemplo más básico del kernel RBF, la Ecuación (3.23) una vez se han añadido los hiperparámetros queda como sigue: k(x,x0) = σ2 fexp(−1 2l2|x−x0|2)(3.30) Se observa, que tanto σf y l son considerados como hiperparámetros además del propio ruido, σ , que puede ser tomando igualmente como hiperparámetro. Se verá en el capítulo correspondiente como estos hiperparámetros serán optimizados con el fin de encontrar el kernel que mejor funcione en este proyecto basándose en la información proporcionada por las muestras. La discusión en torno a la elección del kernel es uno de los aspectos fundamentales cuando se trabaja con procesos gaussianos y es por ello que la decisión final deberá estar justificada. En uno de los capítulos posteriores se nombrará algunas características adicionales sobre los hiperparámetros y especialmente se considerará el parámetro l el cual recibe el nombre de factor de escala o lengthscale. 3.3.3 Media distinto de cero Hasta ahora y por simplicidad en el desarrollo matemático se ha considerado que la función media del proceso gaussiano es cero. Teniendo en cuenta que esta suposición no concuerda con el modelo estudiado en este proyecto (el cual será presentado en un capítulo posterior) será necesario aclarar los conceptos adicionales que aparecen cuando se trabaja con un proceso gaussiano de media distinta de cero. Teniendo en cuenta una función media distinta de cero, la densidad de probabilidad conjunta queda de la siguiente forma: f f∗∼Nm(X) m(ˆ X),K(X,X)+σ2I K(X,X∗) K(X∗,X)K(X∗,X∗) (3.31) De igual forma que para el caso anterior se puede desarrollar dicha probabilidad conjunta y alcanzar una función densidad de probabilidad condicionada, la cual es una distribución gaussiana cuya media es en este caso: ¯ f∗=m(ˆ X)+K(ˆ X,X)(K(X,X)+σ2)−1(f−m(X)) (3.32) Teniendo en cuenta que el término m(X) se desconoce, será necesario estimarlo a partir de los datos. Se parte por tanto de la siguiente expresión: f(x) = g(x)+h(x)Tβ+σ2I(3.33) 16 Capítulo 3. Procesos Gaussianos para Regresión Donde g(x) es un proceso gaussiano de media cero como cualquiera de los vistos a lo largo de este capítulo, h(x) es un conjunto fijo de bases y β son parámetros adicionales. Esta visión hace que β se optimice a la misma vez que los hiperparámetros del kernel [ 28 ]. Otra posible opción se aprecia en [ 29 ], donde β∼N(b,B), obteniéndose de esta forma un nuevo proceso gaussiano: f(x)∼GP(h(x)Tb,k(x,x0)+h(x)TBh(x0)) (3.34) Al igual que para el resto de procesos gaussianos vistos en este capítulo, se puede difinir una función densidad de probabilidad conjunta la cual da lugar a una probabilidad condicionada con una media y una matriz de covarianza. Se puede acceder a la referencias para ver los resultados finales así como el desarrollo matemático, los cuales no son plasmados en esta memoria ya que se considera que están fuera del alcance de este trabajo. Lo más importante a destacar en este punto es que se genera un nuevo proceso gaussiano el cual se puede expresar a partir de la media y covarianza de un proceso gaussiano de media cero, a los que se suma una serie de términos que aparecen cuando se supone que la media del proceso gaussiano es distinta de cero. En un caso práctico, la media del proceso gaussiano es cero cuando no hay ningún conocimiento a priori, pero distinta de cero cuando se conoce algo sobre la media. Por ejemplo, si se sabe a priori que la media es una recta con una pendiente determinada, se incluiría esta información como media del GPR dejando el valor final de la pendiente como hiperparámetro. 3.3.4 Estimación Recursiva En muchas aplicaciones, y al igual que ocurre en este proyecto, podría darse el caso en el que el escenario no fuera fijo, y por tanto, variase a lo largo del tiempo, siendo necesario calcular una nueva función densidad de probabilidad condicionada cada vez que se recibe una nueva muestra. Para afrontar este punto y los que vienen a partir de ahora, será necesario hacer un cambio de mentalidad, y ver las fórmulas de media y matriz de covarianza obtenidas en la Ecuación (3.27) a nivel de muestra. Para ello se va a realizar el siguiente cambio de notación: K(X,X)+σ2 nI≡Cn=Kn+σ2 nIn µ∗≡µn=KnC−1 nyn Σ∗≡Σn=Kn−KnC−1 nKn (3.35) Además, a partir de ahora se tendrá en cuenta un modelo para la ecuación de regresión con la siguiente notación: y=f(x)+σ . Las muestras de entrenamiento serían por tanto cada yn mientras que las muestras de test serán cada xn. De esta manera, cada vez que se recibe una nueva muestra de entrenamiento yn+1 y una nueva muestra de test xn+1, los valores de media y matriz de covarianza se pueden actualizar como sigue [26]: µn+1=µn µf(xn+1)−µf(xn+1)−yn+1 σ2 yn+1hn+1 σ2 f(xn+1)(3.36) Σn+1=Σnhn+1 hT n+1σf(xn+1)−1 σ2 yn+1hn+1 σ2 f(xn+1)hhT n+1σ2 f(xn+1)i(3.37) Donde hn+1=ΣnK−1 nkn+1. Por tanto, y a diferencia de lo que se pudiera pensar en primera instancia, no es necesario calcular en cada iteración una nueva función densidad de probabilidad, sino que únicamente habrá que actualizar los valores de media y matriz de covarianza, reduciendo de manera muy considerable la carga computacional. Además, no es necesario almacenar las dos matrices sino que únicamente bastará con actualizar una de ellas y calcular la otra a partir de la primera. 3.3.5 Factor de olvido o Forgetting factor Se trata de un concepto muy importante cuando las muestras varían con el tiempo y por tanto se tiene que dar una mayor importancia a las muestras recientes. De esta manera, y gracias a este parámetro, se consigue 3.4 Sparse GP. Una mejora del tiempo de ejecución 17 olvidar la información contenida en las muestras más antiguas. Para ello, y después de actualizar las matrices en cada iteración, se realiza el siguiente paso: µ←√λ µ Σ←λΣ+(1−λ)Σ(3.38) El factor de olvido λ puede tomar valores comprendidos entre cero y uno ( 0<λ≤1 ), no teniendo ningún efecto cuando vale uno ya que como se aprecia en la Ecuación (3.38) , los nuevos valores de media y matriz de covarianza se estarían calculando a partir de la muestra actual. Por tanto, valores cercanos a uno darán más importancia a las muestras actuales que a las antiguas, mientras que conforme el valor se acerca más a cero, esta importancia va decayendo. De esta manera se lleva a cabo una predicción en la cual se tiene en cuenta tanto la muestra actual como las pasadas, pero cuya importancia en la predicción está ponderada por un parámetros λ. Para una mayor información se puede acceder a la bibliografía y especialmente a [ 26 ] donde se demuestra como este paso en realidad no es visto como un paso adicional en la predicción sino como parte de un procedimiento más completo en el que el kernel tiene una visión espacio-temporal. 3.4 Sparse GP. Una mejora del tiempo de ejecución Una desventaja común a todas las técnicas basadas en ML está relacionada con los tiempos de ejecución de los algoritmos implementados. En la mayoría de los escenarios de aplicación de estos algoritmos, los tiempos de ejecución rondan valores bastantes altos siendo estos en algunos casos del orden de días o semanas, incluso después de hacer uso del kernel trick. En este proyecto, esta desventaja aparece también ya que, al no ser Python un lenguaje de programación orientado a matrices, los tiempos de computación se disparan. Por tanto, se trató de encontrar una alternativa que redujera el tiempo de ejecución siendo además la pérdida de precisión mínima. Con el fin de encontrar este comportamiento es habitual usar la técnica del sparse GP [31] la cual es explicada a continuación. 3.4.1 Explicación básica La idea detrás de este decremento en el tiempo de ejecución está relacionada con una reducción en el número de muestras usadas en el kernel para estimar una nueva salida. Es trivial pensar que, un menor número de muestras implica una reducción en el tiempo de ejecución total y más cuando este ronda las 24 horas como ocurre en este trabajo. La base teórica de esta técnica se considera que se encuentra fuera del alcance de este trabajo, pero se puede acceder a la bibliografía en el caso de querer profundizar en este tema [ 32 ], [ 33 ]. Básicamente, este subconjunto de muestras usadas para la estimación no son exactamente parte de las muestras de entrenamiento, sino que se parte del conjunto total de muestras, las cuales son tratadas con el fin de obtener un subconjunto de muestras que reúnan la información acerca del conjunto total de muestras. De esta manera, se puede tener teóricamente la misma información pero en un número menor de muestras, por lo que las operaciones matriciales necesitarán de menos tiempo de computación, reduciendo por tanto el tiempo total empleado para llevar a cabo la estimación. En la práctica, se verá como este subconjunto de muestras realmente no tienen la información completa, obteniendo resultados menos precisos. 4 Presentación del Escenario En cuestiones de ciencia, la autoridad de miles no vale más que el humilde razonamiento de un único individuo. Galileo Galilei En el capítulo anterior se pudo desarrollar de una manera matemática y estadística los detalles a cerca del algoritmo de ML que se va a aplicar en este proyecto. Por tanto, y una vez presentada la base teórica del algoritmo, en este capítulo se va a introducir el escenario en el que se va a aplicar el mencionado algoritmo. Se van a dar detalles sobre el modelo de propagación usado, así como las características principales del algoritmo dentro de este escenario. Es muy importante destacar que este capítulo está basado en el artículo en el cual descansa los aspectos fundamentales de este proyecto [ 34 ]. Como ya se comentó en el capítulo de introducción y en el de objetivos, mi aportación al estado del arte es simplemente convertir el código que fue desarrollado para elaborar dicho artículo a un lenguaje de programación de software libre. Por tanto, el lector debe acceder a este capítulo considerando que lo expuesto en él procede de investigaciones llevadas a cabo por personal ajeno al autor de esta memoria. Por otro lado, se considera importante apartar este espacio para hacer un inciso en la notación, la cual puede llegar a ser una fuente de incertidumbre en este capítulo. A diferencia de la notación usada en [ 34 ], para indicar la dependencia temporal de los datos no va a usarse un superíndice sino que va a indicarse como se hace habitualmente. Esto es, si la variable x depende del tiempo, aparecerá en las ecuaciones como x(t) . Por otro lado, cuando se vaya a tratar con las ecuaciones que modelan el algoritmo para la regresión de las muestras (GPR), se va a usar la notación a nivel de muestra como se hizo a partir de la Sección 3.3.4. Finalmente, este capítulo cuenta con tres partes bien diferenciadas: (1) Una primera donde se presenta el modelo, (2) una segunda parte donde se estudia la estimación de los parámetros que se desconocen dentro de ese modelo, y (3) por último una sección donde se presenta la aplicación del algoritmo de ML dentro de este escenario. 4.1 Escenario de aplicación de GPR Como ya se comentó en el capítulo de introducción y en el de objetivos, este proyecto está basado en la estimación recursiva de campo recibido a partir de la información proporcionada por una serie de sensores de bajo coste los cuales se encuentran repartidos por una cierta zona espacial. La grandes preguntas que surge en este momento, y que animan a la realización de esta sección es: ¿en qué consiste esa información proporcionada por las medidas de los sensores?¿cómo podemos modelar esas medidas?¿es necesario estimar algún parámetro dentro de ese modelo? Todas esas preguntas serán respondidas a lo largo de este capítulo. Antes de nada, se considera necesario mostrar un pequeño gráfico en el que se representa el problema a solucionar en este trabajo. Por tanto, en la Figura 4.1 se muestra de manera gráfica la distribución de los nodos y sensores con el fin de clarificar el escenario base. Se parte de un espacio de 500 ×500 m en el que se encuentran un total de M (1088) nodos distribuidos uniformemente en una rejilla, y en cuyas posiciones se tratará de estimar la señal recibida. Con el fin de llevar a cabo la estimación de la forma más exacta posible, se va a usar como muestras de entrenamiento 19 20 Capítulo 4. Presentación del Escenario −200 −100 0 100 200 Eje x (m) −200 −100 0 100 200 Eje y (m) Nodos Transmisor Sensores −100 −90 −80 −70 −60 −50 RSS [dBm] Figura 4.1 Escenario de aplicación del algoritmo. la información de señal recibida proporcionada por un total de N (218) sensores distribuidos de manera aleatoria a lo largo del espacio de aplicación. En la Figura 4.1 se aprecia además como el triángulo representa al transmisor, el cual está situado en el centro del grid pero cuya localización se desconoce, los cuadrados corresponden a las posiciones de los nodos en las que se pretende estimar la señal recibida, y los círculos de colores representan a los sensores distribuidos aleatoriamente cuyas posiciones se conoce pero de forma aproximada. Se puede apreciar como el color de los sensores depende de la intensidad de señal recibida en su posición, siendo los sensores coloreados con tonos más claros aquellos que se encuentran más cerca del transmisor y en los cuales se recibe un valor más alto de intensidad de señal, mientras que los sensores con tonos más oscuros se encuentran más alejados del transmisor siendo la señal recibida en estos más débil. A continuación, y una vez se tiene una idea general del problema, se va discutir acerca del desarrollo matemático presente en este escenario. Se partirá del modelo más simple en el que no existe ningún tipo de error en la posición de los sensores, para posteriormente ir añadiendo más complejidad al modelo base con el fin de modelar por completo el escenario en el que se encuentra este trabajo. Estos sensores comparten información acerca del campo recibido en ciertos puntos del espacio y por tanto, esa información sigue un modelo de propagación el cual está basado en un modelo de pérdidas por camino (log-normal path loss model). Este tipo de modelos dependen de numerosos parámetros entre los que se encuentran la localización de los sensores, el exponente de pérdidas por camino, la potencia transmitida y la localización de los puntos muertos (shadowing). La elección de este modelo está basada en la suposición de que tanto la posición del transmisor como la de los sensores, así como los efectos de shadowing, afectan al modelo de propagación. De esta manera, y a partir de la aplicación del modelo ya mencionado, el campo recibido en su manera más simple puede expresarse como sigue: z(t) = 1P(t)−10α(t)log10(d(t))+v(t)+ w(t)(4.1) En la Tabla 4.1, se muestra el significado de cada uno de los parámetros del modelo de manera resumida. Conviene destacar algunos aspectos importantes que han sido mencionados en la Tabla 4.1 antes de añadir una mayor complejidad al modelo. En primer lugar, para el cálculo de la distancia se ha usado la siguiente fórmula: di j(t) = q(xi(t)−xj(t))T(xi(t)−xj(t)) (4.2) En la que los términos xi j corresponde a la posición de los N sensores que proporcionan la información necesaria, así como de los M puntos del espacio en los que se quiere calcular el campo recibido. Estas posiciones están plasmadas en un plano XY como se verá más adelante en este documento, por lo que únicamente cuenta con dos valores (uno para la posición respecto al eje x y otro para la posición respecto al eje y). 4.1 Escenario de aplicación de GPR 21 Tabla 4.1 Definción de parámetros de Ecuación (4.1). Parámetro Definición z(t) [dBm] Medida de campo recibido en cada uno de los sensores. P(t) [dBm] Se trata de la potencia isotrópica radiada equivalente (PIRE) del transmisor el cual se encuenta en la posición x0. Tanto la posición como la potencia transmitida son dos de los parámetros que será necesario estimar. α(t)Es el exponente de pérdidas por camino en el instante ty tiene un valor que necesita ser estimado. d(t) [m] Se trata de la distancia entre los sensores y el transmisor. También puede aparecer el parámetro dgen el que se indica la distancia entre el transmisor y los puntos en los que se quiere calcular el campo recibido. v(t) Este parámetro modela la atenuación debido al efecto del shadowing y se trata de una distribución Gaussiana de media cero y matriz de covarianza: Σv. w(t) Parámetro que añade un ruido de tipo Gaussiano a las muestras de campo recibida y sigue una distribución Gaussiana de media cero y matriz de covarianza: σ2 wIN. Por otro lado, cada término de la matriz de covarianza Σv que forma parte del modelado de la atenuación por efectos de shadowing se calcula como sigue: Cov(vi(t)vj(t)) = σ2 vexpdi j(t) Dcorr (4.3) Donde el término Dcorr modela la correlación entre las muestras, y cuyo valor será especificado más adelante. Por último, y en relación al término de ruido añadido w(t) , comentar que la matriz diagonal de covarianza tiene como valores el parámetros σw , el cual tiene un valor de σw=√7 (obtenido a partir de las referencias). 4.1.1 Imprecisión en la posición de los sensores El anterior modelo está basado en una suposición en la que la posición de los sensores es perfectamente conocida. Esto podría darse en algunos escenarios de aplicación en el que los sensores son fijos y proporcionan medidas muy precisas. En cambio, en este proyecto se realiza una estimación a partir de un número muy elevado de medidas, cuya precisión es muy baja, las cuales son proporcionadas por sensores de bajo coste como pueden ser smartphones, cuya posición no sólo no es conocida de forma precisa sino que además puede variar a lo largo del tiempo (crowdsourcing). Es por ello necesario añadir al modelo original (Ecuación (4.1) ) esta incertidumbre en la posición de los sensores con el fin de modelar el campo recibido de la manera más precisa posible. Para indicar que la posición no es completamente conocida se usará la siguiente notación: ˆ X(t) = [ˆx1(t),ˆx2(t)...ˆxN(t)] . De esta manera, la distancia respecto al transmisor tendrá también un valor poco preciso y será por tanto expresada de la siguiente forma: ˆ d(t) = [ ˆ d1(t),ˆ d2(t)... ˆ dN(t)]. Esta imprecisión en la posición de sensores se puede modelar a partir de la siguiente ecuación: ˆ di(t) = di(t)+εd(4.4) Se puede apreciar como a la distancia original se añade un término de ruido el cual sigue una distribución Gaussiana de media cero y varianza σ2 d . Este valor de varianza es conocido ( σd=13.16 m), por lo que se llega de manera sencilla a la siguiente expresión: ˆ di(t)∼N(di(t),σd)(4.5) Este modelado de posición de los sensores que refleja la incertidumbre de su localización hace que el modelo de la Ecuación (4.1) evolucione hacia un escenario más realista: z(t) = 1P(t)−10α(t)log10(ˆ d(t))+ u(t)+ v(t) +w(t)(4.6) En el que se puede observar la aparición de un término nuevo: u(t) . Este parámetro refleja dicha imprecisión y tiene la siguiente expresión: u(t)∼N0,ρ2 u(t)ˆ D(t)(4.7) 22 Capítulo 4. Presentación del Escenario La procedencia del parámetro ρ2 u(t) [mdB] puede verse detallada en el apéndice de [ 34 ], donde además se demuestra de igual forma la aparición del término u(t) en la Ecuación (4.6) . Los dos parámetros con los que se calcula la matriz de covarianza en la Ecuación (4.7) tienen las siguientes expresiones: ρ2 u(t) = 10α(t)σdlog10(e) = 200 (4.8) ˆ D(t) = diag(1/ˆ d2 1(t),1/ˆ d2 2(t)...1/ˆ d2 N(t)) (4.9) 4.1.2 Ejemplo con imprecisión en la posición Una vez se ha avanzado en la formulación matemática del modelo incluyendo la imprecisión en la posición de los sensores, en esta sección se va a presentar un ejemplo gráfico donde se muestra la importancia de añadir este término de imprecisión en el modelo original. Para ello, se va a realizar una simulación acotada, en la que los parámetros son perfectamente conocidos y las fórmulas son más simples que el modelo de propagación propuesto en la Ecuación (4.6) . Por tanto, se va a realizar un estudio que relaciona disminución de la potencia con la distancia. La ecuación base de este estudio es la siguiente: E(zi) = P−10αlog10 di(4.10) En la que los valores de αyPson, respectivamente 3.5 y 0 dBm. Esta gráfica incluirá distintas curvas correspondientes a situaciones en las que (1) la distancia es perfectamente conocida (roja), (2) la distancia tiene un error de 10 metros (azul) y (3) el error en la distancia está condicionado al valor de ρu (negra a rayas), el cual es de 200 mdB como ya se comentó anteriormente. Estas curvas se muestran en la Figura 4.2. 50 100 150 200 di (m) −90 −80 −70 −60 −50 −40 −30 −20 −10 E ( zi ) [dBm] P −10 α log10( di ) P −10 α log10(  di ) P −10 α log10(  di )± ρu /  di Figura 4.2 Nivel de potencia respecto a la distancia. La principal conclusión obtenida a partir del análisis de la Figura 4.2 es la siguiente: conforme más cerca se encuentran los sensores de la posición del transmisor, mayor será el efecto del error de posición de los sensores. Para demostrar esta conclusión de manera empírica y no visual se muestra la Figura 4.3 donde se ha representado el porcentaje de error en el cálculo de la potencia debido al error de posición de los sensores. En dicha gráfica se aprecia de manera más que clara como el porcentaje de error es muy elevado en distancias cercanas al transmisor respecto a distancias más alejadas. A partir de una distancia en torno a 50 metros el porcentaje de error es prácticamente nulo por lo que el efecto de la imprecisión en la posición empieza a ser despreciable. Por tanto, habrá que tener muy en cuenta estas consideraciones a la hora de estudiar la información proporcionada por sensores que se encuentre en torno al transmisor en distancias muy cercanas. 4.2 Estimación de parámetros del modelo 23 50 100 150 200 di (m) 0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00 Error de P [%] Figura 4.3 Porcentaje de error en la potencia. 4.2 Estimación de parámetros del modelo Como se ha comentado en el estudio de las Ecuaciones (4.1) y (4.6) y la Tabla 4.1, existen una serie de parámetros que han de ser estimados con el fin de modelar el campo recibido en los sensores de manera correcta. Estos parámetros son: la posición del transmisor, el exponente de pérdidas por camino y la potencia isotrópica radiada equivalente (PIRE) recibida en los sensores. Por tanto se dedicará un espacio en esta memoria al estudio de la estimación de estos parámetros. 4.2.1 Posición del transmisor Se comenzará presentando el estudio acerca de la estimación de la posición del transmisor. Para ello, se ha usado un algoritmo de localización basado en la fuerza del campo recibido (RSS), el cual es ampliamente usado en localización para aplicaciones inalámbricas. Cabe destacar que, por lo general, los algoritmos de localización basados en medidas de RSS son bastante imprecisos y por tanto, el error en la posición estimada es bastante elevado. Esto es debido principalmente a las situaciones a la que se enfrenta normalmente cualquier sistema de comunicaciones inalámbricas, como puede ser la degradación por efectos de shadowing o las los desvanecimientos de señal. Estas circunstancias hacen que el algoritmo de localización proporcione resultados muy poco precisos y variantes con el tiempo en función de las características de la señal recibida [ 35 ]. Aún así, y como se ha comentado anteriormente, son algoritmos ampliamente usados debido a su bajo coste y complejidad [36]. Es por ello que para la localización del transmisor se propone un algoritmo en el que se añaden unos pesos a la medidas proporcionadas por los sensores y, de esta manera, y como se podrá comprobar a partir de las fórmulas, se dará una mayor importancia a la información proporcionada por sensores con mayor RSS. Este algoritmo recibe el nombre de weighted centroid approach [37]. Adicionalmente, en este trabajo se ha añadido una variante al algoritmo de localización añadiendo una dependencia temporal a las muestras para, de esta forma, incluir la información proporcionada por muestras anteriores en el cálculo de la posición actual. En relación a la notación, y al ser un parámetro estimado, la posición del transmisor cambiará su representación a: ˆx0 . Por tanto, la distancia entre los sensores y el transmisor, la cual es necesaria de calcular como se aprecia en la Ecuación (4.6), se estudiará a partir de la siguiente expresión: ˆ di(t) = |ˆ xi(t)−ˆ x0(t)|(4.11) 5 Python e implementación de GPR La ciencia es el padre del conocimiento, pero las opiniones son las que engendran la ignorancia. Hipócrates Una vez se han presentado las ecuaciones matemáticas deducidas para este proyecto con el fin de estimar el campo recibido a partir de la técnica de GPR, el siguiente paso en la memoria sería la explicación e introducción del código desarrollado en este proyecto. Pero antes de presentar el código en el capítulo siguiente, se va a hacer uso de este capítulo para presentar tanto el entorno de programación usado, así como las librerías que han sido utilizadas a lo largo del código. La principal finalidad de este capítulo reside en proporcionar al lector una idea general del entorno de programación usado con el fin de facilitar el entendimiento del código que va a ser presentado en un capítulo posterior. Este código utiliza numerosas librerías que, de no haber sido presentadas con anterioridad, podrían ser fuente de malentendidos. Este capítulo tiene dos secciones: (1) una primera donde se presentan las librerías usadas a lo largo del código, mostrando especial interés en aquellas con una mayor relevancia en el proyecto y (2) una segunda sección donde se introduce el entorno virtual creado. 5.1 Librerías usadas La elección de librerías es uno de los aspectos más importantes cuando se trabaja con cualquier lenguaje de programación, adquiriendo una importancia aún mayor en aquellos que son de código abierto como Python. Por tanto, en este apartado se van a listar las librerías usadas en este proyecto, realizando además una breve descripción de ellas con el fin de justificar su presencia en este trabajo. Dicha lista se muestra a continuación: •numpy : Es la librerías más usada e imprescindible dentro de este proyecto ya que da soporte para vectores y matrices, haciendo que el uso de estos sea más cómodo. Es una librería que consigue igualar de alguna manera las facilidades de MATLAB en cuanto a la utilización de vectores y matrices, convirtiéndose de este modo en la librería más usada a lo largo de este proyecto. Tanto las operaciones matriciales como la inicialización y uso de vectores se llevan a cabo de manera muy simple gracias a esta librería [43]. •matplotlib : Esta librería es usada principalmente para la representación de gráficos a partir de datos contenidos en vectores, por lo que soporte el formato de matrices y vectores de numpy. Su uso es bastante similar a MATLAB lo que hace que la representación sea llevada a cabo de manera muy simple, y su aparición en el código está centrada en la Clase graficas [44]. •scipy : Se trata de otra librería ampliamente usada ya que también soporta el formato de vectores y matrices de numpy. Es una librería la cual tiene implementados en su código fuente numerosos algoritmos para optimización, así como módulos para álgebra lineal, procesamiento de imagen... Dentro de este proyecto, su uso se reduce a la utilización de los algoritmos de minimización necesarios para llevar a cabo la estimación de los parámetros α y P. La función lsq_linear que aparece en la línea 6 del Código 6.3 es un ejemplo de método implementado en esta librería y aplicado en este proyecto [45]. 31 32 Capítulo 5. Python e implementación de GPR 5.1.1 Librería GPy [ 46 ] Debido a su importancia dentro de este proyecto se va a dedicar un apartado exclusivamente a esta librería. El aprendizaje en torno al uso de librerías que implementen algoritmos de ML es uno de los objetivos principales de este proyecto. Tras el uso del algoritmo de GPR de esta librería, el autor de este proyecto se encuentra en disposición de usar otros algoritmos dentro de la misma, así como directamente otras librerías que incluyan algoritmos de GP. Por tanto, el correcto uso de esta librería está relacionado directamente con el cumplimiento de uno de los objetivos de este trabajo. Aunque su uso ya apareció en algunos de los códigos de la sección anterior, en este apartado se va mostrar de manera muy breve su utilización en un ejemplo muy simple [ 47 ]. Se va a tratar de estimar las salidas correspondientes a una función sencilla ( y=0.25x2 ), añadiendo además ruido a las muestras de entrenamiento. De igual forma, se va a analizar el efecto del parámetro de escala o lengthscale. El ejemplo se reduce a las líneas del Código 5.1. Código 5.1 Código básico de ejemplo de GPy. 1 # Creación del kernel 2 kernel = GPy.kern.RBF(input_dim=1, lengthscale=.5) 3 # Creación del modelo a partir de los datos de entrenamiento 4 m = GPy.models.GPRegression(X,Y,kernel) 5 # Representación para lengthscale=1 6 print (m) 7 m.plot() 8 9 # Optimización 10 m.optimize() 11 # Optimización para lengthscale óptimo 12 print (m) 13 m.plot() Para la primera simulación se va a usar un valor de factor de escala igual a 0.5. Es bien sabido en estos casos que conforme menor es el factor de escala, menor es también la suavidad a la hora de ajustar las muestras, como se puede apreciar en la comparación entre las Figuras 5.1 y 5.2. Un valor muy pequeño de factor de escala hará que los cambios en la función que ajusta las muestras sean muy bruscos obteniendo de esta manera una solución poco precisa. La misma situación pero a la inversa se puede apreciar en la gráfica obtenida para un valor de factor de escala muy grande, en la que los cambios en la función son tan suaves que difícilmente se llega a ajustar de manera adecuada a las muestras. En esta situación es cuando cobra una gran importancia la optimización de hiperparámetros, ya que será necesario encontrar el valor de lengthscale que mejor se ajuste a estas muestras. Para ello, únicamente habrá que seguir la línea 10 en la que gracias al método optimize implementado en la librería GPy se consigue obtener unos valores adecuados de factor de escala y de varianza. Este método hace uso de la técnica de máxima verosimilitud para ajuste de hiperparámetros, la cual aparece en [ 29 ]. La aportación de la varianza es similar al del factor de escala pero a la inversa, ya que unos valores mayores harán que la función se ajuste a las muestras de una manera más exacta, y viceversa. En la Figura 5.3 se muestran los resultados para los valores óptimos de factor de escala y varianza, y se puede apreciar de manera clara como la estimación es sustancialmente mejor que en las anteriores figuras. Los valores óptimos obtenidos se muestran en la Tabla 5.1. Tabla 5.1 Valores obtenidos tras optimización de hiperparámetros. Parámetro Valor óptimo Factor de escala 3.344647559 Varianza 28.900546413 5.1 Librerías usadas 33 Figura 5.1 Simulación para factor de escala igual a 0.5. Figura 5.2 Simulación para factor de escala igual a 5. 5.1.2 Mejora de la librería GPy Un aspecto interesante respecto al uso de esta librería dentro de este proyecto está relacionado con la implementación de la función kernel de la Ecuación (4.27) . En la línea 2 del Código 5.1 se aprecia como la función kernel RBF se puede inicializar de manera muy simple usando uno de los métodos de la librería. En cambio, la implementación de los kernels NSE y LOG que aparecen en la Ecuación (4.27) no se podían llevar a cabo usando directamente los métodos de la librería ya que estos no venían implementados. Por tanto, fue necesario iniciar un proceso de ingeniería inversa con el fin de investigar la forma en la que está desarrollado tanto el kernel RBF, así como otros kernels dentro de la librería. No fue un proceso especialmente largo ya que una vez encontrada la manera en la que estaban implementados estos kernels, únicamente fue necesario cambiar las fórmulas correctamente para calcular los resultados de matriz de covarianza a partir de las expresiones adecuadas. Además, y teniendo en cuenta que es necesario llevar a cabo una optimización del modelo, se añadió en el sitio correspondiente, la expresión de la derivada de cada uno de los kernels introducidos a mano, la cual es usada a lo largo del proceso de optimización. 34 Capítulo 5. Python e implementación de GPR Figura 5.3 Simulación para factor de escala óptimo. 5.2 Entorno Virtual Una buena práctica cuando se trabaja con un lenguaje de programación basado en librerías como puede ser Python es la creación de entornos virtuales, en los que se centraliza la instalación de librerías. La principal ventaja de esta práctica está relacionada con el control absoluto de las versiones de las librerías, pudiendo tener distintas versiones de las mismas en distintos proyectos realizados en paralelo. Además, se puede tener acceso en todo momento a las librerías instaladas en el entorno así como conocer su función de manera muy simple usando un software especializado en entornos virtuales [48]. Para este proyecto se ha usado el programa ANACONDA [ 49 ] en el que la instalación de librerías y activación del entorno se lleva a cabo de manera muy simple. Basta con acceder a la consola proporcionada por el programada e instalar las librerías usando el comando conda install library en dicha consola. Una vez instaladas las librerías necesarias para el proyecto, basta con acceder a la pestaña environment y seleccionar el entorno virtual deseado para activarlo como se aprecia en la Figura 5.4. Para este proyecto, el entorno virtual creado recibe el nombre de myenv. Como se aprecia en dicha Figura, existen otros entornos virtuales creados de manera totalmente aislada al de este trabajo, los cuales fueron creados para proyectos personales. Figura 5.4 Selección del entorno virtual deseado. Una de las principales ventajas de usar entornos virtuales está relacionada con la creación de nuevos en 5.2 Entorno Virtual 35 tornos a partir de las versiones de las librerías instaladas en otro entorno. Para ello, se hace uso de un fichero llamado requirements.txt el cual puede ser usado para crear un nuevo entorno virtual a partir del siguiente comando: conda create –name <env> –file <this file>. En este fichero se recogen todas las librerías usadas en un determinado entorno virtual, así como la versión instalada de dicha librería. De esta forma, se puede reproducir perfectamente un entorno virtual nuevo a partir de uno previamente creado. En este proyecto, el fichero requirements.txt donde se indican las librerías usadas así como sus versiones se desglosa en el Código 5.2. Se puede apreciar como el número de librerías que aparecen es considerablemente superior a las tratadas en este capítulo. Esto es debido a que, una librería puede estar soportada por otro librería que está a su vez soportada por otra librería, y así sucesivamente. Por tanto, cuando se instala una librería de cero, se instala a su vez todas las librerías que la soporta. Este es el motivo por el que aparece esta enorme cantidad de librerías. Por último, y para conseguir reproducir con fidelidad el entorno virtual usado para este trabajo, bastará con crear un fichero requirements.txt usando la información que aparece en el Código 5.2, y posteriormente hacer uso del comando presentado con anterioridad. Código 5.2 requirements.txt. 1 absl-py=0.9.0 2 alabaster=0.7.12 3 argh=0.26.2 4 astor=0.8.1 5 astroid=2.4.0 6 atomicwrites=1.3.0 7 attrs=19.3.0 8 autopep8=1.4.4 9 babel=2.8.0 10 backcall=0.1.0 11 bcrypt=3.1.7 12 bleach=3.1.4 13 ca-certificates=2020.1.1 14 cachetools=4.1.0 15 certifi=2020.4.5.1 16 cffi=1.14.0 17 chardet=3.0.4 18 cloudpickle=1.3.0 19 colorama=0.4.3 20 cryptography=2.9.2 21 cycler=0.10.0 22 dataclasses=0.7 23 decorator=4.4.2 24 defusedxml=0.6.0 25 docutils=0.16 26 entrypoints=0.3 27 flake8=3.7.9 28 future=0.18.2 29 gast=0.2.2 30 google-auth=1.14.1 31 google-auth-oauthlib=0.4.1 32 google-pasta=0.2.0 33 gpflow=1.5.1 34 gpy=1.9.9 35 grpcio=1.28.1 36 h5py=2.10.0 37 icu=58.2 38 idna=2.9 39 imagesize=1.2.0 36 Capítulo 5. Python e implementación de GPR 40 importlib-metadata=1.6.0 41 importlib_metadata=1.5.0 42 intervaltree=3.0.2 43 ipykernel=5.1.4 44 ipython=7.13.0 45 ipython_genutils=0.2.0 46 isort=4.3.21 47 jedi=0.15.2 48 jinja2=2.11.2 49 jpeg=9b=hb83a4c4_2 50 jsonschema=3.2.0 51 jupyter_client=6.1.3 52 jupyter_core=4.6.3 53 keras-applications=1.0.8 54 keras-preprocessing=1.1.0 55 keyring=21.1.1 56 kiwisolver=1.2.0 57 lazy-object-proxy=1.4.3 58 libpng=1.6.37 59 libsodium=1.0.16 60 libspatialindex=1.9.3 61 markdown=3.2.1 62 markupsafe=1.1.1 63 matlabengineforpython=R2017b 64 matplotlib=3.2.1 65 mccabe=0.6.1 66 mistune=0.8.4 67 more-itertools=8.2.0 68 multipledispatch=0.6.0 69 nbconvert=5.6.1 70 nbformat=5.0.6 71 numpy=1.18.3 72 numpydoc=0.9.2 73 oauthlib=3.1.0 74 openssl=1.1.1g 75 opt-einsum=3.2.1 76 packaging=20.3 77 pandas=1.0.3 78 pandoc=2.2.3.2=0 79 pandocfilters=1.4.2 80 paramiko=2.7.1 81 paramz=0.9.5 82 parso=0.5.2 83 pathtools=0.1.2 84 pexpect=4.8.0 85 pickleshare=0.7.5 86 pip=20.0.2 87 pluggy=0.13.1 88 prompt-toolkit=3.0.4 89 prompt_toolkit=3.0.4 90 protobuf=3.11.3 91 psutil=5.7.0 92 py=1.8.1 93 pyasn1=0.4.8 94 pyasn1-modules=0.2.8 95 pycodestyle=2.5.0 96 pycparser=2.20 5.2 Entorno Virtual 37 97 pydocstyle=4.0.1 98 pyflakes=2.1.1 99 pygments=2.6.1 100 pylint=2.5.0 101 pynacl=1.3.0 102 pyopenssl=19.1.0 103 pyparsing=2.4.7 104 pyqt=5.9.2 105 pyrsistent=0.16.0 106 pysocks=1.7.1 107 pytest=5.4.1 108 python=3.6.10 109 python-dateutil=2.8.1 110 python-jsonrpc-server=0.3.4 111 python-language-server=0.31.10 112 pytz=2019.3 113 pywin32=227 114 pywin32-ctypes=0.2.0 115 pyyaml=5.3.1 116 pyzmq=18.1.1 117 qdarkstyle=2.8.1 118 qt=5.9.7 119 qtawesome=0.7.0 120 qtconsole=4.7.3 121 qtpy=1.9.0 122 requests=2.23.0 123 requests-oauthlib=1.3.0 124 rope=0.17.0 125 rsa=4.0 126 rtree=0.9.4 127 scipy=1.4.1 128 setuptools=46.1.3 129 sip=4.19.8 130 six=1.14.0 131 snowballstemmer=2.0.0 132 sortedcontainers=2.1.0 133 sphinx=3.0.3 134 sphinxcontrib-applehelp=1.0.2 135 sphinxcontrib-devhelp=1.0.2 136 sphinxcontrib-htmlhelp=1.0.3 137 sphinxcontrib-jsmath=1.0.1 138 sphinxcontrib-qthelp=1.0.3 139 sphinxcontrib-serializinghtml=1.1.4 140 spyder=4.1.3 141 spyder-kernels=1.9.1 142 sqlite=3.31.1 143 tabulate=0.8.7 144 tensorboard=1.14.0 145 tensorflow=1.14.0 146 tensorflow-estimator=1.14.0 147 tensorflow-gpu=2.1.0 148 tensorflow-gpu-estimator=2.1.0 149 tensorflow-probability=0.9.0 150 termcolor=1.1.0 151 testpath=0.4.4 152 toml=0.10.0 153 tornado=6.0.4 38 Capítulo 5. Python e implementación de GPR 154 traitlets=4.3.3 155 typed-ast=1.4.1 156 ujson=1.35 157 urllib3=1.25.9 158 vc=14.1 159 vs2015_runtime=14.16.27012 160 watchdog=0.10.2 161 wcwidth=0.1.9 162 webencodings=0.5.1 163 werkzeug=1.0.1 164 wheel=0.34.2 165 win_inet_pton=1.1.0 166 wincertstore=0.2 167 wrapt=1.12.1 168 yaml=0.1.7 169 yapf=0.28.0 170 zeromq=4.3.1 171 zipp=3.1.0 172 zlib=1.2.11 6 Código desarrollado El aspecto más triste de la vida en este preciso momento es que la ciencia reúne el conocimiento más rápido de lo que la sociedad reúne la sabiduría. Isaac Asimov Una vez finalizado todo el análisis matemático en torno a este proyecto, tanto en este capítulo como en los siguientes se va a dejar de lado las demostraciones teóricas correspondientes al escenario, modelo o algoritmo, para estudiar el código desarrollado en este proyecto. Este código representa el principal esfuerzo invertido a lo largo de la realización de este trabajo, por lo que será necesario mostrar las consideraciones principales y los detalles más importantes con el fin de justificar el tiempo invertido en este apartado. Es importante mencionar que uno de los objetivos, a parte de conseguir entender toda la matemática detrás de este proyecto, consistía en trasladar el código realizado originalmente en MATLAB a otro tipo de lenguaje más propio del ML y que, además fuera de código abierto como Python. Por tanto, se trata igualmente de un capítulo con una alta relevancia dentro de esta memoria. Es necesario realizar una serie de comentarios antes de entrar en detalle en el código ya que ayudan a entender la estructuración del código: • El código está dividido en clases en las cuales se agrupan un porcentaje bastante alto del código completo. Se irá estudiando la estructuración y contenido de cada clase de manera individual. • Un fichero principal orquestará las llamadas a cada una de las clases. Es importante en este punto tener en cuenta los argumentos de entrada y salida de cada uno de los métodos de cada clase. Se reservará también un espacio dentro de este punto para estudiar el algoritmo de programación desarrollado para orquestar el uso de las clases. • Los resultados y las gráficas obtenidas gracias a este código serán comentadas en un capitulo posterior. 6.1 Presentación de las clases Aunque estos apartados podrían ser considerados menos interesante, el autor de esta memoria considera muy importante su introducción ya que forman parte del esfuerzo realizado a la hora de llevar a cabo este trabajo. Es por ello que no se va a detallar en gran manera su contenido y únicamente se van a mencionar las variables y métodos principales dentro de cada clase. 6.1.1 Class Flags Se trata de una clase llamada al comienzo del código correspondiente al script que orquesta las llamadas a las clases. En la llamada al constructor de esta clase se va a especificar el valor de las banderas que se quiere para cada uno de los supuestos planteados en este escenario. Esto es, el campo recibido en los sensores varía con el tiempo o es constante, o los sensores se encuentran fijos o desplazando su posición, entre otros. En la Tabla 6.1, se muestran cada uno de los flags que forman parte del código. En relación a la bandera correspondiente al escenario, se puede apreciar que tiene tres valores distintos, los cuales se describen a continuación: 39 46 Capítulo 6. Código desarrollado La dinámica seguida en estas funciones es siempre la misma, y se trata de uno de los procedimientos más usados a la hora de aplicar algoritmos de ML en escenarios reales. Normalmente, se parte de librerías las cuales reúnen los aspectos técnicos más complejos con el fin de liberar al programador de la gran carga que supone desarrollar los algoritmos. Por lo que gracias al uso de los métodos y clases implementadas en estas librerías, el esfuerzo final dedicado se reduce exponencialmente. Debido a la importancia de estas dos funciones y a la cantidad de código implementado en ellas, se estudiarán por separado como se hizo en la sección anterior. Function algoritmo_GPStatic Primeramente, para esta sección se ha partido de la base teórica expuesta en la Sección 4.3.1 por lo que las ecuaciones que ahí aparecen serán usadas a lo largo de esta función. Se considera de importancia destacar, antes de entrar a valorar los aspectos más interesantes de esta función, la diferencia entre las muestras de entrenamiento y las de test. La variable Mon (que corresponde con el número M de nodos del grid), la cual es usada varias veces a lo largo de esta función, se utiliza para marcar el límite de las muestras que son usadas para entrenamiento dejando las restantes hasta llegar al total de las proporcionadas por los Nsensores para test. La preparación de algunas variables, las cuales son necesarias calcular antes de aplicar el algoritmo, se muestra en las líneas del Código 6.6. Código 6.6 Preparación de variables aplicadas en GPR. 1 Prev=np.append(posNxNoise[0:variables.Mon], posNyNoise[0:variables.Mon]) 2 # Entradas correspondientes a las muestras de entrenamiento 3 Xtrain=np.reshape(Prev, (variables.Mon, 2), order='F') 4 N_training=np.size(Xtrain,0) 5 # Salidas correspondientes a las muestras de entrenamiento 6 ytrain=ZMon 7 Prev=np.append(posNxNoise[variables.Mon:variables.N], posNyNoise[variables.Mon: variables.N]) 8 # Entradas correspondientes a las muestras de test 9 Xtest=np.reshape(Prev, (variables.N-variables.Mon,2), order='F') 10 11 q=10*np.log10(dtxNoise[0:variables.Mon]) 12 qd=10*np.log10(dtxNoise[variables.Mon:variables.N]) 13 # Variable que trata de emular el kernel LOG y el término bias (\sigma_{P}) 14 qq=varalpha*np.append(q,qd)[:,np.newaxis]@np.append(q,qd)[np.newaxis,:]+varP*np .ones([variables.N,variables.N]) 15 Sigman=(variables.varnoise+variables.noise_varnoise)*np.eye(variables.Mon)+ np. diag((variables.sigma_u+variables.noise_sigmau)**2/dtxNoise[0:variables.Mon ]**2) 16 17 # Media de GP 18 mtrain=meanP-10*meanalpha*np.log10(dtxNoise[0:variables.Mon]) 19 mtest=meanP-meanalpha*qd Como entrada a la función objetivo se usa las posiciones imprecisas de los sensores las cuales son definidas a partir de su valor en el eje de abcisas y de ordenada. De ahí que la variable Xtrain de la línea 3 sea una matriz de dos columnas y Mon filas. Esta variable se usa para almacenar las entradas correspondientes a las muestras de entrenamiento y, de igual forma, modela el parámetro ˆ X de las ecuaciones de la Sección 4.3.1. Además, la variable ytrain corresponde a las salidas de dicha función objetivo para las muestras de entrenamiento las cuales han sido calculadas anteriormente en otra parte del código y corresponde con el campo recibido en los sensores, almacenado en la variable ZMon 2 . Esta variable modela el parámetro z(t) en las ecuaciones de la ya mencionada sección. Por último, la variable Xtest de la línea 9 almacena las entradas pero en este caso correspondientes a las muestras de test, esto es, corresponden al parámetro Xg en las ecuaciones. El subíndice gindica que son posiciones que pertenecen al grid. 2El cálculo del campo recibido se lleva a cabo en el script principal y será comentado más adelante. 6.1 Presentación de las clases 47 Por otro lado, las variables de las líneas 11 y 12 están relacionadas con los parámetros q y qg respectivamente. Para el caso en el que no se optimizan los parámetros del kernel, y como se verá un poco más adelante, se hace uso de un kernel RBF más una serie de términos que tratan de modelar el kernel propuesto en la Ecuación (4.27) . Estos términos que se suman a los resultados obtenidos a partir del kernel RBF son almacenados en la variable qq. Basta con hacer una breve observación para asociar estos términos de la Ecuación (4.27) con la variable qq. La variable Sigman de la línea 15 modela las muestras de ruido correspondientes al modelo GP de la Ecuación (4.24) y, como ya explicó, estas muestras siguen una distribución cuya media es cero y cuya matriz de covarianza tiene la siguiente expresión: Σn=σwIN+ρ2 uˆ D(t). Por último dentro de este primer bloque de líneas, se comenta las variables mtrain ymtest de las líneas 18 y 19. Estas variables corresponden con los parámetros mXg(t) y mˆ X(t) de las Ecuaciones (4.30) y (4.25) respectivamente, esto es, con las funciones media de los procesos de GP tanto para las muestras de entrenamiento como para las muestras de test. Por tanto, se dispone en este momento de una serie de variables las cuales han sido inicializadas a partir de los datos de campo recibido en las posiciones de las muestras de entrenamiento, y se quiere estimar la media y la matriz de covarianza de las muestras que modelan el campo estimado en ciertas posiciones, determinadas por las muestras de test. Para ello se hará uso de las líneas presentadas en el Código 6.7. Código 6.7 Estimación de campo recibido en posiciones de test I. 1 if flags.optimiseHyperparameters==True: 2 # Creación del Kernel 3 bias=varP*np.ones([variables.N,variables.N]) 4 NSEKern=GPy.kern.NSE(Xtrain.shape[1]) 5 LOGKern=GPy.kern.LOG(Xtrain.shape[1]) 6 7 # Suma de los dos kernels. Ecuación (42) 8 kern=NSEKern+LOGKern 9 beta=np.diag(1/((variables.sigma_u+variables.noise_sigmau)**2/dtxNoise**2+ ( variables.varnoise+variables.noise_varnoise)*np.ones(variables.N))) 10 11 Prev=(ytrain-mtrain)[:,np.newaxis]@np.ones([1,2]) 12 13 # Selección del modelo Gaussian Processes for Regression (GPR) 14 mR=GPy.models.GPRegression(Xtrain, Prev, kern) 15 # Optimización de los hiperparámetros 16 mR.optimize() 17 18 # Obtención del kernel una vez optimizado los hiperparámetros 19 kern=mR.kern 20 21 # K_{\hat{X} en Ecuación (37) 22 Ktrain=kern.K(Xtrain,Xtrain)+bias[0:N_training,0:N_training]+beta[0: N_training,0:N_training] 23 # K_{X_{g}, \hat{X}} en Ecuación (37) 24 Kx=kern.K(Xtest,Xtrain)+bias[N_training:,0:N_training] 25 # K_{X_{g}} en Ecuación (37) 26 Ktest=kern.K(Xtest,Xtest)+bias[N_training:,N_training:] 27 # Inversa de la Ecuación (41) 28 C_inv=np.linalg.inv(Ktrain+Sigman) 29 30 # La media de la predicción 31 mGP=mtest+Kx@C_inv@(ytrain-mtrain) 32 # La covarianza de la predicción 33 vGP=Ktest-Kx@[email protected] 34 48 Capítulo 6. Código desarrollado 35 setup.RSSgpstatic=mGP 36 37 # Error cuadrático medio entre señal estimada y valor teórico 38 setup.mseGPRstatic[kk,t]=setup.mseGPRstatic[kk,t]+np.sum((setup.RSSgpstaticZUon)**2) 39 else: 40 # Kernel RBF para el caso en el que no se optimizan los hiperparámetros 41 kern=GPy.kern.RBF(input_dim=2,variance=shadowstd**2, 42 lengthscale=variables.Dcorr, inv_l=True) 43 44 # En este caso se añade la variable qq para tratar de simular lo 45 # máximo posible el kernel de la Ecuación (42) 46 Ktrain=kern.K(Xtrain,Xtrain)+qq[0:N_training,0:N_training] 47 Kx=kern.K(Xtest,Xtrain)+qq[N_training:,0:N_training] 48 Ktest=kern.K(Xtest,Xtest)+qq[N_training:,N_training:] 49 C_inv=np.linalg.inv(Ktrain+Sigman) 50 51 # La media de la predicción 52 mGP=mtest+Kx@C_inv@(ytrain-mtrain) 53 # La covarianza de la predicción 54 vGP=Ktest-Kx@[email protected] 55 56 setup.RSSgpstatic=mGP 57 58 # Error cuadrático medio entre señal estimada y valor teórico 59 setup.mseGPstatic[kk,t]=setup.mseGPstatic[kk,t]+np.sum((setup.RSSgpstaticZUon)**2) Se puede apreciar como el código se divide en dos partes bien diferenciadas, la primera de ella correspondiente a las líneas 1-38 y la segunda a las líneas 40-59. En el primer bloque se lleva a cabo la estimación del campo recibido realizando previamente una optimización de los hiperparámetros del kernel. Pero primeramente, se realiza la definición del kernel en las líneas 3,4 y 5 en las que se inicializa el término bias y los kernel NSE y LOG respectivamente. Cada término corresponde con cada sumando de la Ecuación (4.27) y, gracias al uso de la librería GPy, la cual se presentó en un capítulo anterior, basta con usar el operando +para definir la función kernel por completo. Posteriormente, destaca las líneas 14 y 16 donde nuevamente la librería GPy es usada para definir el modelo, el cual como se ha comentado a lo largo de esta memoria no es otro que un proceso gaussiano para regresión (GPR), y se inicializa con las entradas correspondientes a las muestras de entrenamiento y con las salidas una vez restada la media. Una de las líneas más importantes es la 16, en la que se aprecia como el modelo se optimiza con el fin de obtener aquellos hiperparámetros que proporcionen mejores resultados en la función kernel. Nuevamente, las líneas 21-28 corresponden a la inicialización de variables las cuales son sumamente importante en este proyecto. Con el fin de conseguir un mejor entendimiento de esta parte tan importante, se ha rellenado la Tabla 6.3 en la que se realiza una asociación entre las variables definidas en estas líneas y los parámetros de la Ecuación (4.32). Tabla 6.3 Asociación parámetro-variable en Ecuación (4.32). Variable Parámetro Argumentos de entrada Ktrain Kˆ XMuestras de entrenamiento Kx KXg,ˆ XMuestras de entrenamiento y test Ktest KXgMuestras de test Para inicializar estas variables se hace uso de la función kernel una vez optimizado los hiperparámetros. Los argumentos de entrada de esa función son las posiciones correspondientes a las muestras de entrenamiento o test según corresponda. A los resultados proporcionados como salidas de la función se les suma el término bias el cual no fue introducido en la optimización del kernel y por tanto se añade en este punto y además, 6.1 Presentación de las clases 49 a la variable Ktrain se le suma la variable beta que incluye el ruido de las muestras como se aprecia en la Ecuación (4.32) . Adicionalmente, se encuentra la variable C_inv que está asociada con el parámetro C−1 ˆ X (Ecuación (4.36)). Todas estas variables definen perfectamente la función densidad de probabilidad conjunta necesaria en todo proceso gaussiano para, una vez condicionada dicha función densidad de probabilidad a las salidas (ytrain o z(t) ) se pueda obtener la media y la matriz de covarianza de las muestras que modelan el campo estimado. En este punto se aprecia claramente como las líneas 31 y 33 corresponden perfectamente con las Ecuaciones (4.34) y (4.35) , calculando de esta forma la media y la matriz de covarianza de las muestras respectivamente. Por último, en la línea 38 se calcula el error cuadrático medio cuya finalidad será estudiada en el capítulo de simulaciones realizadas. Para el caso en el que no se optimizan los hiperparámetros el código es mucho más simple ya que únicamente se define un una función kernel RBF la cual no es optimizada y que además es usada para calcular directamente las variable Ktrain,Kx yKtest en las líneas 46-49. Adicionalmente, se le suma la variable qq con el fin de simular de la manera más fiel posible el kernek de la Ecuación (4.27) . Igualmente se estima la media y la matriz de covarianza de las muestras en las líneas 52 y 54 a partir de las variables anteriores y de las ecuaciones ya mencionadas. Function algoritmo_GPRecursive Una vez estudiado el código para el caso en el que campo es estático se va a proceder a presentar el código utilizado para estimación en el supuesto en el que el campo recibido en los sensores sea variante en el tiempo. Las diferencias desde el punto de vista teórico respecto al caso en el que el campo recibido en los sensores es estático han sido estudiadas en un capítulo anterior por lo que aquí únicamente se presentará la aplicación de las fórmulas mostrando especial interés en la introducción del factor de olvido. Las líneas correspondientes a la estimación en este supuesto se encuentran en el Código 6.8 en el que únicamente se incluyen las líneas correspondientes a la estimación sin optimización de hiperparámetros con el fin de evitar cargar en exceso el código introducido en esta memoria. Código 6.8 Estimación de campo recibido en posiciones de test II. 1 global mprior 2 global Cprior 3 Prev=np.append(posNxNoise[0:variables.Mon], posNyNoise[0:variables.Mon]) 4 # Entradas correspondientes a las muestras de entrenamiento 5 Xtrain=np.reshape(Prev, (variables.Mon, 2), order='F') 6 N_training=np.size(Xtrain,0) 7 # Salidas correspondientes a las muestras de entrenamiento 8 ytrain=ZMon 9 Prev=np.append(posNxNoise[variables.Mon:variables.N], posNyNoise[variables.Mon: variables.N]) 10 # Entradas correspondientes a las muestras de entrenamiento 11 Xtest=np.reshape(Prev, (variables.N-variables.Mon,2), order='F') 12 13 q=10*np.log10(dtxNoise[0:variables.Mon]) 14 qd=10*np.log10(dtxNoise[variables.Mon:variables.N]) 15 # Variable que trata de emular el kernel LOG y el término bias (\sigma_{P}) 16 qq=varalpha*np.append(q,qd)[:,np.newaxis]@np.append(q,qd)[np.newaxis,:]+varP*np .ones([variables.N,variables.N]) 17 Sigman=(variables.varnoise+variables.noise_varnoise)*np.eye(variables.Mon)+ np. diag((variables.sigma_u+variables.noise_sigmau)**2/dtxNoise[0:variables.Mon ]**2) 18 19 # Media de GP 20 mtrain=meanP-10*meanalpha*np.log10(dtxNoise[0:variables.Mon]) 21 mtest=meanP-meanalpha*qd 22 23 # Kernel RBF para el caso en el que no se optimizan los hiperparámetros 50 Capítulo 6. Código desarrollado 24 kern=GPy.kern.RBF(input_dim=2,variance=shadowstd**2, 25 lengthscale=variables.Dcorr, inv_l=True) 26 27 # En este caso se añade la variable qq para tratar de simular lo 28 # máximo posible el kernel de la Ecuación (42) 29 # K_{\hat{X}} en Ecuación (37) 30 Ktrain=kern.K(Xtrain,Xtrain)+qq[0:N_training,0:N_training] 31 # K_{X_{g}, \hat{X}} en Ecuación (37) 32 Kx=kern.K(Xtest,Xtrain)+qq[N_training:,0:N_training] 33 # K_{X_{g}} en Ecuación (37) 34 Ktest=kern.K(Xtest,Xtest)+qq[N_training:,N_training:] 35 # Inversa de la Ecuación (41) 36 C_inv=np.linalg.inv(Ktrain+Sigman) 37 38 # \mu_{post}. Ecuación (57) 39 mpos=Kx@C_inv@(ytrain-mtrain) 40 # \Sigma_{post}. Ecuación (58) 41 Cpos=Kx@C_i[email protected] 42 43 # "prior" in los nodos 44 if t==0 or (flags.flag_moving==0 and flags.flag_intermitent==0): 45 mprior=mpos 46 Cprior=Cpos 47 48 # La media de la predicción 49 mGP=mtest+variables.forgetting_factor*mpos+(1-variables.forgetting_factor)* mprior 50 # La covarianza de la predicción 51 vGP=Ktest-variables.forgetting_factor*Cpos-(1-variables.forgetting_factor)* Cprior 52 53 setup.RSSgprecursive=mGP 54 55 #\mu_{prior}. Ecuación (59) 56 mprior=variables.forgetting_factor*mprior+(1-variables.forgetting_factor)*mpos 57 #\Sigma_{prior}. Ecuación (60) 58 Cprior=variables.forgetting_factor*Cprior+(1-variables.forgetting_factor)*Cpos 59 60 # Error cuadrático medio entre señal estimada y valor teórico 61 setup.mseGPrecursive[kk,t]=setup.mseGPrecursive[kk,t]+np.sum((setup. RSSgprecursive-ZUon)**2) Observando las líneas expuestas, se aprecia como la preparación de variables del Código 6.6 son exactamente iguales que las líneas 3-21. Además, la definición de la función kernel, así como el calculo de las variables de la Tabla 6.3 se realiza en las líneas 30-36 de manera similar a como se hacia en el caso estático. Las novedades en este fragmento de código empiezan a aparecer en la línea 39 y 41, donde se calcula la media y la matriz de covarianza para la función densidad de probabilidad a posteriori usando las expresiones de las Ecuaciones (4.39) y (4.40) respectivamente. Por otro lado, para el (1) instante cero, o (2) para el caso en el que los sensores desplacen su posición en cada instante de tiempo, o (3) para el supuesto en el que los sensores permanezcan apagados en algún instante de tiempo, la media y matriz de covarianza a priori coincide con los valores a posteriori calculados en las líneas mencionadas anteriormente. Esta consideración se muestra en las líneas 44-46. Una vez inicializadas estas variables, la media y matriz de covarianza de las muestras que modelan el campo estimado se calcula en las líneas 49 y 51 haciendo uso de la base teórica de las Ecuaciones (4.37) y (4.38) . En estas líneas, y como ocurría en las ecuaciones, aparece el factor de olvido o forgetting factor para dar una mayor relevancia en la estimación a la muestras recientes frente a las más antiguas. 6.2 Fichero principal 51 Por último, se calcula la media y matriz de covarianza a priori para la siguiente iteración en las líneas 56 y 58 haciendo uso de las Ecuaciones (4.41) y (4.42). 6.1.6 Class gráficas Esta última clase tiene una importancia considerablemente inferior a sus dos inmediatas predecesoras ya que únicamente cuenta con tres métodos los cuales son usados para representar los resultados obtenidos. Los detalles más importantes de estos métodos están relacionados con el uso de la librería matplotlib, por lo que se considera innecesario entrar demasiado en detalle. Los tres métodos que forman esta clase se listan a continuación: •representacion_scenario : Es usada para representar una gráfica muy interesante del escenario de aplicación del algoritmo ya que presenta la posición del transmisor así como de los sensores y nodos donde se pretende estimar el campo recibido. •representacion_variacion_potencia : Se trata de un método usado para representar el campo recibido en función de la distancia. Para los resultados de RSS que se quieren representar se consideran las medidas de los sensores, los valores estimados y los valores teóricos. •representacion_final_algoritmo : Se encarga de representar el error cuadrático medio entre la estimación realizada y el valor teórico real frente a distintos valores de varianza de las muestras que modelan la atenuación por efectos de shadowing (σ2 v). 6.2 Fichero principal Todas y cada una de las clases presentadas en la anterior sección son inicializadas meticulosamente y los métodos desarrollados en cada una de ellas son llamados de manera orquestada a partir de un fichero principal. En torno al 90% está condensado en las clases presentadas en la sección previa mientras que el 10% del código restante, el cual se presenta en esta sección, se encarga de gestionar las llamadas a las clases y métodos de manera ordenada. Este 10% correspondiente al fichero principal cuenta con la siguiente estructura: Destaca la presencia de tres bucles que hacen que el tiempo de ejecución del algoritmo sea bastante extenso. En los dos bucles siguientes al primero se itera en torno a los instante de tiempo y los distintos valores de varianza de shadowing. Por defecto, se lleva a cabo una simulación de 10 instantes de tiempo, con un segundo por iteración mientras que los valores de varianza que modela las pérdidas por shadowing están acotados entre 0.5 y 10, iterando cada dos valores. El primer bucle está implementado con el fin de realizar un promedio de los resultados obtenidos. Más adelante, en el capítulo correspondiente a las simulaciones realizadas, se profundizará más en la importancia de este promediado. Como se vio en las funciones correspondientes a la Clase setup, la posición de los nodos del grid se configuraban haciendo uso de funciones definidas en esa clase. En cambio, las posiciones de los sensores dentro de ese grid es determinada en el fichero principal. Además, como se comentó en el capítulo correspondiente a la presentación del escenario, es necesario añadir una indeterminación a la posición de los sensores con el fin de dar un mayor realismo al modelo, ya que esta no puede ser perfectamente conocida. Este calculo de error se realiza igualmente en el fichero principal. Por otro lado, la acción más importante a realizar dentro del fichero principal se recoge en las líneas mostradas en el Código 6.9. Código 6.9 Calculo de campo recibido en sensores. 1 # Path-loss exponent 2 alpha=np.ones(variables.N)*variables.alphai 3 4 # Shadowing 5 delta=np.append(deltaM[indexon,t],deltaU) 6 7 # Ruido 8 noise=np.append(np.sqrt(variables.varnoise)*np.random.randn(variables.Mon),np. zeros(variables.U)) 52 Capítulo 6. Código desarrollado 9 10 # RSSI 11 Z=variables.P-np.diag(10*alpha*np.log10(dtx))@np.ones(variables.N)+delta+noise 12 ZMon=Z[0:variables.Mon] 13 ZUon=Z[variables.Mon:variables.N] En la línea 8 se observa claramente la implementación en fórmula de la Ecuación (4.6) en la que se aprecia las muestras que modelan la atenuación por shadowing así como el ruido gaussiano que modela el ruido propio de las muestras así como la imprecisión en la posición de los sensores. Estas muestras quedan almacenadas en las variables delta ynoise respectivamente. Los resultados obtenidos a partir de la línea 8 tienen principalmente dos funciones: 1. Las primeras Mon muestras son tomadas como si fueran información proporcionada por sensores y se almacena en la variable ZMon. Esta variable es usada principalmente como salida de la función objetivo en las posiciones de entrenamiento por lo que se asocia al parámetro z(t)en las Ecuaciones. 2. Las muestras restantes son tomadas como campo recibido de manera teórica en las posiciones de los nodos. Por tanto el valor estimado a partir del algoritmo de GPR será comparado con los valores almacenados en esta variable con el fin de calcular el error cuadrático medio y de esta forma obtener un parámetro que mide la precisión de la estimación realizada. 6.3 Código desarrollado para sparse GP Como ya fue comentado en un capítulo anterior, en este trabajo se hace uso de una técnica que pretende reducir el tiempo de ejecución total de este código. La base teórica detrás de esta técnica se presenta en la Sección 3.4. Por tanto, y siguiendo con la idea de este capítulo, únicamente se mostrarán las líneas de código necesarias para hacer uso de esta técnica. La librería GPy, ya explicada con anterioridad en este documento, permite de manera muy simple determinar el modelo de GP requerido para cada escenario. Como se veía en el Código 6.7 en la línea 12, la elección del modelo usado se lleva a cabo de manera trivial a partir del método GPRegression. Para usar el modelo sparse GP con el fin de reducir el tiempo de ejecución total, basta con hacer el cambio mostrado en el Código 6.10. Código 6.10 Selección del modelo sparse GP. 1 num_inputs=150 2 mC=GPy.models.SparseGPRegression(Xtrain, Prev, kern, num_inducing=num_inputs) 3 mC.optimize En dicho código se aprecia como únicamente es necesario hacer uso del método SparseGPRegression para seleccionar el modelo con reducción de muestras en lugar del modelo de regresión convencional. Además, se observa como en la línea 1 se indica el número de muestras que van a "codificar" la información correspondiente al conjunto total de muestras. Ni que decir tiene que una reducción de este valor implica un decremento en el tiempo total de ejecución pero en cambio, la estimación realizada es menos precisa. 7 Simulaciones y resultados obtenidos Equipado con sus cinco sentidos, el hombre explora el universo que lo rodea y a sus aventuras las llama Ciencia. Edwin Powell Hubble La principal finalidad de todo código desarrollado en un proyecto reside en la obtención de resultados, usados con el fin de llevar a cabo una serie de conclusiones. Por tanto, definir perfectamente las simulaciones que se van a realizar es uno de los pasos más importantes dentro de cualquier trabajo ya que determinarán conclusiones finales del estudio realizado. A lo largo de este capítulo se van a presentar las simulaciones que se han realizado a partir del código desarrollado, así como los resultados obtenidos. Además, se mencionarán algunas de las conclusiones técnicas principales obtenidas a partir de un análisis de los resultados obtenidos gracias a las simulaciones realizadas. Las conclusiones finales del proyecto se dejarán para un capítulo posterior. 7.1 Robustez de valores estimados Uno de los aspectos más interesantes tratados a lo largo de la memoria está relacionado con la estimación de aquellos parámetros del modelo de los cuales no se conocían de manera exacta su valor. Tras una explicación extensa acerca del contexto teórico en el que se mueven estas estimaciones, así como una presentación detallada del código implementado para poder llevar a cabo dicha estimación, en esta sección se van a mostrar algunos resultados correspondientes a la exactitud de estos parámetros. Primeramente se van a mostrar los resultados de una serie de simulaciones correspondientes a distintas estimaciones de la posición del transmisor. Como se ha comentado en la sección anterior, el grid en el que se mueve el escenario de este trabajo está determinado por una superficie de 500x500 m. Además, y como se aprecia en la Figura 4.1, los ejes están definidos de forma que se establece la posición cero en el medio y por tanto, las posibles posiciones van desde el -250 hasta el 250 tanto para el eje de abscisas como para el de ordenadas. Por tanto, se podrá determinar la posición del transmisor en cualquier lugar dentro de este grid, siempre y cuando se tenga en cuenta las consideraciones acerca de los ejes mencionadas anteriormente. Tabla 7.1 Estimación de posición del transmisor para distintas casos. x[1] 0ˆx[1] 0x[2] 0ˆx[2] 0x[3] 0ˆx[3] 0x[4] 0ˆx[4] 0 Pos x 0 -5.19 -30 -43.56 130.6 104.36 -180.4 -224.67 Posy 0 7.34 60 64.07 130.6 107.38 -180.4 -203.43 Como se aprecia en la Tabla 7.1, se han realizado una serie de cuatro simulaciones (indicadas en el superíndice de los elementos de la tabla) en las que se ha variado drásticamente la posición del transmisor a lo largo de la totalidad de la superficie del escenario. Se puede observar como los resultados obtenidos no son especialmente exactos, existiendo en algunos casos un error de en torno al 10% , pero teniendo en cuenta todas las fuentes de error añadidas al modelo, se puede concluir que estos resultados son aceptables ya que no estima de manera exacta la posición del transmisor, pero ayuda a dar una idea aproximada de su posición. 53 54 Capítulo 7. Simulaciones y resultados obtenidos Por otro lado, se realizaron otras cuatro simulaciones pero para distintos valores de potencia transmitida y de exponente de pérdidas . La principal finalidad de estas simulaciones es similar a la anterior, ya que se pretende mostrar una idea de la exactitud y robustez de las estimaciones de estos dos parámetros. Las estimación correspondiente a estas dos variables se muestra en la Tabla 7.2 para cada una de las cuatro simulaciones realizadas. Tabla 7.2 Estimación de potencia transmitida y exponente de pérdidas para distintas simulaciones. P[1] tx (dBm)α[1]P[2] tx (dBm)α[2]P[3] tx (dBm)α[3]P[4] tx (dBm)α[4] Valor teórico -15 3.6 -10 3.5 -5 3.4 0 3.3 Valor estimado -18.19 3.50 -12.19 3.41 -6.89 3.38 0.33 2.95 A la vista de los resultados se puede concluir que las estimaciones realizadas para la potencia transmitida y para el exponente de pérdidas son considerablemente mejores que para la posición del transmisor. Cabe destacar que las estimaciones del parámetro α son especialmente exactas, exceptuando para la última simulación en la que el error cometido es considerable. En un gráfica correspondiente a un apartado posterior se mostrará desde otro punto de vista la fiabilidad de estas estimaciones. 7.2 Estimación de campo recibido En esta sección se muestran los resultados más importantes de este trabajo , ya que se van a presentar las simulaciones realizadas, así como los resultados obtenidos a partir de estas, en las que se muestra la precisión del modelo a la hora de estimar el campo recibido en los nodos del grid. Al igual que para la estimación de parámetros, la explicación de teórica así como el código desarrollado para llevar a cabo estas simulaciones fueron presentadas en los capítulos anteriores, por lo que está sección va a estar enfocada en la introducción de las simulaciones realizadas y los resultados obtenidos. También se apartará un espacio en esta sección para presentar la manera de obtener cada una de las figuras, esto es, se comentarán las banderas que son necesarias de inicializar para cada una de las simulaciones realizadas. El resto de parámetros permanecen constantes en todas las simulaciones. 7.2.1 Campo estático En este primer apartado se va a partir del supuesto en el que el campo es constante a lo largo del tiempo, y por tanto únicamente será necesario tener en cuenta la muestra actual para poder realizar las estimaciones del campo recibido. 0 50 100 150 200 250 300 350  di (m) −100 −80 −60 −40 −20 0 RSS [dBm] P = -10, μP =-5.32, α =3.5, μα =3.71 P −10 α log10(  di )  μP −10  μα log10(  di ) μi −100 −90 −80 −70 −60 −50 Figura 7.1 Variación de campo recibido respecto a la distancia. 7.2 Estimación de campo recibido 55 Una de las simulaciones más interesantes realizadas en este apartado se muestra en la Figura 7.1. A partir del análisis de esta figura se pueden desarrollar algunas conclusiones importantes: • Los puntos corresponden a la información, proporcionada por los sensores, de campo recibido en ciertas posiciones del espacio. Si se analiza con detenimiento se puede concluir que se tratan de los mismos puntos de la Figura 4.1 pero distribuidos de otra forma. • La línea negra corresponde con el campo recibido en función de la distancia para el caso "teórico". Esto es, para el caso en el que la potencia del transmisor y el exponente de pérdidas no son estimados sino que se parte de sus valores originales. • La línea roja a rayas corresponde a la variación del campo recibido en función de la distancia para el caso en el que los parámetros son estimados. Como ya se apreció en la sección anterior, las estimaciones son considerablemente aceptables, hasta el punto de obtener resultados muy próximos a los teóricos. • Un aspecto interesante en esta simulación corresponde a la estimación de campo recibido en posiciones próximas al transmisor. Como ya se ha comentado, la información proporcionada por los sensores en estos puntos es muy imprecisa como ya se demostró a raíz de la Figura 4.2. Gracias a las mejoras introducidas, las cuales ya fueron explicadas con anterioridad en esta memoria, la información proporcionada por estos sensores tienen un peso menor que la del resto, por lo que la estimación en esas posiciones cercanas siguen siendo buenas a pesar de ese error. En esta situación de campo estático, se llevaron a cabo además algunas simulaciones adicionales. La primera de ellas, da lugar a una gráfica en la que se muestra la media de la distribución a posteriori estimada a partir del Proceso gaussiano. La idea detrás de esta gráfica reside en el estudio del campo recibido a lo largo de todas las posiciones del escenario. Se podría haber representado de manera discreta, únicamente a partir de datos aislados, pero tiene un mayor sentido dibujar una malla en la que se muestra como el campo recibido varía a lo largo de todas las posiciones del escenario. La representación de esta importante simulación se muestra en la Figura 7.2. -70 -60 200 -50 -40 100 RSS (dBm) 200 -30 x(2) (m) 100 0 -20 x(1) (m) -10 0 -100 -100 -200 -200 Figura 7.2 Campo recibido a lo largo de todo el escenario (x0= [0 0]). En esta figura se representa además con puntos rojos el campo recibido en los sensores, y se aprecia de manera clara como esta información afecta determinantemente al campo estimado. Por ejemplo, en la esquina superior izquierda (valores pequeños del eje x, y grandes del eje y), se aprecia una hendidura en la superficie debido a una acumulación de medidas en torno a esa zona. Se puede observar también, como la superficie representada trata de "unir" y "juntar" todos los puntos rojos, obteniendo de esta forma los resultados esperados. Por tanto, se ve claramente la regresión llevada a cabo entre los puntos con la información de campo recibido de los sensores. 62 Capítulo 8. Conclusiones y trabajos futuros De esta manera, y a la vista de los resultados obtenidos, se puede concluir que este objetivo fue alcanzado satisfactoriamente. 8.1.2 Aprendizaje ML Se trata del objetivo fijado desde el punto de vista personal. Se considera importante volver a recordar en este punto que, todo el marco teórico que rodea a este trabajo, parte de un estudio realizado anteriormente y en el cual, el autor de esta memoria no tuvo ninguna implicación. La base teórica de la que partía el realizador de este trabajo, en cuanto a aspectos relacionados con el ML era nula y, por tanto, haber realizado este trabajo desde cero hubiera supuesto un esfuerzo el cual se encuentra muy por encima de lo requerido como Trabajo Fin de Máster. Por otro lado, se trata de un objetivo cuyo cumplimiento es difícilmente demostrable de manera empírica, ya que no hay ninguna forma de medir el nivel de conocimientos adquiridos de forma numérica. Por tanto, este apartado tiene un enfoque más personal que técnico. De manera sincera, y aunque no haya forma de demostrar las competencias adquiridas, puedo decir que el aprendizaje adquirido gracias a este trabajo es muy considerable. Como se ha comentado, la base era nula y tras unos meses invertidos en la comprensión de los fundamentos de GPR aplicados en este escenario, se pudo satisfactoriamente y de manera autónoma con ayuda del tutor de este trabajo, obtener resultados fiables. Por lo que se puede concluir que este objetivo fue alcanzado ya que, a partir de este momento, los conocimientos generales sobre los algoritmos de ML, y más específicamente sobre los algoritmos de GP para regresión, han sido adquiridos de manera satisfactoria. De esta forma se alcanza uno de los objetivo personales (ajenos a este trabajo) que andaba buscando el cual consistía en adquirir conocimientos sobre ML de manera que pudieran ser aplicados en un escenario real. 8.2 Trabajos futuros Otra de las buenas prácticas que rodean a todo trabajo está basada en la fijación clara de los objetivos, esto es, en delimitar el alcance del proyecto de forma que no deje lugar ningún tipo de dudas. De esta forma, se pueden sacar conclusiones relacionadas con el éxito o fracaso del proyecto, al cumplir o no los objetivos como ya fue explicado en la sección anterior. También evita realizar trabajo adicional ya que, al delimitar el alcance del proyecto de manera clara, las actividades a realizar así como el trabajo total a desarrollar quedan perfectamente acotados. En cambio, el hacer un esfuerzo por delimitar el alcance del trabajo de manera clara, no implica que no se pueda "ir más allá", y que el estudio realizado se acabe al finalizar la memoria del proyecto. Podrían darse el caso de posibles estudios o actividades futuras relacionadas con el trabajo que trasciendan los límites y alcance del proyecto, pero que pueda llegar a proporcionar resultados interesantes. Al ser necesario que el proyecto tenga un cierre bien definido, este tipo de supuestos se suelen especificar en el apartado de trabajos futuros y por tanto, en esta sección se presentarán algunos de los trabajos futuros que pudieran surgir de este trabajo. Al no encontrarse especialmente relacionados los objetivos de este trabajo con el estudio teórico, es difícil de encontrar, por mi parte, vías interesantes de estudio que puedan surgir a partir de este proyecto. De todas formas, existen algunos supuestos trabajos futuros que pueden ser interesantes los cuales son listados a continuación, y están relacionados con el transmisor: 1. El primero de ellos está relacionado con detectar la existencia o ausencia de transmisor. En este trabajo se da el supuesto de que siempre existe un transmisor que además se encuentra en una zona fija. Por tanto, sería un avance detectar si existe o no transmisor antes de estimar el campo recibido, lo que ahorraría tiempo de computación. 2. Otro aspecto interesante estaría relacionado con la existencia de más de un transmisor lo que implicaría un cambio considerable del modelo ya que sería necesario tener en cuenta los efectos de emisores adicionales que interfieren entre ellos. Por tanto, sería necesario añadir al modelo original las interferencias entre transmisores una vez han sido detectados y localizados correctamente. Apéndice A Código correspondiente al script usado para obtener las figuras de la Sección 7.2 Código A.1 static_GP.py. 1 # Autor: Daniel Vela Calderón 2 # Trabajo Fin de Máster 3 4 # Código Python correspondiente al paper: 5 # "Recursive Estimation of Dynamic RSS Fields Based on 6 # Crowdsourcing and Gaussian Processes" 7 8 # Script principal encargado de llamar a las distintas funciones que forman 9 # este proyecto 10 11 # Librerías importadas 12 import numpy as np 13 import math 14 import time 15 import random 16 import matplotlib.pyplot as plt 17 from scipy.optimize import minimize 18 from scipy.optimize import lsq_linear 19 import GPy 20 import matlab.engine 21 from flags import Flags 22 from variable import Variables 23 from setup import Setup 24 import aditional_functions as functions 25 import graficas as gr 26 import algoritmos as alg 27 #import gpflow 28 29 # Herramienta para ejecturar funciones de Matlab 30 eng=matlab.engine.start_matlab() 31 eng.addpath(r'C:\Users\Dani Vela\Desktop\TFM\Codes\Matlab\FinalCode', nargout =0) 32 33 34 #%% 35 63 64 Apéndice A. Código correspondiente al script usado para obtener las figuras de la Sección 7.2 36 # Sentencia necesario para medir el tiempo de ejecución de las simulaciones 37 expend=time.time() 38 39 ''' 40 Los distintos flags son almacenados en la siguiente clase: 41 1. Escenario usado. Hay tres posibles escenarios: 42 1.1. Todos los sensores están estáticos (1) 43 1.2. Todos los sensores se están moviendo (2) 44 1.3. Todos los sensores están estáticos pero no están siempre transmitiendo (3) 45 2. Estimación de la posición del transmisor (1 ó0) 46 3. Uso de algorimto GPR para escenario estático (1 ó0) 47 4. Uso de algoritmo GPR para escenario recursivo (1 ó0) 48 5. Uso del algoritmo OKD. Mirar referencia del paper (1 ó0) 49 6. Uso de algoritmo "Gholami". Mirar referencia del paper (1 ó0) 50 7. Uso de algoritmo "Watcharapan". Mirar referencia del paper (1 ó0) 51 8. Representación de las figuras (1 ó0) 52 9. Representación de los hiperparámetros estimados del kernel (1 ó0) 53 10. Posición fija de los nodos (1 ó0) 54 11. Los hiperparámetros se obtienen del Kernel (True) o de los datos (False ) 55 12. El modelo usado es GP para regresión (1 ó0) 56 13. El modelo usado es GP para regresión con inducing inputs (1 ó0) 57 ''' 58 flags=Flags(1, 0, 1, 0, 0, 0, 0, 1, 0, 1, True, 1, 0) 59 flags.flag_mov_inter() 60 61 # Establecemos una semilla para controlar la aleatoriedad de las muestras 62 np.random.seed(1) 63 64 ''' 65 Las variables que han sido obtenidas en distintos estudios son almacenados en 66 la siguien clase, además de las variables necesarias para la ejecución del 67 programa: 68 1. Varianza del efecto "shadowing" en el exterior en dB 69 2. Número total de experimentos 70 3. Instantes de tiempo simulado 71 4. Potencia transmitida (dBm) 72 5. Número de nodos no disponibles 73 6. Pérdidas por multitrayecto 74 7. rho_u en el paper (mdB) 75 8. Distancia de decorrelación 76 9. Varianza de ruido 77 10. "Forgetting Factor". Lambda = 0, olvida todo lo anterior. Lambda = 1 78 todas las muestras anteriores aportan lo mismo 79 11. Porcentaje de los nodos totales que estarán off en cada instante de tiempo 80 12. Varianza entre instantes de tiempo consecutivos en el que se mueve los nodos 81 13. noise_sigmau 82 14. noise_varnoise 83 ''' 84 variables=Variables([0.5, 2, 4, 6, 8, 10], 10, 10, -10, 10, 3.5, 200, 50, 85 7, 0.5, 20, 1, 0, 0) 86 87 ''' 88 Clase para preparar el setup necesario para este trabajo: 65 89 1. Grid donde se encuentran los nodos (500mx500m) 90 *La densidad de nodos de observación es de 4 por cada 100mx100m 91 2. Densidad de nodos dentro del grid 92 3. Distancia entre nodos 93 ''' 94 setup=Setup([500, 500], 0.2, 100) 95 96 # Posición de los nodos 97 setup.node_position(flags, variables) 98 99 # Posición del transmisor 100 # Situación del transmisor en el centro del grid 101 postx=[0, 0] 102 setup.tx_position(postx, variables) 103 104 # Distribución de los nodos disponibles entre el total de nodos del Grid 105 setup.node_distribution(flags, variables) 106 107 # A continuación se inicializa los vectores donde se almacenará el error 108 # cuadrático medio para cada algoritmo 109 setup.initialize_vectors(flags, variables) 110 111 # Bucle principal 112 for nexperiments in range(0,variables.Nexp): # Nexp 113 print ('Nexp=' +str(nexperiments) + '/' +str(variables.Nexp-1)) 114 115 # Para cada experimento, genera los datos. Vector con la posición de los 116 # sensores y de todos los grid 117 posNx=np.append(setup.posMxall[:,:,nexperiments].flatten('F'), setup.posUx) 118 posNy=np.append(setup.posMyall[:,:,nexperiments].flatten('F'), setup.posUy) 119 120 # Calculo de las distancias real 121 Nall=len(posNx) 122 Dall=functions.calculate_real_distance(Nall, posNx, posNy) 123 124 #%% 125 for kk in range(0,len(variables.shadowvarSim)): #len(shadowvarSim) 126 print ('ShadowvarSim=' +str(kk) + '/' +str(len(variables.shadowvarSim) -1)) 127 # Genera las muestras para la atenuación debido al fenómeno de 128 # "shadowing" la cual sigue una distribución normal de media cero y 129 # varianza shadowvar. Estas muestras tienen que ser correladas por 130 # por lo que son generadas con una variable gaussiana multidimensional 131 # de media cero y covarianza c 132 deltaM, deltaU, shadowstd, var_v = functions.calculate_sample_shadow( 133 variables, Nall, Dall, kk) 134 135 #%% 136 for tin range(0,variables.Ttotal): #Ttotal 137 print ('Instante=' +str(t) + '/' +str(variables.Ttotal-1)) 138 139 # En función del instante de tiempo, algunos nodos estarán emitiendo 140 # o no. Esto se refleja en los nuevos valores de posNx y posNy 141 posNx, posNy, indexon = functions.readjust_node_emition(flags, variables, setup, t, nexperiments) 142 143 dtx=np.sqrt((postx[0]-posNx)**2+(postx[1]-posNy)**2) 66 Apéndice A. Código correspondiente al script usado para obtener las figuras de la Sección 7.2 144 dtxNoise=np.append(np.absolute(dtx[0:variables.Mon]+variables. sigma_d*np.random.randn(variables.Mon)),dtx[variables.Mon: variables.N]) 145 # Generación a partir de la función randn de MATLAB 146 #dtxNoise=np.append(np.absolute(dtx[0:Mon]+sigma_d*np.array(eng. randn(1,Mon))[0]),dtx[Mon:N]) 147 148 # Error en la posición 149 errd=dtxNoise[0:variables.Mon]/dtx[0:variables.Mon] 150 posMxNoise=posNx[0:variables.Mon]*errd 151 posMyNoise=posNy[0:variables.Mon]*errd 152 153 posNxNoise=np.append(posMxNoise, setup.posUx) 154 posNyNoise=np.append(posMyNoise, setup.posUy) 155 156 # Calculo de la "distancia de ruido" entre posiciones 157 DNoise=functions.calculate_noise_distance(variables, posNxNoise, posNyNoise) 158 159 #%% 160 CNoise=var_v*np.exp(-DNoise/variables.Dcorr) 161 162 # Datos 163 164 # Path-loss exponent 165 alpha=np.ones(variables.N)*variables.alphai 166 167 # Shadowing 168 delta=np.append(deltaM[indexon,t],deltaU) 169 170 # Ruido 171 noise=np.append(np.sqrt(variables.varnoise)*np.random.randn( variables.Mon),np.zeros(variables.U)) 172 173 # RSSI teórico 174 Z=variables.P-np.diag(10*alpha*np.log10(dtx))@np.ones(variables.N)+ delta+noise 175 ZMon=Z[0:variables.Mon] 176 ZUon=Z[variables.Mon:variables.N] 177 178 if flags.flag_tx_est == 1: 179 # Estimación de la posición del transmisor 180 dtxNoise, postx_est = functions.estimate_pos_tx(ZMon, posMxNoise, 181 posMyNoise, posNxNoise, posNyNoise, t) 182 else: 183 postx_est=postx 184 185 # Representación únicamente en la primera iteración 186 if flags.flagfigs==1 and t==0 and kk==0 and nexperiments==0: 187 # Figura 2 en el paper 188 gr.representacion_scenario(setup, postx, ZMon) 189 190 #%% 191 # Estimación de alfa y de P 192 meanP, meanalpha, varalpha, varP = functions.alpha_beta_estimation( 67 193 flags, variables, dtxNoise, CNoise, ZMon, ZUon, posMxNoise, posMyNoise, 194 posNyNoise, posNxNoise, postx_est) 195 196 #%% 197 if flags.flagfigs==1 and t==0 and kk==0 and nexperiments==0: 198 # Figura 4 en el paper 199 gr.representacion_variacion_potencia(variables, ZMon, dtxNoise, 200 meanP, meanalpha) 201 202 # A continuación iría uno por cada algoritmo que se quiera hacer 203 #%% 204 # Gholami 205 if flags.flagGholami==1: 206 # Estimación a partir de método de Gholami [Mirar referencias en la memoria] 207 alg.algoritmo_Gholami(variables, setup, posMxNoise, posMyNoise, posNyNoise, posNxNoise, ZMon, kk, t, ZUon) 208 #%% 209 # Watcharapan 210 if flags.flagWatcharapan==1: 211 # Estimación a partir de método de Watcharapan [Mirar referencias en la memoria] 212 alg.algoritmo_watcharapan(variables, setup, posNyNoise, posNxNoise, ZUon, ZMon, kk, t) 213 # %% 214 # Se estima la señal recibida en los nodos disponibles 215 #OKD 216 if flags.flagOKD==1: 217 # Estimación a partir de método de OKD [Mirar referencias en la memoria] 218 alg.algoritmo_OKD(variables, setup, meanP, meanalpha, dtxNoise, ZMon, DNoise, ZUon, kk, t) 219 #%% 220 # GPrecursive 221 if flags.flagGPrecursive==1: 222 # Estimación a partir del método de GP para campos variantes en el tiempo 223 alg.algoritmo_GPRecursive(flags, variables, setup, posNxNoise, 224 posNyNoise, ZMon, dtxNoise, meanalpha, meanP, varalpha, varP, 225 shadowstd, ZUon, kk, t) 226 #%% 227 # GPstatic 228 if flags.flagGPstatic==1: 229 # Estimación a partir del método de GP para campos estáticos en el tiempo 230 alg.algoritmo_GPStatic(flags, variables, setup, posNxNoise, 231 posNyNoise, ZMon, dtxNoise, meanalpha, meanP, varalpha, varP, 232 shadowstd, ZUon, kk, t) 233 #%% 234 235 # Representación de los resultados de error obtenidos a partir de las simulaciones 236 my_tplot=1 237 gr.representacion_final_algoritmos(flags, variables, my_tplot, setup) 238 239 # Tiempo total de ejecución 68 Apéndice A. Código correspondiente al script usado para obtener las figuras de la Sección 7.2 240 elapsed=time.time()-expend 241 print("El tiempo es: " +str(elapsed)) Índice de Figuras 1.1 Crecimiento del ML (azul) y Big Data (rojo) en los últimos años [13] 2 2.1 Importancia por sector industrial [25] 6 2.2 Importancia por función [25] 6 3.1 Obtención de muestras para función a priori (Ecuación (3.24)) 13 3.2 Obtención de muestras para función a posteriori (Ecuación (3.22)) 14 4.1 Escenario de aplicación del algoritmo 20 4.2 Nivel de potencia respecto a la distancia 22 4.3 Porcentaje de error en la potencia 23 5.1 Simulación para factor de escala igual a 0.5 33 5.2 Simulación para factor de escala igual a 5 33 5.3 Simulación para factor de escala óptimo 34 5.4 Selección del entorno virtual deseado 34 7.1 Variación de campo recibido respecto a la distancia 54 7.2 Campo recibido a lo largo de todo el escenario (x0= [0 0]) 55 7.3 Campo recibido a lo largo de todo el escenario (x0= [−150 −150]) 56 7.4 Error cuadrático medio del campo estimado para distintos valores de varianza de shadowing 56 7.5 Error cuadrático medio del campo estimado para distintos valores de varianza de shadowing y campo variante en el tiempo 58 7.6 Comparación de resultados respecto a la simulación con inducing inputs 59 7.7 Variación de la potencia transmitida a lo largo del tiempo 60 69 Índice de Tablas 4.1 Definción de parámetros de Ecuación (4.1) 21 5.1 Valores obtenidos tras optimización de hiperparámetros 32 6.1 Banderas usadas en el código 40 6.2 Parámetros constantes a lo largo de la ejecución del código 41 6.3 Asociación parámetro-variable en Ecuación (4.32) 48 7.1 Estimación de posición del transmisor para distintas casos 53 7.2 Estimación de potencia transmitida y exponente de pérdidas para distintas simulaciones 54 7.3 Valores de bandera para simulación en situación de campo estático 57 71