scieee AI-readable full text Open interactive document viewer

Automatización de diagnósticos mediante el uso de técnicas de Machine Learning

Sánchez Sánchez, Esdras

Abstract

El avance de los estudios realizados en el campo de la Inteligencia Artificial, así como su implementación directa en la industria está suponiendo un cambio inminente. En la industria aeronáutica la seguridad es un pilar fundamental. Los accidentes aéreos se producen debido tanto al factor humano como al fallo de la maquinaria. Aquí donde el Machine Learning tiene la oportunidad de detectar estos errores y mitigarlos. Algunas de las aplicaciones pueden ser usadas para predecir el mantenimiento de ciertas partes del avión, otras para liberar de carga de trabajo al piloto a la hora de tomar decisiones en situaciones de elevado estrés mediante la indicación por parte de la máquina de la acción más favorable que debe realizar. Mediante el empleo de estas técnicas se puede reducir potencialmente el número de accidentes. En una situación similar a la del piloto se encuentra la tarea de un médico, que también se encarga de proteger y salvar vidas, y para ello la toma de decisiones es fundamental. La motivación del presente trabajo es abordar problemas cercanos a las personas, del día a día. Esto se llevará a cabo mediante el empleo de técnicas de aprendizaje automático, también conocido como Machine Learning.

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 Grado Grado en Ingeniería Aeroespacial Automatización de diagnósticos mediante el uso de técnicas de Machine Learning Autor: Esdras Sánchez Sánchez Tutor: María Ángeles Martín Prats Dpto.Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 Trabajo Fin de Grado Grado en Ingeniería Aeroespacial Automatización de diagnósticos mediante el uso de técnicas de Machine Learning Autor: Esdras Sánchez Sánchez Tutor: María Ángeles Martín Prats Profesor Titular Dpto.Ingeniería Electrónica Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 Trabajo Fin de Grado: Automatización de diagnósticos mediante el uso de técnicas de Machine Learning Autor: Esdras Sánchez Sánchez Tutor: María Ángeles Martín Prats 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 Amis padres, por ser mi pilar incondicional, mi apoyo día tras día y transmitirme siempre felicidad. Por enseñarme valores tan importantes como el respeto, la solidaridad, la constancia y el trabajo. Sois mi ejemplo a seguir. A mi hermana, por ser una persona extraordinaria en todos los sentidos. Sigue siendo como eres porque vas a conseguir todo lo que te propongas. A Carmen, por haberte cruzado en el camino durante esta aventura y llenarme de alegría día tras día. Esto es solo el comienzo de todo lo que nos espera. A mi familia y amigos, muchas gracias. Al grupo docente de la Universidad y en especial a mi tutora María Ángeles, por haberme abierto los ojos y ayudarme a descubrir mi pasión. Muchas gracias por todo el tiempo y esfuerzo que ha dedicado ha sido un placer trabajar con usted durante este tiempo. I Resumen El avance de los estudios realizados en el campo de la Inteligencia Artificial, así como su implementación directa en la industria está suponiendo un cambio inminente. En la industria aeronáutica la seguridad es un pilar fundamental. Los accidentes aéreos se producen debido tanto al factor humano como al fallo de la maquinaria. Aquí donde el Machine Learning tiene la oportunidad de detectar estos errores y mitigarlos. Algunas de las aplicaciones pueden ser usadas para predecir el mantenimiento de ciertas partes del avión, otras para liberar de carga de trabajo al piloto a la hora de tomar decisiones en situaciones de elevado estrés mediante la indicación por parte de la máquina de la acción más favorable que debe realizar. Mediante el empleo de estas técnicas se puede reducir potencialmente el número de accidentes. En una situación similar a la del piloto se encuentra la tarea de un médico, que también se encarga de proteger y salvar vidas, y para ello la toma de decisiones es fundamental. La motivación del presente trabajo es abordar problemas cercanos a las personas, del día a día. Esto se llevará a cabo mediante el empleo de técnicas de aprendizaje automático, también conocido como Machine Learning. III Índice de Figuras 3.1 Modelo de regresión lineal [8] 6 3.2 Visualización de errores regresión lineal [5] 7 3.3 Regresión logística para determinar la probabilidad de aprobar un examen en función de las horas de estudio [9] 8 3.4 Ejemplo Support Vector Machine lineal [10] 9 3.5 Estructura árbol de decisión [19] 10 3.6 KNN para clasificación [7] 11 3.7 Método del codo. Optimización del número de clusters [25] 13 3.8 Situación de la red neuronal [13] 14 3.9 Arquitectura red neuronal [4] 15 3.10 Función de activación escalón [18] 16 3.11 Función de activación sigmoidea [18] 17 3.12 Función de activación rectificador [18] 17 3.13 Función de activación tangente hiperbólica [18] 18 3.14 Reducción del valor de la función de coste tras realizar iteraciones [28] 19 3.15 MaxPooling [1] 20 3.16 Arquitectura de la red neuronal convolucional [27] 21 3.17 Ejemplo matriz de confusión [17] 22 3.18 Ejemplos curvas ROC [32] 24 5.1 Representación gráfica de distintos pacientes y la correspondiente clasificación en cada grupo 33 5.2 Distribución resultados de evaluación 36 5.3 Previsualización del dataset tras la carga de datos 37 5.4 Características variables de entrada para cáncer benignos 37 5.5 Características variables de entrada para cáncer malignos 38 5.6 Explicación visual del gráfico de cajas 38 5.7 Gráfico de cajas para las variables del problema 38 5.8 Matriz de correlación de las variables 39 5.9 División en conjunto de entrenamiento y testing 40 5.10 Carga de las librerías usadas para entrenar el modelo 40 5.11 Análisis de resultados 40 5.12 Visualización de imágenes I 42 5.13 Visualización de imágenes II 42 5.14 Determinación variables nulas 43 5.15 Estudio de imágenes duplicadas 43 5.16 Distribución de casos según problema cutáneo 44 5.17 Código de escalado de las muestras 45 5.18 Muestras escaladas 45 5.19 Arquitectura red neuronal 46 5.20 Arquitectura red neuronal II 46 XI XII Índice de Figuras 5.21 Resumen red neuronal 47 5.22 Evolución de la exactitud de la red neuronal a medida que aumenta el número de epochs 47 5.23 Evolución del error de la red neuronal a medida que aumenta el número de epochs 48 5.24 Matriz de confusión 48 5.25 Matriz de confusión incorrecta 49 5.26 Respuesta de la aplicación 50 5.27 Respuesta de la aplicación 50 5.28 Escalado de las imágenes 51 5.29 Evolución de la exactitud de la red neuronal a medida que aumenta el número de epochs. Caso mejorado 52 5.30 Evolución del error de la red neuronal a medida que aumenta el número de epochs. Caso mejorado 52 5.31 Matriz de confusión 53 Notación ML Machine Learning IA Inteligencia Artificial DL Deep Learning SV Ms Support Vector Machines SVC Support Vector Classifier SV R Support Vector Regression KNN K-Nearest-Neighbor, K-Vecinos más cercanos RNA Red Neuronal Artificial RNC Red Neuronal Convolucional TP True Positive, Verdadero positivo TN True Negative, Verdadero negativo FP False Positive, Falso positivo FN False Negative, Falso negativo XIII 1 Introducción La necesidad de automatización de procesos, de asistentes para la toma de decisiones y de proporcionar predicciones de distintos problemas son las bases sobre las que se sustenta el presente trabajo. Cada vez más, aparece la necesidad de disminuir el número de fallos de sistemas y el factor humano, y es por ello que la detección de estos errores con la suficiente antelación supone una gran ventaja en todos los sentidos; tanto económico, de seguridad como por supuesto de salud. Esto se lleva a cabo con el famoso "Big Data" y la Inteligencia Artificial. Se comenzará con el estudio del estado del arte de la Inteligencia Artificial, más concretamente de la rama de Machine Learning. Dentro del apartado se hablará de cómo estas tecnologías están aplicándose en la industria aeronáutica y se comentarán alguno de sus ejemplos. El siguiente punto será el estado del arte en el ámbito de la medicina. Se tratarán ambos sectores debido a que son dos de los que tienen un contacto más cercano con la vida de personas y el factor humano juega un papel muy relevante. Posteriormente se hablará del Machine Learning y se explicarán las técnicas que se usan para resolver este tipo de problemas. Se dividirá el estudio en algoritmos de aprendizaje supervisado [ 24 ] y no supervisado, y el primero se dividirá en algoritmos de regresión y de clasificación. Dentro de este apartado también se hablará del Deep Learning o Aprendizaje profundo [ 23 ] que son algoritmos que simulan el funcionamiento del cerebro humano. Seguidamente se explicará cómo aplicar la teoría mediante el uso del lenguaje de programación Python explicando cuáles son las librerías necesarias para resolver estos problemas. Para poner estos conocimientos en práctica, se han tenido que realizar búsquedas de datos y pese a hacerlo en primera instancia con bases de datos del sector aeronáutico, no se ha podido encontrar nada que fuese fiable. Esto se debe principalmente a que la mayoría de empresas del sector aún están comenzando a aplicar este tipo de tecnologías y no tienen una cantidad de datos suficientes o si alguna ya lo tiene, no está disponible. Otra opción que se planteó fue hacer uso de algún simulador de vuelo, pero finalmente se concluyó que esto no era una buena opción debido a la inexperiencia para usar el software. La consecuencia que esto tendría es que no se podría simular lo que un piloto haría en distintas situaciones y lo que interesa es obtener datos de pilotos experimentados para que así la máquina aprenda de las distintas situaciones que ocurren durante un vuelo y cómo actúa el piloto. Por lo que si lo hace una persona sin experiencia el avión no volará de forma correcta y por tanto no serían válidos los datos obtenidos. Aunque la metodología que se va a emplear es aplicable en cualquier sector (ya que se trata de aplicar algoritmia a un conjunto de datos), debido a la estrecha relación que guardan los problemas del sector sanitario con aviación en la toma de decisiones en situaciones con elevado estrés, y debido a que se han encontrado datos de mayor veracidad, se ha decidido que los casos prácticos estén orientados a la salud. El primero ellos se tratará de un proceso de clasificación de pacientes según el estado de gravedad tras sufrir una amputación, para que de esta forma se pueda aplicar el protocolo de asistencia que más favorezca a su estado de salud. Seguidamente se determinará la probabilidad que un paciente con unas determinadas características padezca o no cáncer de mama. Como último caso, se estudiará el análisis de lesiones cutáneas mediante el empleo de técnicas de tratamiento de imágenes. Para finalizar, se analizarán las distintas conclusiones obtenidas a lo largo del trabajo, así como las líneas futuras en las que se podría continuar trabajando. 1 2 Estado del Arte Inteligencia Artificial La inteligencia artificial definida como la inteligencia de las máquinas, está siendo el pilar fundamental del progreso tecnológico de la industria e incluso de nuestro día a día, y esto viene impulsado por un uso eficiente de los datos. Además, a día de hoy no es necesario almacenar estos datos en un lugar físico debido al avance en las tecnologías cloud que permiten acelerar la evolución tecnológica. El objetivo principal que tiene esta Ciencia del Dato es a partir de algoritmos poder tomar decisiones, lo que se podría llamar ciencia de decisión. A continuación, se hablará de dos industrias en las que estas técnicas están presentes. 2.1 Industria Aeroespacial La aplicación de técnicas de inteligencia artificial en el sector aeroespacial es algo inminente pese a que como anteriormente se ha comentado, las empresas lo están llevando a cabo desde hace muy poco tiempo. Todos los sensores que tiene cada avión generan una gran cantidad de datos por segundo lo cual permite generar una gran base de datos para posteriormente utilizarla aplicando algoritmos predictivos. Con esta información se podría determinar con una alta precisión el momento en el que un sensor dejase de funcionar. Otro objetivo fundamental que tendrían estas técnicas, sería la determinación de mantenimiento de distintos sistemas, subsistemas o elementos. De esta manera se reducirían los costes ya que se tendría conocimiento de la probabilidad que tiene un determinado sistema de fallar y permitiría a los operarios actuar en consecuencia. Empresas como Rolls Royce [ 26 ] utilizan este tipo de técnicas para aprovechar los datos que genera el motor en funcionamiento para que si en algún momento se detecta algo que está fuera de lo común, se pueda actuar con la mayor rapidez posible. Otro ejemplo sin duda muy relacionado con lo que posteriormente se verá en el caso de medicina, es la capacidad de eliminar situaciones que puedan suponer al piloto un elevado estrés. Igual en un futuro se verán aviones volando sin piloto ya que será todo manejado por un supercomputador, pero hasta que llegue ese momento (si finalmente ocurre), se tiene que buscar una solución al problema de que una gran parte de los accidentes se deben al fallo humano. Esto puede ser debido a que psicológicamente haya días en los que no se realice el checklist por completo, o que no se tengan los mismos reflejos, y es por eso que un gran aporte sería la implementación de un asistente que permitiese eliminar esta carga cognitiva al piloto para facilitar así su labor. Un ejemplo de este tipo de proyecto es Harvis, en el cual participa la empresa sevillana Skylife Engineering [ 30 ]. Este proyecto europeo consiste en establecer un "single pilot", es decir, que en la cabina haya un único piloto y una computadora que mediante el aprendizaje a través de numerosos vuelos, aprendiendo de las acciones que realza el piloto, pueda asistir definiendo cuál es la acción más favorable a realizar. En definitiva, se trata de un asistente que ha aprendido lo que un piloto hace en las distintas fases de un vuelo gracias a que ha sido entrenado por pilotos con gran experiencia, y de esta forma en cualquier situación podrá dar indicaciones acerca de la tarea que se tiene que realizar. Otra aplicación que tendrá un gran uso en el futuro debido al aumento en el número de vuelos que se tiene previsto, será la optimización de las trayectorias [ 11 ]. Esto es de vital importancia para los momentos en los que haya una elevada congestión del tráfico ya que el algoritmo optimizará la ruta de los distintos vehículos evitando posibles accidentes. 3 4Capítulo 2. Estado del Arte Inteligencia Artificial 2.2 Medicina En el caso de Medicina la mayor aplicación que tiene es en medicina predictiva. Para que se pueda predecir si un paciente con ciertas características tiene una determinada enfermedad, es necesario contar con un gran volumen de datos de registros que se tengan de pacientes previos de los cuales se conozcan una serie de características y se haya obtenido un diagnóstico en función de estas entradas. Para que esto sea posible es fundamental llevar a cabo un proceso de digitalización. De esta manera, el hospital o centro de salud tendrá registrado a todos los pacientes de modo que estén presentes en formato digital y así el sistema pueda alimentarse de esta información y poder llevar a cabo un algoritmo predictivo que sea eficaz. En definitiva, la máquina aprenderá de los diagnósticos que hacen los médicos para que cuando se hayan registrado una cantidad suficiente de pacientes, el algoritmo actúe con una tasa de acierto elevada o lo que es lo mismo, que tome la misma decisión que hubiese tomado un especialista. En este trabajo se presentarán una serie de casos en los que esto se pone en práctica. Un punto muy positivo es que dado que el algoritmo lo que lee son características de los pacientes (bien sean numéricas o imágenes), se podrá adelantar a la aparición de esa enfermedad y así actuar de manera que, al hacerlo previo a la aparición de forma grave del problema, la recuperación sea más rápida y el paciente corra el menor riesgo posible. Otro punto a favor de esto es para aquellos médicos que hayan terminado sus estudios y comiencen a trabajar. La experiencia que el algoritmo tiene tras miles o decenas de miles de pacientes (cuantos más mejor) ayudarán en cuanto a la toma de decisión de un diagnóstico más certero y un tratamiento correcto. Se ha hablado ya de prevención de enfermedades, lo cual es muy interesante por las razones que se han expuesto. Otra aplicación que tiene la inteligencia artificial en medicina es la asignación de un tratamiento a un paciente [ 20 ]. Un paciente con unos determinados síntomas tendrá que ser recetado con una medicación. Si se tuviese el registro de los pacientes a los que se les ha recetado una medicación dada una serie de características presentadas, se almacenase haciendo uso de las tecnologías Big Data y se aplicase el algoritmo predictivo de Machine Learning más adecuado, se conocería el medicamento que el paciente necesita, así como las dosis que serían adecuadas. Se trataría de un proceso de automatización y toma de decisiones que ayudaría a trabajar a los médicos. Todo esto concluye a que se prevé un futuro en el que el objetivo será desarrollar aplicaciones centradas en la salud del paciente y poder así tener una atención médica más personalizada y efectiva. El objetivo de la medicina de precisión [ 22 ] es seleccionar tratamientos que tengan más probabilidad de ayudar a pacientes de acuerdo a su genética. Esto se conoce también como medicina personalizada. El problema que existe a día de hoy es que una persona a la que se le diagnostica un cáncer, es tratada del mismo modo que otra persona que presenta el mismo tipo y estadio de cáncer. Esto es un problema debido a que cada individuo responde de forma diferente. Los pacientes presentan variaciones genéticos que hace que la respuesta al tratamiento sea distinta. El objetivo principal de la medicina de precisión es que con las pruebas genéticas que se realicen y mediante un algoritmo predictivo, se pueda determinar qué tratamiento es el que tiene una mayor probabilidad de curar un tumor. 3 Machine Learning Se define la modelización predictiva como un conjunto de algoritmos de la rama de la estadística que cuando se aplican a datos históricos es capaz de devolver una función matemática que tiene que ser útil para resolver un determinado problema [ 12 ]. En definitiva, se busca predecir un resultado basándose en una serie de parámetros de entrada sobre los que nuestro modelo opera y predice de modo que en el futuro cuando se tengan nuevos datos de entrada, la salida del algoritmo permita tomar decisiones. La estadística juega un papel muy relevante; dice el volumen de los datos, cómo están distribuidos (si hay un valor central o si en cambio los datos están dispersos), si existe correlación entre variables o si son independientes. En general la estadística ayuda a responder a estas y muchas más cuestiones. Los algoritmos generarán ecuaciones matemáticas basados en datos históricos que ayudarán a predecir datos a posteriori. Se pueden clasificar en dos grandes grupos. 3.1 Algoritmos de aprendizaje supervisado Los algoritmos de aprendizaje supervisado trabajan con datos etiquetados, intentando encontrar una función que, dadas las variables de entrada les asignen la etiqueta de salida adecuada. Dicho algoritmo se entrena con un "histórico" de datos y así "aprende" a asignar la etiqueta de salida adecuada a un nuevo valor, es decir, predice el valor de salida. De los algoritmos que se verán a continuación, algunos se usarán para clasificación, otros para regresión y algunos para ambos. En los problemas de clasificación se tratará de asignar la nueva muestra en una clase. Por ejemplo, un reloj inteligente cuando clasifica la actividad que la persona está realizando tendría que escoger entre andar, correr, montar en bicicleta... Otro ejemplo podría ser si la acción de una determinada empresa subirá o no. Por otro lado, en los algoritmos de regresión la salida es un valor numérico. Algunos ejemplos podrían ser en cuánto está valorada una propiedad, determinar el número de ventas que una panadería va a tener en un día o el tiempo que un cliente va a permanecer en una empresa, son algunas de las aplicaciones que tienen estos algoritmos. •Regresión: Regresión Lineal, SVMs, Árbol de decisión, Redes neuronales. •Clasificación: Regresión Logística, SVMs, Árbol de decisión, Redes neuronales. 5 12 Capítulo 3. Machine Learning 3.2 Algoritmos de aprendizaje no supervisado Estos algoritmos trabajan sin variables de salida de los datos históricos. El aprendizaje no supervisado tiene lugar cuando no se dispone de datos "etiquetados" para el entrenamiento. Sólo se conocen los datos de entrada, pero no existen datos de salida que correspondan a un determinado input. Por tanto, sólo se puede describir la estructura de los datos para tratar así de encontrar algún tipo de organización que simplifique el análisis. Por ello, tienen un carácter exploratorio. 3.2.1 Clustering Es un algoritmo que categoriza las entradas del dataset en clusters o segmentos donde las entradas que pertenecen a un mismo cluster son similares. En definitiva: • Se busca agrupar los datos que presenten semejanzas entre los miembros del cluster (que sean parecidos). • Los datos que pertenezcan a grupos diferentes, deben tener rasgos suficientemente diferentes entre sí. Por ejemplo, a la hora de realizar campañas de marketing, si se tienen distintos cluster o grupos de clientes identificados se podrá realizar una campaña específica para cada uno de ellos. Existen diversos tipos de segmentación, y para ello se verán a continuación distintos modelos utilizados para medir la similitud y diferencias. Distancia Euclídea Como se ha dicho anteriormente, es fundamental conocer la similitud que hay entre los puntos de modo que esto permita clasificar el nuevo dato en un determinado grupo. Para poder realizar esta medición, se hace uso de la distancia y aunque hay distintas formas de medirla, se va a explicar la distancia euclídea. Siendo x las variables de entrada de cada punto de cada set, se define la distancia entre un punto y otro como sigue: D(xi,xj) = q(xi1−xj1)2+(xi2−xj2)2+... +(xin −xjn)2=sn ∑ k=1 (xik −xjk)2(3.15) Como se puede observar, nes el número de columnas del data set. Clustering K-Means Este algoritmo no supervisado [ 6 ] permite dividir un número de observaciones en determinados grupos. En principio, el número de grupos "k" será conocido, pero también se verá que existe una manera de optimizar el número de clusters o grupos que se conoce como el método del codo. Se definen los centroides del cluster o grupo como el punto medio de la nube de puntos que lo define. Con respecto a este punto se medirá la distancia. El proceso que llevará a cabo el modelo es el siguiente: SSw(Cj) = ∑ x∈Cj (x−cj)2(3.16) Una vez se incluye un nuevo punto al cluster, hay que volver a calcular el centroide debido a que el "centro de masas" habrá variado. Para ello se aplica lo siguiente: Se SW= k ∑ j=1 SSW(Cj) ∑n i=1(xi−x)2(3.17) Se repetirán sucesivamente estos dos últimos pasos hasta que ya no se pueda variar el centroide. El objetivo es reducir la distancia intracluster SSW. La ecuación por tanto a minimizar será como sigue: SSW(k) = k ∑ j=1 SSw(Cj) = k ∑ j=1 ∑ x∈Cj (x−cj)2(3.18) Donde como se ha dicho antes: •k : número de clusters. •xi: muestra i-ésima. 3.2 Algoritmos de aprendizaje no supervisado 13 •cj: centroide del cluster j-ésimo. A continuación, se va a hablar de cómo encontrar el valor óptimo de k , que es una de las partes más difíciles a la hora de elaborar un algoritmo por K-Means. A continuación, se presentará el método del codo . Figura 3.7 Método del codo. Optimización del número de clusters [25]. Es evidente que al aumentar el número de clusters, la distancia intra-cluster disminuirá paulatinamente. El caso extremo sería que se tuvieran tantos clusters como puntos en el dataset y por tanto la distancia sería nula. Esta técnica se denomina método del codo debido a que en casi todos los casos suele haber una variación máxima donde se observa que la curva tras ese punto decrece más lentamente que en los puntos anteriores y prácticamente se estabiliza la curva. En el caso de la imagen el punto en el que esto ocurre es en k=3 . En consecuencia, ese punto sería el que marcaría el número de clusters que se debería tomar. 14 Capítulo 3. Machine Learning 3.3 Deep Learning El pionero del aprendizaje profundo o red neuronal es Geoffrey Hinton. Fue el que comenzó a estudiar esta rama del Machine Learning y actualmente se encuentra trabajando en el departamento de Inteligencia Artificial de Google. Mucha de la información que se encontrará en adelante se fundamenta en estudios que realizó Geoffrey y se pueden consultar en sus papers. Figura 3.8 Situación de la red neuronal [13]. Se puede observar en la imagen anterior cómo el Deep Learning es una rama del Machine Learning, y éste a su vez una rama de la Inteligencia Artificial. La principal diferencia que existe entre los algoritmos de Machine Learning y Deep Learning es que estos últimos detectan por sí mismos las distintas características de los datos. En aquellos problemas de clasificación de imágenes, las redes neuronales son capaces de determinar cuáles son los rasgos más característicos que les permitirán realizar una clasificación con un elevado porcentaje de acierto. En cambio, al algoritmo de Machine Learning se le tendría que decir cuáles son estas características. Por ejemplo, en el caso de un vehículo, se le tendría que decir que tiene ruedas, puertas, espejos... Y sin embargo la red neuronal lo detectaría sin necesidad de que se le indicase. Si fuese un problema con variables numéricas o categóricas, la red neuronal se encargaría de dar más o menos importancia a las variables (variando su peso) para así obtener el mejor modelo. La idea detrás del aprendizaje profundo es simular al cerebro humano y hacer uso de la neurociencia para establecer dichas leyes que rigen dicho funcionamiento. La tendencia que tienen las neuronas en el cerebro humano es conectarse entre ellas, ya que por sí mismas no tienen utilidad. En un cerebro humano existen alrededor de 100.000 millones de neuronas juntas. 3.3 Deep Learning 15 La arquitectura típica de red neuronal es como sigue: Figura 3.9 Arquitectura red neuronal [4]. •Capa de entrada: son los inputs o variables de entrada. •Salida: es la predicción que se quiere realizar. • Capas ocultas: nodos intermedios que son las neuronas que conecta y transmite la información de la entrada a la salida. Puede haber más de una capa oculta. Aquí es donde se realiza el aprendizaje. 16 Capítulo 3. Machine Learning 3.3.1 RNA: Red Neuronal Artificial Ya se ha definido anteriormente la arquitectura de la red neuronal. Ahora se va a proceder a explicar la red neuronal artificial, la cual es un algoritmo de Machine Learning supervisado. Un detalle a tener en cuenta es que, en la capa de entrada, los distintos inputs que se tengan deben estar todos en el mismo rango para que el algoritmo no tenga preferencia por ninguna de estas variables. Esto se puede llevar a cabo mediante la estandarización. El valor de salida puede ser tanto un valor continuo como un valor categórico dependiendo del problema que se esté estudiando. En el caso de que sea categórico, se tendrán distintos valores de salida y cada uno de ellos será la categoría que se está tratando de asignar. •Primer paso : la neurona va a ponderar cada variable de entrada mediante la aplicación de distintos pesos a cada una de ellas: m ∑ i=1 wixi(3.19) La red neuronal aprenderá ajustando los distintos pesos. •Segundo paso : una vez se tenga la suma ponderada se aplicará una función de activación que servirá para saber si la información de esa neurona se tiene que transmitir o en su defecto (al no ser muy buena), que esta información no se transmita a la siguiente capa. Dependerá en algunos casos de la función de activación si la neurona transmite o no dicha información. •Tercer paso: la transmisión de dicha información. El poder que tiene la red neuronal es que cada neurona entenderá los datos a su modo. La sinapsis, que es la línea que unen datos con neuronas, permite transmitir la información que realmente interese a la neurona. La función de activación La función de activación decide si la información obtenida por la neurona tras realizar la ponderación tiene que ser transmitida o no. Existen distintas funciones de activación y a continuación se hablará de cuatro de ellas. Función escalón La función escalón crea un salto en torno al valor 0 de forma que si al hacer el sumatorio de la multiplicación de los pesos de la red neuronal por cada una de las variables sale negativo, la función de activación tomará el valor nulo. En cambio, si el sumatorio es positivo, la función escalón tomará el valor unitario. Figura 3.10 Función de activación escalón [18]. Función sigmoide La función que define dicha activación viene dada como sigue: φ(x) = 1 1+e−x(3.20) x= m ∑ i=1 wixi(3.21) 3.3 Deep Learning 17 Se puede observar que para el valor del sumatorio nulo, la función de activación toma el valor φ=0.5 . Con esta función se puede definir la probabilidad que tiene una neurona de activarse. Además, la fórmula es igual que la de la regresión logística. Figura 3.11 Función de activación sigmoidea [18]. Función rectificadora En el rectificador lineal unitario (RELU). Se puede observar que la mitad de la función es totalmente nula mientras que la otra mitad crece de manera lineal. Es una de las funciones más populares para redes neuronales artificiales ya que al igual que ocurría en la función escalón, todo aquello que sea negativo lo convierte en nulo. Por otro lado, todo lo positivo se queda tal cual queda el resultado de la ponderación, y esa es la razón por la cual el valor de φvaría entre el valor nulo y el máximo de ∑m i=1wixi. Figura 3.12 Función de activación rectificador [18]. 18 Capítulo 3. Machine Learning Función tangente hiperbólica Tiene una forma muy similar a la sigmoidea pero esta función comienza en −1 y llega hasta el valor positivo unitario. Figura 3.13 Función de activación tangente hiperbólica [18]. Función softmax La función softmax también conocida como la función exponencial normalizada, es una generalización de la función logística usada para múltiples dimensiones. Se utiliza normalmente como la última función de activación en una red neuronal para así normalizar la salida de la red para que se obtenga la distribución de probabilidad. De esta forma la salida de esta función estará siempre dentro del intervalo (0,1) . Se define de la siguiente forma: σ(z)i=ezi ∑K j=1ezj(3.22) Se da para i=1,...,Kyz= (z1,...,zK)en el intervalo ∈RK Cabe destacar también que cada neurona puede tener una función de activación diferente y de esta forma filtrar la información a su manera. Es bastante usual utilizar en la capa de salida la función sigmoidea debido a que como se ha explicado anteriormente, esta función permitiría conocer qué tan probable es que la salida pertenezca a una u otra clase o qué tan probable es que la salida tome un determinado valor. Método de aprendizaje de las redes neuronales Una vez ejecutada la red neuronal y obtenido el valor de salida, ˆy se comparará con el resultado real y . Se define la función de costes como sigue: C=1 2(ˆy−y)2(3.23) El objetivo será minimizar dicha función de costes. Para conseguirlo, lo único que la red neuronal puede hacer es variar el valor de los pesos que multiplica a cada variable. Se trata de un trabajo de ida y vuelta constante corrigiendo los pesos. 3.3 Deep Learning 19 Gradiente descendente Ya se ha adelantado anteriormente que el objetivo que tiene toda red neuronal es disminuir el valor de la función de costes. Es por ello que se va a hablar ahora del gradiente descendente. Lo primero y más importante, para que la solución converja, la función de costes tiene que ser convexa. Se busca el mínimo global de la función. Figura 3.14 Reducción del valor de la función de coste tras realizar iteraciones [28]. El gradiente se define como la tangente a la curva y se calcula mediante la derivada. Si la pendiente es nula se estaría en el mínimo, luego ya habría convergido el algoritmo. En aquellas situaciones en las que la función de costes no sea convexa y existan fluctuaciones es más aconsejable hacer uso del gradiente estocástico. En este caso se busca el mínimo de la función de costes, pero no necesariamente será el mínimo global. Entrenamiento Red Neuronal Artificial •Paso 1: inicializar los pesos de las variables de entrada de forma aleatoria con valores próximos a 0. •Paso 2 : introducir el primer punto del dataset en la capa de entrada. Como se ha dicho anteriormente, cada nodo de entrada es una de las columnas del dataset. •Paso 3 : se propaga de izquierda a derecha. Las neuronas se irán activando de acuerdo a las funciones de activación y se obtendrá la predicción. •Paso 4: se compara la predicción obtenida con el resultado real. Se mide el error. •Paso 5: se propaga el error hacia atrás para que de esta forma se puedan actualizar los pesos. •Paso 6 : se repiten los pasos del 1 a 5 para cada una de las observaciones del dataset y se actualizan los pesos. •Paso 7 : una vez se ha barrido todo el dataset, se vuelve a repetir el proceso el número de veces que más interese mediante la variación del número de epochs. 20 Capítulo 3. Machine Learning 3.3.2 Red Neuronal Convolucional Los algoritmos de redes neuronales de convolución [ 2 ] son los utilizados por excelencia para el tratamiento de imágenes ya que son capaces de identificar las características más importantes que la definen sin necesidad de que se indique. Se suministrará una imagen y el algoritmo dará la salida que nos indique a qué categoría pertenece la imagen. La red neuronal convolucional tratará de obtener rasgos de las imágenes. Un ejemplo muy sencillo sería enviar imágenes categorizadas como gatos y perros de tal manera que cada imagen tiene una etiqueta asignada. Tras tratar con gran cantidad de ejemplos de cada una de estas clases, la RNC habrá identificado los rasgos más característicos de cada una de las dos especies de modo que cuando se le pase una nueva imagen ya sea de un perro o de un gato, ésta sea capaz de clasificarla correctamente. Lo primero que hay que realizar antes de suministrar datos a la red, es normalizar los valores. Los píxeles toman valores de 0 a 255 por lo que se transformará cada pixel dividiendo el valor de cada uno entre 255 y de esta forma se tendrá todo entre 0 y 1 . Si la imagen estuviese en blanco y negro habría dos canales, y si es a color habría tres canales rojo, verde y azul. A continuación, se explican los pasos que se siguen para construir la red neuronal convolucional: •Paso 1: Convolución: en este paso se llevan a cabo las convoluciones. Se trata de seleccionar grupos de píxeles de la imagen de entrada y realizar productos escalares con una matriz que es el llamado kernel. Dicho kernel recorre todas las neuronas de entrada y genera una nueva matriz a la salida que será la nueva capa de neuronas. Realmente se aplican más de un kernel, es decir se tendrán un conjunto de filtros en cada capa. Se tendrán entonces tantas matrices como filtros haya. Por lo tanto, el número de neuronas por cada capa vendrá dado por el número de kernels multiplicado por la dimensión de la imagen (si es 28x28, el número de kernels multiplicado por 784). En definitiva, estos filtros lo que buscan es identificar características de la imagen original. Se aplica ahora la función de activación, normalmente se utiliza para estas capas el rectificador lineal unitario. •Paso 2: Max Pooling: se encarga de reducir la dimensión del problema. Tomando las matrices definidas anteriormente por los filtros, reducen su tamaño. Por ejemplo, si se tiene un Max Pooling de 2x2 , se seleccionan 4 pixeles de la imagen y solamente se pone el que tiene el valor más alto. Se reduce mucho el número de neuronas y se supone que se sigue almacenando la información que define las características de las imágenes. Figura 3.15 MaxPooling [1]. Este proceso se aplicará tantas veces como capas se quieran. •Paso 3: Flattening: tras haber realizado las distintas fases de Max Pooling, para unirse con la red neuronal se necesita que se tenga como variables de entrada valores escalares. Esta capa se encarga de transformar la última matriz obtenida en el Max Pooling en un vector cuyas componentes serán las entradas en la red neuronal artificial. •Paso 4: Full Connection: entrada de una red neuronal. 3.3 Deep Learning 21 Figura 3.16 Arquitectura de la red neuronal convolucional [27]. 28 Capítulo 4. Machine Learning en Python Esto último es importante debido a que no interesa coger por ejemplo el 80 % primero, sino que es mejor que esté todo mezclado. 4.4.2 Modelos predictivos Como ya se ha introducido anteriormente, en la actualidad Sklearn (Scikit-Learn) es una de las librerías más potentes para Machine Learning. La implementación del algoritmo se realiza una vez se ha separado el modelo con la función anterior. Regresión lineal Para este algoritmo los parámetros que se pueden configurar son los siguientes: • fit _ intercept: True/False. Esto lo que hará será hacer el valor de la constante que traslada la recta nula o distinta de 0. En el caso de que dicha constante fuese nula, la recta pasaría por el origen. •normalize : True/False. Para normalizar o no los datos. Generalmente se normaliza/estandariza antes de llegar a este punto, pero si antes no se ha realizado, se sabe que aquí es posible hacerlo y de esta forma el algoritmo trabajará correctamente. Regresión logística Para este algoritmo los parámetros que se pueden configurar son los siguientes: •fit_intercept: True/False. Al igual que antes. •penalty: sirve como regulador. Tiene los siguientes tipos: – L1: aquellas variables de entrada que no afecten de forma significativa a la salida las toma como nulas, o lo que es lo mismo β=0. – L2: se conoce como Ridge. En este caso en lugar de eliminar las β , las minimiza y así elimina el sobreajuste. – elasticnet: aplica las dos regulaciones citadas anteriormente. Hay que indicar el peso o importancia que se quiere tener de cada una de las dos. •tol : sirve para que una vez se alcanza la tolerancia deseada (convergencia del algoritmo), el programa deje de iterar. Árbol de decisión A modo de ejemplo, se verán los parámetros para la regresión. Para este algoritmo los parámetros que se pueden configurar son los siguientes: •criterion : selección del criterio de división que hace que los datos se dividan de la mejor manera posible. Por defecto está "mse" que es la más importante. "mse" es la media del error cuadrado. Para una versión actualizada de la librería también se encuentra disponible "mae", la media del error absoluto. •splitter : estrategia utilizada para la división en cada nodo. "best" que es la mejor opción y está por defecto y "random" que lo realiza de forma aleatoria. •max depth: la profundidad máxima del árbol. •main samples split Support Vector Machines Como se ha explicado anteriormente, los algoritmos de SVMs son usados para clasificación, regresión y detección de outliers. • Para clasificar se utiliza SVC, Support Vector Classifier. Para poder obtener el algoritmo de SVC primero hay que cargar el de SVM mediante la librería scikit-learn y posteriormente el de SVC. • Para la regresión se utiliza SVR, Support Vector Regression. El método para utilizarlo sería igual que el anterior, es decir, cargar el algoritmo de SVM mediante la librería de scikit-learn y posteriormente cargar SVR. 4.5 Keras 29 4.5 Keras Es la librería [ 21 ] por excelencia que se utiliza para elaborar algoritmos de Deep Learning o aprendizaje profundo. Se utilizarán principalmente los siguientes módulos de la librería: •Sequential: permite que las capas se agrupen de forma secuencial. •Dense: permite conectar las distintas capas de la red neuronal. •SGD: optimizador del algoritmo mediante el gradiente descendente. 5 Casos de estudio Se van a aplicar las técnicas descritas de Machine Learning en Python. Como ya se ha expuesto anteriormente, debido a la falta de datos fiables del sector aeroespacial (aún están comenzando a implementar estas técnicas por lo que no se tienen suficientes datos y las empresas que los tengan no los ceden a terceros), ya que la toma de decisiones de personas clave del sector como es el caso del piloto es muy similar a la de un médico y además hay fuentes fiables de datos, se van a abordar problemas del sector sanitario. Se analizarán tres casos. El primero de ellos se trata de un problema de Machine Learning no supervisado, el segundo un problema de Machine Learning supervisado, y el último se trata de un problema de tratamiento de imágenes en el que se aplican técnicas de Deep Learning. 5.1 Caso I. Clasificación de pacientes con amputaciones traumáticas en distintas clases según su gravedad Se ha realizado el estudio de la agrupación de pacientes con hemorragia externa de distintas clases, ordenadas de menor a mayor gravedad para su posterior tratamiento con un protocolo de actuación previamente definido [16]. Como variables de entrada se han utilizado las siguientes: 5.1.1 Descripción de cada clase Clase I •Estimación de sangre: Hasta 750 ml. •Frecuencia cardiaca: Hasta 100 lpm. •Presión pulsos: Normal. •Relleno capilar: Normal. •Frecuencia respiratoria: entre: 14 rpm y20 rpm. •Diuresis: >30 (ml/h). •Nivel de conciencia: Ansiedad leve. •Coloración piel: Normal. En el programa se introduce un vector cuyas componentes serían las siguientes: Clase I = [0,0,0,0,0,0,0,0](5.1) Clase II •Estimación de sangre: Entre 750 ml y1500 ml. •Frecuencia cardiaca: Entre 100 lpm y120 lpm. •Presión pulsos: Disminuido. •Relleno capilar: Retrasado. 31 32 Capítulo 5. Casos de estudio •Frecuencia respiratoria: entre 20 rpm y30 rpm. •Diuresis: entre: 20 (ml/h) y 30 (ml/h). •Nivel de conciencia: Ansiedad o agresividad. •Coloración piel: Pálida. En el programa se introduce un vector cuyas componentes serían las siguientes: Clase II = [1,1,0,1,1,1,1,1](5.2) Clase III •Estimación de sangre: Entre 1500 ml y2000 ml. •Frecuencia cardiaca: Entre 120 lpm y140 lpm. •Presión pulsos: Disminuido. •Relleno capilar: Retrasado. •Frecuencia respiratoria: entre 30 rpm y35 rpm. •Diuresis: entre: 10 (ml/h) y 20 (ml/h). •Nivel de conciencia: Ansiedad y confusión. •Coloración piel: Pálida. En el programa se introduce un vector cuyas componentes serían las siguientes: Clase III = [2,2,1,1,2,2,2,1](5.3) Clase IV •Estimación de sangre: 2000 ml o más. •Frecuencia cardiaca:140 lpm o más. •Presión pulsos: Disminuido. •Relleno capilar: Retrasado. •Frecuencia respiratoria: más de 35 rpm. •Diuresis: entre: 0(ml/h) y 10 (ml/h). •Nivel de conciencia: Confusión + letargia. •Coloración piel: Grisácea. En el programa se introduce un vector cuyas componentes serían las siguientes: Clase IV = [3,3,1,1,3,3,3,2](5.4) 5.1.2 Estudio del problema Cada clase está determinada por un paciente ideal. Se define el centroide como el paciente ideal de cada clase. La labor que se tiene que realizar es que, tomando los datos anteriores con diferentes sensores, el programa clasifique al nuevo paciente para que ingrese en una clase u otra. Para ello lo que se van a evaluar son las características que tenga el nuevo paciente para así poder compararlas con cada una de las clases y de este modo agruparlo en la que sea más similar. En el problema, se ha definido que la mayoría de las variables son categóricas (cada una tiene una categoría diferente). Esto supondrá tener que afrontar el problema de una forma diferente a si las variables no fuesen clases y fuesen variables continuas. 5.1.3 Modelos predictivos posibles Se han propuesto tres posibles métodos de asignación de pacientes. 5.1 Caso I. Clasificación de pacientes con amputaciones traumáticas en distintas clases según su gravedad 33 Matriz de distancias, K-Means sin variación del centroide Se adjunta una representación gráfica en la que se basará la posterior explicación del problema, Figura 5.1 Representación gráfica de distintos pacientes y la correspondiente clasificación en cada grupo. Como se puede apreciar en la imagen, hay cuatro grupos diferenciados (en este caso estos vienen definidos y no se pueden alterar debido a que para cada uno de ellos hay distintos protocolos de actuación). Como ya se ha dicho, el centroide de cada clase es el paciente ideal. Lo más importante en esta clasificación: • El paciente ideal siempre es el mismo. Se ha considerado que lo más importante es el protocolo médico. • Para medir cuál es el grupo al que pertenece el paciente, se calculará la distancia euclídea que hay a cada paciente ideal y aquella que sea menor, será a la clase a la que pertenezca el paciente evaluado. Si solo se tuviesen dos variables de medición xey, la distancia se obtendría de la siguiente forma: d1=q(x−xclaseI )2+ (y−yclaseI)2 Siendo xeyel valor de la variable que tendría el nuevo paciente. Tampoco se puede determinar la eficacia del modelo empleado ya que no hay valores para validar los resultados obtenidos. Para mejorar el modelo sería conveniente establecer un criterio que permitiese tener unas variables de entrada con mayor peso y de esta forma la distancia estaría ponderada. K-Modes Este método de clasificación se aplica si las variables con las que se trabajan son categorías como ocurre en este caso. Se utiliza un concepto de distancia diferente al anterior. Hay que maximizar la función de similaridad. Esta se define de forma que si una de las variables del nuevo paciente coincide con la del paciente ideal sumaría 1 a dicha distancia. Por lo tanto, cuantas más veces coincida con las variables del paciente ideal mayor será esta función. De esta manera estudiando esta función con respecto a cada una de las clases, aquella que el sumatorio sea mayor, será a la que pertenezca el paciente. Claramente este modelo no es el elegido debido a que: • No se tiene en cuenta el ascenso de gravedad que se tiene en aquellas variables que no se puede agrupar únicamente en dos grupos. Es decir si, por ejemplo, se compara la estimación de sangre perdida, el modelo trataría igual si comparamos con <750ml a cualquier paciente que estuviera fuera de ese rango. El problema que hay, como ya se ha comentado, es que es muy importante tener en cuenta que 34 Capítulo 5. Casos de estudio un paciente de clase IV debe ser tratado diferente que uno de clase II el cual es bastante similar a la primera clase que hemos comentado. • Otro inconveniente sería a la hora de actualizar el paciente ideal debido a que tomará aquel que sea la moda (y no la media como es en el caso de K−Mean). K-Means Al igual que en el caso anterior, para determinar el grupo al que se le asigna un paciente, se tomará la menor de las distancias con respecto a los pacientes ideales. La diferencia que existe es que, es posible que el centro de cada clase varíe. Para poder llevar a cabo este estudio, sin que el paciente tipo sufra mucha variación, ya que podría alterar el protocolo, se ha supuesto que previo al ingreso de nuevos pacientes, habían llegado 100 pacientes ideales de cada una de las clases. De esta forma se consigue que una nueva actualización de un paciente no varía el centro del grupo. Por lo tanto, se ha considerado vital que los pacientes que caracterizan a cada clase no se desplacen de forma muy agresiva. Se va a explicar el procedimiento matemático: • 1) Asignación de cada observación al cluster con la distancia euclídea. Este es el paso que se realiza en el primer método que se ha explicado. • 2) Recalcular el centro de cada clasificación (volver a calcular el nuevo paciente ideal) una vez se ha añadido un nuevo paciente. 5.1.4 Razones de elección del modelo Tras la descripción de cada uno de los modelos, en primera instancia se ha descartado el método de las K−Modes por las razones expuestas. Por lo que queda elegir entre el método de la matriz de distancias y K-Means, poniendo en este último 100 pacientes previos asignados en cada grupo para que el paciente ideal no varíe bruscamente. Ambos procedimientos se consideran válidos y dependerá de la flexibilidad que se tenga para alterar al paciente que define a cada clase ya que igual según el criterio de los médicos, esto es inalterable. 5.1.5 Análisis de resultados Para realizar el estudio pertinente, se ha utilizado Python y las librerías numpy , pandas , kmodes.kmodes y sklearn.cluster. Se han añadido 149 pacientes aleatorios y se ha comparado el método de la Matriz de distancias con el de K-Means. Los resultados han sido los siguientes: •Coincidencias = 138 pacientes asignados al mismo grupo = 92.62 % •Diferencia de 1clase = 8pacientes = 5.37 % •Diferencia de 2clases = 3pacientes = 2.01 % Se puede observar que, como se quería, los centroides apenas han variado y es por ello que ambos métodos han coincidido en la asignación de la gran mayoría de pacientes. A continuación, se adjuntan los 3 pacientes que han tenido una diferencia de dos clases a la hora de clasificarlos. Se usarán estas muestras para que contando con la ayuda de personal médico cualificado, se sepa el grupo al que realmente debería pertenecer. [2,0,1,0,2,1,0,0] •KMeans fijo = Clase I •KMeans = Clase III [0,1,1,0,0,3,0,1] •KMeans fijo = Clase I •KMeans = Clase III [1,1,1,0,0,2,0,1] •KMeans fijo = Clase I •KMeans = Clase III 5.1 Caso I. Clasificación de pacientes con amputaciones traumáticas en distintas clases según su gravedad 35 5.1.6 Usabilidad El método de uso sería evaluar variable a variable al nuevo paciente que se quiera asignar e introducir los valores en el programa. Una vez hecho esto se tendría la clase a la que pertenece y a continuación se actuaría en función del protocolo descrito. 5.1.7 Mejora del modelo Para un primer modelo del algoritmo, se ha tenido en cuenta que todas las variables tienen el mismo peso. Realmente esto no es algo preciso ya que hay ciertas variables que son más críticas y afectan en mayor medida a la agrupación del paciente. La mejora se podría realizar de diversas formas y aquí se plasman dos de ellas: • Acudir a un especialista médico que permita conocer desde su experiencia cuáles son las mediciones a las que se les da más importancia. Incluso puede ser que haya variables que permitan descartar algún grupo. Debido a esto, la experiencia de un profesional es crucial. • Tener un registro de pacientes y conocer en cada caso a qué grupo se le ha asignado. Esto supondría pasar de algoritmos de Machine Learning No Supervisados (como se ha afrontado el problema) a Supervisados. Se podría entrenar un modelo de K-Nearest Neighbours lo cual sería mucho más eficaz. 36 Capítulo 5. Casos de estudio 5.2 Caso II. Determinación lesión cáncer de mama Se ha realizado el estudio de la determinación de la probabilidad que tiene un paciente dado una serie de rasgos, de padecer cáncer de mama benigno o maligno. Para ello se ha empleado el dataset proveniente del Hospital Universitario de Wisconsin proporcionado por el doctor William H. Wolberg. La fecha en la que se hizo público esta base de datos fue el 8 de Enero de 1991 [15]. Se llevó a cabo un registro de 699 pacientes. De cada uno de ellos se tiene la información de las variables que se explican a continuación: •Radio: media de las distancias desde el centro hasta los puntos del perímetro. •Textura: desviación estándar de los valores de la escala de grises. •Perímetro •Área •Suavidad: variación local en longitudes de radio. •Compacidad: permetro2 rea −1 •Puntos cóncavos: número de porciones cóncavas del contorno. •Simetría •Dimensión fractal •Resultado: cáncer benigno o maligno. Se tienen 9 variables de entrada que toman un valor entre el 1−10 ya que los datos vienen escalados. Como variable objetivo o variable a predecir se tiene "Resultado", en la que se registra la decisión que el médico tomó para cada paciente. Debido a esto, se puede concluir que se trata de un problema de Machine Learning Supervisado. En este caso el problema consiste en una clasificación y se tienen dos categorías posibles. 5.2.1 Análisis exploratorio A continuación, se adjunta una imagen donde se puede observar el porcentaje de casos benignos y malignos. Figura 5.2 Distribución resultados de evaluación. Como se puede observar en la imagen anterior, el 65.52 % de los casos tuvieron como resultado benigno, mientras que el 34.48 % restante fueron malignos. Debido a que se examinaron un total de 699 pacientes, se tiene que: •458 pacientes tuvieron cáncer benigno. 5.2 Caso II. Determinación lesión cáncer de mama 37 •241 pacientes tuvieron cáncer maligno. Son cifras que permiten asegurar que se trata de un problema cuyos datos de salida están balanceados ya que no existe una gran diferencia entre las dos clases. A continuación, se adjunta la previsualización que se obtuvo tras haber realizado la carga de datos. Figura 5.3 Previsualización del dataset tras la carga de datos. Se observa que, como se ha dicho anteriormente, se tienen pacientes registrados desde el paciente 0 al 698 quedando un total de 699 pacientes. Otro punto positivo que tiene este dataset es que todas las variables de entrada que se han definido previamente están dentro de un mismo rango de modo que no es necesario estandarizar o normalizar, se podría hacer. De todos modos, se realiza la estandarización de las variables de entrada para que el rango esté entre 0y1. Siguiendo con la etapa del análisis exploratorio de los datos, se adjuntan las principales características que tiene cada una de las variables tanto para el caso de cáncer benigno como maligno. Figura 5.4 Características variables de entrada para cáncer benignos. 44 Capítulo 5. Casos de estudio Como se puede observar, 4501 imágenes están duplicadas, lo que supone el 44.94 % del total del dataset. Una vez se eliminan dichas duplicidades, se pasa a visualizar el número de imágenes que el dataset contiene de cada uno de los grupos. Figura 5.16 Distribución de casos según problema cutáneo. Claramente se trata de un problema no balanceado, •Nevus melanocítico: 4415 imágenes •Enfermedades benignas, Queratosis: 440 imágenes •Melanoma: 230 imágenes •Carcinoma de células basales: 175 imágenes •Queratosis actínica: 151 imágenes •Lesiones vasculares: 64 imágenes •Dermatofibroma: 39 imágenes Cierto es que en las primeras aproximaciones del modelo no se balanceó el problema y como era de esperar no dio un buen resultado. A modo de ejemplo, uno de los problemas más comunes que tienen que estudiar los científicos de datos en el sector bancario es la determinación de transacciones fraudulentas. Si hubiese 1 transacción fraudulenta diaria y 100.000 registradas en un día, si el algoritmo dice que todas son correctas, tendría una exactitud del 99.999 % . ¿Esto querría decir que el modelo funciona correctamente? No, ya que no está resolviendo el problema. Para llevar esta labor a cabo, se utiliza de la librería de sklearn la opción de resample . Se generarán 500 imágenes de cada uno de los casos. Para el Nevus melanocítico de las 4415 imágenes se seleccionarán 500 y del resto lo que se hará será repetirse el número de imágenes hasta llegar a 500 . Este paso es clave para garantizar la eficacia del modelo pese a que se pueda llegar a disminuir la precisión por lo que se ha explicado anteriormente. 5.3 Caso III. Predicción problemas cutáneos 45 Figura 5.17 Código de escalado de las muestras. Quedando como resultado lo siguiente, Figura 5.18 Muestras escaladas. 5.3.2 Entrenamiento del modelo Antes de pasar a comentar la estructura de la red neuronal, lo primero que hay que realizar es definir la X y la salida y . En este caso la X será la información que ofrece la imagen (la cual hay que redimensionar dividiendo el vector entre el máximo de las componentes que es 255 ). La y será la enfermedad que ha tenido el paciente y al tener 7 clases se han generado 7 columnas distintas, las cuales se rellenarán para cada caso con 0 si no es el problema que tiene el paciente, o con 1 si lo es. Se ha utilizado el código to_categorical . Una vez hecho esto, se ha procedido a dividir el conjunto en entrenamiento y testing, mediante la función 46 Capítulo 5. Casos de estudio train_test_split (al igual que en el caso anterior), y esta vez se ha destinado un 75 % de los datos para el conjunto de entrenamiento y el resto para el testing. No hay una regla que marque este porcentaje por lo que se podría variar y probar el que de un mejor resultado. Figura 5.19 Arquitectura red neuronal. • La primera capa de neuronas "Convolucional de 2 Dimensiones" es donde entrarán las imágenes. En esta capa se aplican 256 filtros (kernel) de tamaño 3x3 los cuales detectan ciertas características de la imagen. Como función de activación se utilizará el rectificador lineal unitario. • A continuación se hace un MaxPooling de 2x2 que reduce el tamaño de la imagen que entra a la mitad, manteniendo las características que detectó cada kernel. • Para evitar el overfitting se añade la capa de Dropout. La capa de Dropout consiste en eliminar la información que aporta un determinado porcentaje de neuronas dentro de cada una de las capas de la red neuronal y se utiliza con el fin de reducir el sobreajuste. El sobreajuste u overfitting, es el efecto causado por el sobreentrenamiento del algoritmo para unos ciertos datos. • En las siguientes dos capas se sigue la misma metodología. La diferencia es que en cada capa se reducen los filtros del kernel a la mitad. Aunque se podían haber mantenido en todas las capas el número del kernel fijo, se ha decidido hacer de esta forma, porque en cada capa se reduce la dimensión de la imagen a la mitad. • A continuación se aplana con "Flatten()" los 32 últimos filtros del kernel y se crea una capa de 32 neuronas tradicionales mediante "Dense()". • Finalmente se pasan estas 32 neuronas a las 7 clases que son las que se tienen que clasificar. Se usa la función de activación softmax para esta capa de salida. Figura 5.20 Arquitectura red neuronal II. 5.3 Caso III. Predicción problemas cutáneos 47 Figura 5.21 Resumen red neuronal. Se han elegido 75 epochs para que así se pueda visualizar la evolución del algoritmo y cómo va refinando conforme aumenten las iteraciones y se corrijan los pesos. Se ajusta el modelo y comienza el entrenamiento. 5.3.3 Análisis de resultados Para medir el rendimiento de los algoritmos con el conjunto de datos se calcula el accuracy o exactitud. Se ha obtenido una exactitud del 75.2 %. Ahora se verá si los resultados son coherentes. Figura 5.22 Evolución de la exactitud de la red neuronal a medida que aumenta el número de epochs. 48 Capítulo 5. Casos de estudio Figura 5.23 Evolución del error de la red neuronal a medida que aumenta el número de epochs. Ambas representaciones son coherentes debido a que a medida que aumentan los epochs, aumenta la exactitud y disminuye el error. También se puede observar que mientras que el algoritmo en el conjunto de entrenamiento da mejores resultados (la exactitud llega cerca del 90 % ), la validación se ha quedado algo estancada. Se podría probar a aumentar al 80 −85 % el porcentaje de los datos de entrenamiento y evaluar cómo responde el modelo. A continuación, se va a mostrar la matriz de confusión. Esta matriz muestra el número de veces que el algoritmo ha encasillado una imagen en un grupo o en otro. Aquella clasificación que se sitúe en la diagonal será correcta, mientras que la que se sitúe fuera de la diagonal es incorrecta. Figura 5.24 Matriz de confusión. 5.3 Caso III. Predicción problemas cutáneos 49 Lesión Tasa de acierto Células basales carcínomas 73.15 % Dermatofibroma 97.65 % Queratosis benigna 70 % Lesiones vasculares 96.875 % Melanoma 73.15 % Nevus melanocítico 60.714 % Queratosis actínica 72.8 % Como se puede observar los resultados no son del todo malos. Es cierto que el nevus melanocítico se lleva en este caso la peor parte. Es por ello que podría estar bien aumentar el número de imágenes de este tipo para que así el algoritmo sea capaz de detectar de manera correcta los rasgos. A continuación, se va a adjuntar una imagen de la matriz de confusión de una aproximación inicial del algoritmo. En este caso no se habían eliminado las imágenes duplicadas ni se había solucionado el problema del balanceo de casos. Figura 5.25 Matriz de confusión incorrecta. Como se puede observar, el algoritmo coloca prácticamente todas las imágenes como nevus melanocítico por lo que, se llegó a la conclusión de que no estaba trabajando correctamente. Es igual que lo que se ha comentado antes, a pesar de que el algoritmo no está trabajando correctamente, la exactitud es elevada debido a que existe un tipo de imágenes que es prácticamente el 80 % de todos los ejemplos. 5.3.4 Método de uso Como se ha podido observar, el algoritmo acierta en 3 de cada 4 casos en esta aproximación. Mejoraría analizando la red neuronal, aumentando el número de imágenes... Para utilizarlo lo único que habría que hacer sería subir una imagen de la mancha. Podría diseñarse una aplicación sencilla que al subir la imagen devolviese lo siguiente: 50 Capítulo 5. Casos de estudio Figura 5.26 Respuesta de la aplicación. Figura 5.27 Respuesta de la aplicación. 5.3 Caso III. Predicción problemas cutáneos 51 5.3.5 Mejora del modelo Viendo que la efectividad del modelo es del 75.2 % y observando que en la matriz de confusión algunas tasas de aciertos eran bajas, se ha tratado de mejorar el modelo. Para ello las modificaciones que se han realizado han sido las siguientes: •Se han reescalado los datos de la siguiente forma: Figura 5.28 Escalado de las imágenes. Esto se ha realizado con la intención de aumentar el porcentaje de acierto de aquellas clases que tenían una tasa más baja. •El conjunto de entrenamiento en vez de ser el 75 % de los datos, esta vez pasa a ser el 80 %. •Se ha aumentado el número de epochs a 150. 52 Capítulo 5. Casos de estudio Los resultados obtenidos son los siguientes: Figura 5.29 Evolución de la exactitud de la red neuronal a medida que aumenta el número de epochs. Caso mejorado. Figura 5.30 Evolución del error de la red neuronal a medida que aumenta el número de epochs. Caso mejorado. 5.3 Caso III. Predicción problemas cutáneos 53 El modelo alcanza una exactitud del 84.90 % , lo que supone una mejora del 13 % con respecto al modelo anterior. La matriz de confusión que se obtiene es la siguiente: Figura 5.31 Matriz de confusión. Lesión Tasa de acierto Células basales carcínomas 91.866 % Dermatofibroma 100 % Queratosis benigna 75.524 % Lesiones vasculares 100 % Melanoma 71.839 % Nevus melanocítico 68.807 % Queratosis actínica 80 % Se puede observar cómo los resultados en todas las lesiones han mejorado excepto en el caso del melanoma el cual ha disminuido (aunque nuy poco) la tasa de acierto. El modelo ha mejorado bastante y tiene una tasa de acierto elevada. 60 Capítulo 6. Anexo medidas_nuevas = cluster_f - cluster_M # In[65]: medidas_nuevas = medidas_nuevas [400:] medidas_nuevas # ### 3.2.1 Se van a estudiar la desviación que tienen las medidas # In[66]: len(medidas_nuevas) # ### 3.2.2 Coincidencias # In[67]: coincidentes = medidas_nuevas[medidas_nuevas==0] # In[68]: n_coincidentes = len(coincidentes) n_coincidentes # #### Porcentaje de coincidencia # In[69]: tasa_coincidencia = (n_coincidentes/len(medidas_nuevas))*100 tasa_coincidencia # ### 3.2.3 Diferencias de 1 cambio de clase # In[70]: una_clase_pos = len(medidas_nuevas[medidas_nuevas==10]) una_clase_neg = len(medidas_nuevas[medidas_nuevas==-10]) una_clase = una_clase_pos + una_clase_neg #n_una_clase = len(una_clase) una_clase # In[71]: 1 Código 61 # Vemos las veces que sale negativo y positivo frente a las totales (una_clase_neg/una_clase)*100 # In[72]: (una_clase_pos/una_clase)*100 # In[73]: tasa_una_clase = (una_clase/len(medidas_nuevas))*100 tasa_una_clase # ### 3.2.3 Diferencias de 2 cambios de clase # In[74]: dos_clases_pos =len(medidas_nuevas[medidas_nuevas==(20)]) dos_clases_neg =len(medidas_nuevas[medidas_nuevas==(-20)]) dos_clases = dos_clases_pos + dos_clases_neg #n_dos_clases = len(dos_clases) dos_clases # In[75]: (dos_clases_neg/dos_clases)*100 # In[76]: (dos_clases_pos/dos_clases)*100 # In[77]: tasa_dos_clases = (dos_clases/len(medidas_nuevas))*100 tasa_dos_clases # ### 3.2.4 Diferencias de 3 cambios de clase # In[78]: tres_clases_pos =len(medidas_nuevas[medidas_nuevas==(30)]) tres_clases_neg =len(medidas_nuevas[medidas_nuevas==(-30)]) 62 Capítulo 6. Anexo tres_clases = tres_clases_pos + tres_clases_neg #n_dos_clases = len(dos_clases) tres_clases # In[79]: tasa_tres_clases = (tres_clases/len(medidas_nuevas))*100 tasa_tres_clases # ## Añadiendo el método de los K-Means cambiando el centroide # In[59]: from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=4).fit(df_mean) centroids = kmeans.cluster_centers_ centroids = np.around(centroids, decimals=1) print(centroids) # In[8]: c4_mean = [3,3,1,1,3,3,3,2] c2_mean = [1,1,0,1,1,1,1,1] c3_mean = [2,2,1,1,2,2,2,1] c1_mean = [0,0,0,0,0,0,0,0] # In[9]: c1_mean == c1_f # In[10]: c2_mean == c2_f # In[11]: c3_mean == c3_f # In[12]: c4_mean == c4_f 1 Código 63 # In[13]: centroids_normed = centroids / centroids.max(axis=0) # In[18]: [cluster_mean,distance_mean] = vq(data_normed, centroids_normed) # In[19]: cluster_mean # In[57]: cluster_mean = np.where(cluster_mean==1,40,cluster_mean) cluster_mean = np.where(cluster_mean==2,30, cluster_mean) cluster_mean = np.where(cluster_mean==3,10, cluster_mean) cluster_mean = np.where(cluster_mean==0,20, cluster_mean) cluster_mean[528] # In[35]: medidas_nuevas_mean = cluster_f - cluster_mean medidas_nuevas_mean1 = medidas_nuevas_mean medidas_nuevas_mean = medidas_nuevas_mean [400:] medidas_nuevas_mean # In[36]: len(medidas_nuevas_mean) # In[37]: coincidentes_mean = medidas_nuevas_mean[medidas_nuevas_mean==0] n_coincidentes_mean = len(coincidentes_mean) n_coincidentes_mean # In[38]: tasa_coincidencia_mean = (n_coincidentes_mean/len(medidas_nuevas_mean))*100 tasa_coincidencia_mean 64 Capítulo 6. Anexo # In[39]: una_clase_pos_mean = len(medidas_nuevas_mean[medidas_nuevas_mean==10]) una_clase_neg_mean = len(medidas_nuevas_mean[medidas_nuevas_mean==-10]) una_clase_mean = una_clase_pos_mean + una_clase_neg_mean #n_una_clase = len(una_clase) una_clase_mean # In[40]: (una_clase_mean/len(medidas_nuevas_mean))*100 # In[41]: dos_clase_pos_mean = len(medidas_nuevas_mean[medidas_nuevas_mean==20]) dos_clase_neg_mean = len(medidas_nuevas_mean[medidas_nuevas_mean==-20]) dos_clase_mean = dos_clase_pos_mean + dos_clase_neg_mean #n_una_clase = len(una_clase) dos_clase_mean (dos_clase_mean/len(medidas_nuevas_mean))*100 # In[42]: dos_clase_mean # In[43]: tasa_coincidencia_mean+(una_clase_mean/len(medidas_nuevas_mean))*100+(dos_clase _mean/len(medidas_nuevas_mean))*100 # In[45]: #medidas_nuevas_mean1 medidas_nuevas_mean1[np.where(medidas_nuevas_mean1 == 20)] # In[47]: np.where(medidas_nuevas_mean1 == -20) # In[48]: 1 Código 65 np.where(medidas_nuevas_mean1 == 0) # In[ ]: 66 Capítulo 6. Anexo 1.2 Caso II #!/usr/bin/env python # coding: utf-8 # In[1]: import numpy as np from sklearn import neighbors,preprocessing from sklearn.model_selection import train_test_split import pandas as pd import matplotlib.pyplot as plt import seaborn as sns; sns.set() sns.set_style(’darkgrid’) # In[2]: from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.svm import LinearSVC, SVC from sklearn.neural_network import MLPClassifier from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier # In[3]: mainpath="/Users/Usuario/Desktop/Skylife/AI_MEDICINE/" filename= "CANCER_DE_MAMA/cancer/breast-cancer-wisconsin.data.txt" fullpath=mainpath+"/"+filename data = pd.read_csv(fullpath,header=None) data.describe() # In[4]: mainpath="/Users/Usuario/Desktop/Skylife/AI_MEDICINE/" filename= "CANCER_DE_MAMA/cancer/breast-cancer-wisconsin.data.txt" fullpath=mainpath+"/"+filename data = pd.read_csv(fullpath,header=None) data = data.drop([0],axis = 1) data.head() # In[5]: data.describe() 1 Código 67 # In[6]: data.columns = ["V1","V2","V3","V4","V5","V6","V7","V8","V9","Class"] data # In[7]: data.replace("?",-99999999,inplace = True) # ### Exploración de los datos # In[8]: dataframe = data.set_index(data["Class"]) # In[9]: data_benigno = dataframe.loc[2] # In[10]: data_benigno.shape # In[11]: data_benigno.describe() # In[12]: data_maligno = dataframe.loc[4] # In[13]: data_maligno.shape # In[14]: data_maligno.describe() 68 Capítulo 6. Anexo # In[15]: plt.figure(figsize = (8,8)) plt.pie(data[’Class’].value_counts(),autopct = ’%.2f%%’,labels=["Benigno"," Maligno"]) plt.title("Distribución de pacientes") # In[16]: pip install -U seaborn # In[17]: plt.figure(figsize = (25,15)) for i, column in enumerate(data.columns): plt.subplot(4,6,i+1) sns.boxplot(data=data[column]) plt.title(column) plt.show() # In[18]: corr = data.corr() plt.figure(figsize = (24,20)) sns.heatmap(corr, annot = True, vmin = -1.0, cmap = ’mako’) plt.title("Matriz de correlacion") plt.show() # In[19]: X = data[["V1","V2","V3","V4","V5","V6","V7","V8","V9"]] data[’Class’] = data[’Class’].replace({ 2: "Benigno", 4: "Maligno", }) Y = data["Class"] Y # In[20]: X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size = 0.2) # In[21]: 1 Código 69 scaler = StandardScaler() scaler.fit(X_train) X_train = pd.DataFrame(scaler.transform(X_train), index=X_train.index, columns= X_train.columns) X_test = pd.DataFrame(scaler.transform(X_test), index=X_test.index, columns=X_ test.columns) X_train # In[22]: models = { " Logistic Regression": LogisticRegression(), " K-Nearest Neighbors": KNeighborsClassifier(), " Decision Tree": DecisionTreeClassifier(), "Support Vector Machine (Linear Kernel)": LinearSVC(), " Support Vector Machine (RBF Kernel)": SVC(), " Neural Network": MLPClassifier(), " Random Forest": RandomForestClassifier(), " Gradient Boosting": GradientBoostingClassifier(), } for name, model in models.items(): model.fit(X_train, Y_train) print(name + " trained.") # In[23]: for name, model in models.items(): print(name + ": {:.2f}%".format(model.score(X_test, Y_test) * 100)) # In[24]: classification = neighbors.KNeighborsClassifier() classification.fit(X_train,Y_train) # In[25]: accuracy = classification.score(X_test,Y_test) accuracy # In[26]: medida_nueva = np.array([4,4,4,2,2,3,2,1,1]) medida_nueva = medida_nueva.reshape(1,-1) 76 Capítulo 6. Anexo # In[77]: X = np.asarray(skin_df_balanced[’image’].tolist()) X = X/255. # In[78]: x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42) # In[79]: model = Sequential() model.add(Conv2D(256, (3, 3), activation="relu", input_shape=(SIZE, SIZE, 3))) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Conv2D(128, (3, 3),activation=’relu’)) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Conv2D(64, (3, 3),activation=’relu’)) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Flatten()) model.add(Dense(32)) model.add(Dense(7, activation=’softmax’)) model.summary() # In[80]: model.compile(loss=’categorical_crossentropy’, optimizer=’Adam’, metrics=[’acc ’]) # In[81]: model.summary() # In[82]: batch_size = 16 1 Código 77 epochs = 75 # In[83]: history = model.fit( x_train, y_train, epochs=epochs, batch_size = batch_size, validation_data=(x_test, y_test), verbose=2)aju # In[160]: score = model.evaluate(x_test, y_test) print(’Test accuracy:’, score[1]) # In[85]: #plot the training and validation accuracy and loss at each epoch loss = history.history[’loss’] val_loss = history.history[’val_loss’] epochs = range(1, len(loss) + 1) plt.plot(epochs, loss, ’y’, label=’Training loss’) plt.plot(epochs, val_loss, ’r’, label=’Validation loss’) plt.title(’Training and validation loss’) plt.xlabel(’Epochs’) plt.ylabel(’Loss’) plt.legend() plt.show() # In[86]: acc = history.history[’acc’] val_acc = history.history[’val_acc’] plt.plot(epochs, acc, ’y’, label=’Training acc’) plt.plot(epochs, val_acc, ’r’, label=’Validation acc’) plt.title(’Training and validation accuracy’) plt.xlabel(’Epochs’) plt.ylabel(’Accuracy’) plt.legend() plt.show() # In[159]: # Prediction on test data y_pred = model.predict(x_test) # Convert predictions classes to one hot vectors 78 Capítulo 6. Anexo y_pred_classes = np.argmax(y_pred, axis = 1) # Convert test data to one hot vectors y_true = np.argmax(y_test, axis = 1) # In[88]: from sklearn.metrics import confusion_matrix confusion_mtx = confusion_matrix(y_true, y_pred_classes) # plot the confusion matrix plot_labels = [’bcc’, ’df’, ’bkl’, ’vasc’, ’mel’, ’nv’,’akiec’] plot_confusion_matrix(confusion_mtx, classes = plot_labels) # In[100]: sns.heatmap(confusion_mtx.T, square=True, annot=True, fmt=’d’, cbar=True, xticklabels=plot_labels, yticklabels=plot_labels ) # In[140]: prediccion = y_pred[1]*100 x_test[1] # In[121]: print(’La probabilidad que sean células basales carcinomas es del’,prediccion [0],’%’) print(’La probabilidad que sea dermatofibroma es del’,prediccion[1],’%’) print(’La probabilidad que sea benigno (carcinomas) es del’,prediccion[2],’%’) print(’La probabilidad que sea una lesión vascular es del’,prediccion[3],’%’) print(’La probabilidad que sea melanoma es del’,prediccion[4],’%’) print(’La probabilidad que sea nevus melanocítico es del’,prediccion[5],’%’) print(’La probabilidad que sea queratosis actínica es del’,prediccion[6],’%’) # In[126]: columns = [’Células basales carcinomas’,’Dermatofibroma’,’Benigna’, ’Lesiones vasculares’,’Melanoma’,’Nevus melanocítico’,’Queratosis actínica’] # In[135]: df1 = pd.DataFrame(prediccion,columns) df1_transposed = df1.T df1_transposed 1 Código 79 # In[137]: fig, ax2 = plt.subplots(1, 1, figsize= (15, 10)) df1_transposed.plot(kind=’bar’, ax=ax2) # In[158]: y_test # In[155]: y_pred2 = np.argmax(y_pred,axis=1) y_test2 = np.argmax(y_test,axis=1) # In[157]: plt.figure(figsize=(16,16)) for i in range(9): plt.subplot(3,3,i+1) index = i+100 plt.imshow(x_test[index,:,:,::-1]) label_exp = columns[y_test2[index]] #expected label label_pred = columns[y_pred2[index]] #predicted label label_pred_prob = round(np.max(y_pred1[index])*100) plt.title(’Expected:’+str(label_exp)+’\n Pred.:’+str(label_pred)+’ (’+str( label_pred_prob)+’%)’) plt.ylabel(’’) plt.tight_layout() plt.savefig(’final_figure.png’,dpi=300) plt.show() # In[ ]: 80 Capítulo 6. Anexo Mejora del resultado anterior #!/usr/bin/env python # coding: utf-8 # ## 1. Importe de librerías # In[1]: import matplotlib.pyplot as plt import numpy as np import pandas as pd import os import glob import seaborn as sns from PIL import Image np.random.seed(123) from sklearn.preprocessing import label_binarize from sklearn.metrics import confusion_matrix import itertools from sklearn.model_selection import train_test_split import keras from keras.utils.np_utils import to_categorical # used for converting labels to one-hot-encoding from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D from keras import backend as K import itertools from keras.layers.normalization import BatchNormalization from keras.utils.np_utils import to_categorical # convert to one-hot-encoding from tensorflow.keras.callbacks import * from keras.optimizers import Adam from keras.preprocessing.image import ImageDataGenerator from keras.callbacks import ReduceLROnPlateau # ## 2. Carga de imágenes # In[2]: mainpath="/Users/Usuario/Desktop/Skylife/SKIN_CANCER" filename= "skin-cancer-mnist-ham10000" path = mainpath+"/"+filename path_imagenes = {os.path.splitext(os.path.basename(x))[0]:x for x in glob.glob( os.path.join(path,’*’,’*.jpg’))} # ## 3. Carga del documento # In[3]: 1 Código 81 mainpath ="/Users/Usuario/Desktop/Skylife/SKIN_CANCER" filename = "skin-cancer-mnist-ham10000/HAM10000_metadata.csv" fullpath = mainpath+"/"+filename skin_df = pd.read_csv(fullpath) # In[4]: # Visualizamos cómo queda el dataset skin_df.head() # In[5]: # Introducimos el path recorriendo el path de imágenes creado con la image_id skin_df[’path’] = skin_df[’image_id’].map(path_imagenes.get) # In[6]: # Introducimos otra columna para ver el nombre completo de la lesión tipo_lesion = { ’nv’:’Nevus melanocítico’, ’mel’: ’Melanoma’, ’bkl’: ’Enfermedades benignas: Queratosis ’, ’bcc’: ’Células basales carcinomas’, ’akiec’: ’Queratosis actínica’, ’vasc’: ’Lesiones vasculares’, ’df’: ’Dermatofibroma’ } skin_df[’cell_type’] = skin_df[’dx’].map(tipo_lesion.get) # In[7]: # Pasamos las distintas cell_type a categorías skin_df[’cell_type_idx’] = pd.Categorical(skin_df[’cell_type’]).codes # ## Exploración del dataset: limpieza y wrangling # In[8]: skin_df.isnull().sum() # In[9]: skin_df[’age’].fillna((skin_df[’age’].mean()), inplace=True) skin_df.isnull().sum() 82 Capítulo 6. Anexo # In[10]: print(skin_df.dtypes) # In[11]: SIZE = 64 # In[12]: skin_df[’image’] = skin_df[’path’].map(lambda x: np.array(Image.open(x).resize ((SIZE,SIZE)))) # In[13]: skin_df.head() # In[14]: skin_df[’image’].map(lambda x: x.shape).value_counts() # In[15]: skin_df[’image’] # ## Eliminación de imágenes duplicadas # In[16]: # this will tell us how many images are associated with each lesion_id df_undup = skin_df.groupby(’lesion_id’).count() # now we filter out lesion_id’s that have only one image associated with it df_undup = df_undup[df_undup[’image_id’] == 1] df_undup.reset_index(inplace=True) df_undup.head() # In[17]: def get_duplicates(x): unique_list = list(df_undup[’lesion_id’]) if x in unique_list: 1 Código 83 return ’unduplicated’ else: return ’duplicated’ skin_df[’duplicates’] = skin_df[’lesion_id’] skin_df[’duplicates’] = skin_df[’duplicates’].apply(get_duplicates) # In[18]: skin_df[’duplicates’].value_counts() skin_df_nd = skin_df[skin_df[’duplicates’] == ’unduplicated’] # In[19]: skin_df[’duplicates’].value_counts() # In[20]: # Así queda el no ¯de casos skin_df_nd[’cell_type_idx’].value_counts() # In[21]: # Se puede observar cómo está desbalanceado fig, ax1 = plt.subplots(1, 1, figsize= (15, 10)) skin_df_nd[’cell_type’].value_counts().plot(kind=’bar’, ax=ax1) # In[22]: # Se va a proceder a reescalar los casos from sklearn.utils import resample df_0 = skin_df[skin_df.cell_type_idx == 0] df_1 = skin_df[skin_df.cell_type_idx == 1] df_2 = skin_df[skin_df.cell_type_idx == 2] df_3 = skin_df[skin_df.cell_type_idx == 3] df_4 = skin_df[skin_df.cell_type_idx == 4] df_5 = skin_df[skin_df.cell_type_idx == 5] df_6 = skin_df[skin_df.cell_type_idx == 6] # In[23]: df_0_balanced = resample(df_0, replace=True, n_samples=1000, random_state=42) df_1_balanced = resample(df_1, replace=True, n_samples=600, random_state=42) 84 Capítulo 6. Anexo df_2_balanced = resample(df_2, replace=True, n_samples=700, random_state=42) df_3_balanced = resample(df_3, replace=True, n_samples=900, random_state=42) df_4_balanced = resample(df_4, replace=True, n_samples=900, random_state=42) df_5_balanced = resample(df_5, replace=True, n_samples=500, random_state=42) df_6_balanced = resample(df_6, replace=True, n_samples=500, random_state=42) skin_df_balanced = pd.concat([df_0_balanced, df_1_balanced, df_2_balanced, df_3_balanced, df_4_balanced, df_5_balanced, df_6_balanced]) # In[24]: # Se puede observar cómo está desbalanceado fig, ax2 = plt.subplots(1, 1, figsize= (15, 10)) skin_df_balanced[’cell_type’].value_counts().plot(kind=’bar’, ax=ax2) # In[26]: skin_df_balanced[skin_df_balanced.cell_type_idx == 1] # In[27]: # Se puede observar cómo ahora sí nos queda el dataset balanceado skin_df_balanced[’cell_type’].value_counts() # ## Preparamos los datos para entrenar el modelo # In[28]: y = skin_df_balanced[’cell_type_idx’] y.shape # In[29]: y = to_categorical(y, num_classes = 7) y.shape # In[30]: X = np.asarray(skin_df_balanced[’image’].tolist()) X = X/255. # In[31]: 1 Código 85 x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random _state=423) # In[32]: model = Sequential() model.add(Conv2D(256, (3, 3), activation="relu", input_shape=(SIZE, SIZE, 3))) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Conv2D(128, (3, 3),activation=’relu’)) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Conv2D(64, (3, 3),activation=’relu’)) #model.add(BatchNormalization()) model.add(MaxPool2D(pool_size=(2, 2))) model.add(Dropout(0.3)) model.add(Flatten()) model.add(Dense(32)) model.add(Dense(7, activation=’softmax’)) model.summary() # In[33]: model.compile(loss=’categorical_crossentropy’, optimizer=’Adam’, metrics=[’acc ’]) # In[34]: model.summary() # In[36]: batch_size = 16 epochs = 150 # In[37]: history = model.fit( x_train, y_train, epochs=epochs,