Caso Práctico con la Neurona M-P

Andres Felipe Ocampo
15 min readJan 27, 2024

Una vez hemos visto cómo implementar esta neurona de M-P, y concretamente hemos visto cómo este algoritmo recibe una serie de características binarias, procesa esas características binarias mediante una función de agregación Z y después aplicando otra función de activación, básicamente comparando el resultado de esta función Z con un threshold o límite y nos proporciona una característica de salida, un output que también es binario concretamente true o false o 1 — 0.

Vamos a ver cómo aplicar esta misma neurona de M-P a un caso práctico real. Bien, pues para este caso práctico en concreto, nosotros vamos a utilizar un conjunto de datos que se va a corresponder con este que veis en pantalla, aquí el codigo gist -> Caso práctico con la neurona de M-P

El conjunto de datos que vamos a utilizar van a ser datos que provienen de una asociación del cáncer de mama de Wisconsin y que concretamente se van a corresponder con una serie de características de entrada que se han calculado a partir de una imagen digitalizada, de un aspirado de aguja fina, de una masa mamaria. Se describen las características de los núcleos celulares presentes en la imagen, como probablemente la mayoría de vosotros estáis intuyendo cuando habéis leído esto. El ejercicio que vamos a realizar consiste en el diagnóstico, la detección de tumores mamarios malignos, es decir, cáncer de mama y benignos, y concretamente, el conjunto de datos se corresponde con las características que tienen esos tumores, es super importante ver que esto es una herramienta que ayuda a los medicos especialistas a mejorar su diagnóstico NO que se haga su trabajo. De acuerdo, tendremos características como por ejemplo el tamaño del tumor, como por ejemplo la textura del tumor, etc, etc.

Esas son las características que recibirán nuestra neurona de M-P y lo que tiene que hacer es decidir si ese tumor es maligno, que se correspondería con un “true” con un “1" o si es benigno, que se correspondería con un “false” o con un “0".

Bien!!.

Fijaros que este problema es un poquito más complejo o bastante más complejo que el que veíamos anteriormente, en el que nosotros tratábamos de decidir si íbamos al cine o no en base a la respuesta a una serie de preguntas, en este caso tratamos de identificar si un tumor es maligno o benigno en base a una serie de características de entrada, que también tienen que ser binarias {1,0}, pero que se corresponden con las características que tiene ese tumor, como la textura, el tamaño, como por ejemplo el radio, etc.

Bien, pues una vez visto esto, simplemente haceros una mención al conjunto de datos. Vamos a meternos en materia y mas concretamente dentro de técnicas de aprendizaje supervisado. Por lo tanto, vamos a tratar de aplicar ese concepto también a la neurona de M-P y este conjunto de datos en concreto, además de darnos todas esas características de entrada sobre diferentes tumores, nos proporciona una catalogación, nos proporciona una etiqueta que nos indica si ese tumor es maligno o es benigno. Nuestra idea con esto es utilizar este conjunto de datos que ya está catalogado, en el que ya se sabe qué tumores benigno y cuál no, para tratar de ajustar nuestro cerebro al de nuestra red neuronal de la mejor manera posible.

Bien, pues vamos a comenzar con el código y vamos a ver cómo vamos a tratar de diagnosticar si un tumor en una mama se corresponde con un tumor maligno o con un tumor benigno.

Fijaros que en este caso tenemos bastante suerte porque este conjunto de datos se encuentra incluido en esta librería, sklearn, como muchos sabéis, es una de las librerías más populares, sino la más popular que se utiliza para la implementación de algoritmos de machine learning, no obstante mas adelante veremos ejemplos con Keras y Tensorflow.

Sin embargo, este conjunto de datos se encuentra incluido dentro de sklearn datasets y por lo tanto es muy sencillito importarlo.

Simplemente con este método load_breast_cancer nosotros lo invocamos y tenemos este conjunto de datos en esta variable que veis aquí. Este conjunto de datos tiene diferentes atributos con los que nosotros podemos obtener, por ejemplo los datos que es esto que veis aquí o esa etiqueta de la que hablábamos qué describia si ese ejemplo en concreto se correspondía con un ejemplo maligno o con un ejemplo benigno, de acuerdo, ejecutamos esta celda y tenemos almacenado en la variable X los datos y en la variable Y esa etiqueta vale.

Fijaros que nosotros podemos visualizar si queréis que el resto de atributos que tiene este conjunto de datos con el método dir({definimos la variable}), nosotros podemos verlo y pues tiene también el nombre de las características de entrada, la textura, el radio, etc.

Lo vamos a ver ahora también tiene el nombre de la característica de salida y demás atributos bien!! que tampoco son tan relevantes pues pasamos al siguiente apartado de nuestro ejercicio práctico.

Fijaros que en el siguiente apartado lo que yo suelo hacer es visualizar el conjunto de datos y qué problema tenemos ahora mismo? bueno, pues si os fijáis, si nosotros mostramos ahora mismo nuestra característica o nuestra variable “X”, donde tenemos esas características de entrada, esos valores, pues lógicamente corresponden con una matriz en el que tenemos una serie de valores continuos que de alguna manera tenemos que transformar a binarios, pero que no podemos ni visualizar a qué característica de entrada se corresponde ni nada de nada.

Qué es lo que yo suelo hacer y lo que os recomiendo a todos que hagáis transformar esta información en un data frame de pandas.

Pandas es otra de las librerías fundamentales pues este data frame es una de las mejores maneras de tratar los datos, tanto de visualizarlos como de manipularlos, etc. Es muy sencillito convertirlo en un data frame.

Simplemente pasamos en en los parametros del metodo nuestra variable “X” como columnas e indicamos estos nombres de las características de entrada que veíamos que tenía nuestra variable conjunto de datos.

Bien, ejecutamos esta celda y ya podemos observar como ahora si esa información aparece formateada, aparece mucho más clara y básicamente nos la muestra en forma de tabla, indicándonos que cada una de las filas se va a corresponder con un ejemplo.

Es decir, se va a corresponder con una de estas imágenes digitalizadas de las que hablábamos.

Waw uuuyeahhh! chaval, en las columnas tenemos cada una de las características que se han extraído con el valor para esa imagen en particular fijaros que para la primera, pues aquí tenemos, por ejemplo el radio, textura, perímetro, area, tenemos una serie de características de entrada con un valor determinado que en este caso, pues como podéis observar es un valor continuo, pero que transformaremos en un valor binario para que nuestra neurona de M-P que solamente recibe características de entrada binarias, pues funcione correctamente.

Bien, otra cosa importante es que estas características de entrada se van a corresponder con ese x1, x2, x3, x4, así hasta xn, recordais el caso practico de ir al cine, si esta abierto, si tiene estreno pues cada una de esas entrada son estas, el radio, textura, perimetro, area, suavidad, compactacion, etc..

Concretamente tenemos 30 características de entrada hasta x30 de las que hablábamos en el articulo anterior. Y también puede ser relevante que veáis la característica de salida, que es la característica de salida lógicamente es un valor binario que se corresponde con cero uno cero sería si ese ejemplo, esa imagen concreta se corresponde con un tumor benigno y uno si se corresponde con un tumor maligno.

Concretamente, fijaros que para el primer ejemplo que tiene estos valores de características de entrada, pues podemos observar que es un tumor benigno biennnn no?? Nosotros lo que creemos es que nuestra neurona de M-P después de ajustar ese threshold o límite, sea capaz de predecir esto de manera automática, de manera independiente, sin que nosotros le digamos nada. Bien!!!, una de las cosas que se realiza o que tratamos de resolver un problema aplicando técnicas de machine learning, deep learning, cualquier tipo de algoritmo de aprendizaje automático es dividir nuestro conjunto de datos en subconjuntos.

Concretamente, siempre lo vamos a dividir en un subconjunto de entrenamiento que utilizaremos para ajustar diferentes parámetros del algoritmo, en este caso para ajustar ese threshold o límite y un conjunto o un subconjunto de datos de pruebas que utilizaremos para realizar pruebas de qué tal funciona nuestro algoritmo, vamos a dividir nuestro conjunto de datos en dos subconjuntos, por un lado nuestro conjunto de entrenamiento y por otro lado nuestro conjunto de pruebas.

Bien!!!, para ello utilizamos una función de sklearn que se denomina train_test_split pues utilizamos esta función que va a recibir por un lado nuestro data train de pandas df fijaros que lo hemos definido arriba, correcto?. Por otro lado, va a recibir nuestras características de salida y este stratify y lo que va a hacer es tratar de mantener las proporciones en ambos subconjuntos respecto a los valores que hay “Y”, es decir, las proporciones de ejemplos maliciosos y de ejemplos benignos, bien ejecutamos esto y lo que obtenemos es que nos ha separado nuestro conjunto original en dos subconjuntos, concretamente el subconjunto de entrenamiento que tiene 426 ejemplos y el subconjunto de pruebas que tiene 143 ejemplos fijaros que el subconjunto de entrenamiento se encuentra almacenado en X_train mientras que las características de entrada y_train, la característica de salida y el conjunto de pruebas está en X_test y_test.

Un poco marciano no? pues vamos a ir depurando fijaros que originalmente teníamos un conjunto de datos formado por 569 ejemplos que se han dividido de esta forma que vemos aquí, bien, pues una vez que hemos dividido nuestro conjunto de datos, fijaros que es lo que vamos a hacer vamos a ampliar un poquito la neurona de M-P que habíamos implementado en el articulo anterior.

De nuestro código anterior vamos concretamente, a crear un nuevo método que va a ser el método fit y que se va a encargar de buscar de manera automática, el valor del threshold o límite que mejor se adapta a nuestro conjunto de datos.

Cómo vamos a hacer esta búsqueda del threshold o límite?

Fijaros, pues va a ser muy sencillito esta función fit va a recibir por un lado X, de acuerdo?? que será las características de entrada de nuestro conjunto de datos y por otro lado va a recibir la característica de salida, es decir, la etiqueta.

Si ese ejemplo en concreto para esos valores de características de entrada es maligno o es benigno, y una vez que nosotros hemos recibido esto, vamos a seleccionar el threshold o límite de la siguiente forma recorremos todos los valores posibles que podría recibir el threshold o límite. Concretamente, los valores que vamos a considerar posibles van a ser el tamaño de acuerdo de características de entrada que tiene nuestro conjunto de datos de entrenamiento. Es decir, concretamente tenemos 30 características de entrada, como habíamos visto previamente 30 columnas. Por lo tanto, consideraremos nuestro threshold o límite entre 1 y 30 y vamos a ir probando cuál de ellos se comporta mejor.

Teniendo en cuenta que para estas características de entrada sabemos cuál es el resultado que debería dar, porque están clasificados como ejemplos malignos y con ejemplos benignos. Por lo tanto, lo que hacemos es realizamos una predicción para ellos, lo comparamos mediante esta métrica que nos calcula en la exactitud de nuestro modelo, básicamente nos calcula cómo de bien está prediciendo nuestra neurona artificial en base a esas etiquetas que nosotros le hemos proporcionado.

Vale, en otras palabras, tenemos las etiquetas originales “X”, tenemos la predicción que hemos realizado para las características de entrada y comparamos ambos y vemos qué tal se comporta con el threshold o límite o el que mejor se comporte, que será el que obtenga máximo valor de exactitud, será el que nos quedemos y esto es lo que hace esta función, madre miaaaaa!.

La funcion fit() asigna a nuestra variable threshold o límite qué mejor exactitud proporciona para los ejemplos de nuestro conjunto de datos de entrenamiento. Bien, pues una vez que tenemos definido este nuevo método, fijaros que tal y como pone aquí, seguimos teniendo un problema debido a que nuestro conjunto de datos, las características de entrada refieren valores continuos sin embargo, nuestra MPN Huron solo procesa características de entrada con valor binario y por lo tanto tenemos que coger estos valores que tenemos aquí para las características de entrada, que como podéis observar son valores continuos y transformarlos de alguna manera a valores binarios.

Para ello, qué es lo que vamos a utilizar?

Pues vamos a utilizar el siguiente método así que fijaros cómo se comporta.

Vale, os lo he representado como un histora histograma para que veáis mejor cómo va a transformar esas características, esos valores de las características de entrada en 0 o 1, básicamente lo que haces en este caso. Imaginad que tenemos 1, 2, 3, 4, 5, 6, 7 características centrada y para el primer ejemplo te reciben estos valores que tenemos aquí son valores continuos y queremos transformarlo a binario, pues la forma en la que lo transforma a binario va a ser esta de aquí.

La primera característica recibirá un valor de 0, la segunda recibirá un valor de 0 la tercera recibirá un valor de 1, la cuarta recibirá un valor de 1 y así sucesivamente. Y fijaros que el sentido de cómo lo transforma viene representado en esta gráfica.

Lo que estamos diciéndole es que agrupe los valores en dos grandes bloques coge el valor mínimo y el valor máximo y lo divide en dos grandes bloques concretamente esta dividiéndolo en aproximadamente tres si os fijáis aquí lo está dividiendo como en tres y todo lo que caiga de tres o menos lo va a etiquetar con un “0" todo aquello que caiga de aproximadamente tres o más lo etiquetaron con “1” fijaros que 0.04 se corresponde con un 0 dos se corresponde con un 0 cuatro se corresponde con un uno y así sucesivamente. Bien!!, esto es simplemente una intuición de cómo vamos a transformar nuestras características de entrada contínuos con valores continuos a valores binarios para que pueda entender nuestra neurona de M-P, pues una vez que hemos entendido como lo hace, vamos a aplicar este mismo método, pero en este caso a nuestro conjunto de datos completo voy a aplicar este pandas.cut y para hacerlo utilizo esta función, este método apply()

Es super útil y super eficiente a la hora de aplicar una función a todo nuestro conjunto de datos de manera simultánea entonces lo aplico tanto a mi conjunto de datos X_train como a mi subconjunto X_test ahora lo que obtengo es un conjunto de datos que he denominado X_train_bin se asigna aquí qué se corresponde con esas mismas características de entrada 30 columnas. Pero en este caso lo que tenemos son valores binarios para todas esas características.

Veréis que ahora los índices no concuerdan ¿por qué?

Porque la función train_test_split, este split mal esta que veíamos aquí para cortar nuestro conjunto de datos, lo que hace es que antes de realizar la partición mezcla todos los datos para asegurarnos de que no estamos de alguna manera alterando la tendencia de nuestro conjunto de datos pues ya tenemos nuestro conjunto de datos, tanto entrenamiento como de pruebas, transformado a un conjunto de datos cuyos valores son binarios para cada una de las características de entrada. Y lo siguiente que vamos a hacer es utilizar nuestra neurona de M-P buscando ese threshold o límite óptimo

Mediante esa función fit() que hemos definido anteriormente y después vamos a realizar predicciones. Lo primero de todo, por supuesto instanciar es nuestra neurona de M-P y después invocamos este método fit() que va a buscar el threshold o límite óptimo, fijaros que para buscar este threshold o límite óptimo yo voy a utilizar mi subconjunto de datos de entrenamiento y mi subconjunto de pruebas ya he encontrado el fresco óptimo.

Fijaros que ha sido muy rápido y concretamente si yo lo muestro para ver cual ha sido el óptimo aquí dice que para este conjunto de datos, en concreto para este X_train_bin, el threshold o límite es la etiqueta es 26 threshold o límite bastante próximo al número total de características. Bien!!, pues ya tenemos el threshold o límite óptimo.

Lo que quiere decir que si nosotros ahora mismo tuviésemos que implementar esta neurona y ayudar a diagnosticar si para una nueva imagen que se ha obtenido de una nueva paciente, ese tumor es maligno o es benignom nosotros cogeriamos esa imagen, extraemos esas características de entrada de la imagen, la textura, etc. Se la proporcionamos a nuestra neurona de M-P, utilizamos este threshold o límite de acuerdo 26, debería darnos una predicción medianamente decente de si ese tumor es maligno o es benigno.

Cómo podemos asegurarnos si nos está dando buenas o malas predicciones?

Nuestra red neuronal o nuestra neurona artificial, en este caso neurona de M-P utilizando este threshold o límite, pues muy sencillo, vamos a ello!.

Al utilizar nuestro conjunto de datos de pruebas, de acuerdo, X_test_bin que también hemos transformado a binario sin la etiqueta de salida fijaros que nosotros tenemos este test, sabemos a qué se corresponde cada uno de los ejemplos que hay en este test vamos a predecir primero con nuestra red neuronal, vamos a hacer una predicción con este método, predict() para todos los ejemplos en nuestro X_test_bin vamos, lo que tenemos aquí es una predicción para cada uno de los ejemplos false, false, false, que quiere decir que este es benigno o benigno, benigno, maligno, benigno, y así sucesivamente. Vamos a ver qué tal es la predicción respecto a las etiquetas que sabemos que son reales.

Y concretamente, fijaros que nos está diciendo que ha acertado con un 92 por ciento de exactitud, vaya madre mia chaval.

Otra de las formas de visualizar los resultados es comparándolas con lo que se denomina matriz de confusión.

Concretamente la matriz de confusión lo que nos indica es, por un lado, los:

  • verdaderos positivos -> 49
  • verdaderos negativos -> 83
  • falsos positivos -> 4
  • falsos negativos -> 7

Lo que obtenemos es que ha acertado en 49 ocasiones que se correspondían con tumores malignos. Nuestra neurona de M-P los ha identificado efectivamente como tumores malignos muy bien!!. De acuerdo, ha fallado en la identificación de 4 que ha identificado como tumores malignos. Estos son falsos positivos y se corresponden con tumores benignos. Realmente nos hemos equivocado en 4, lo cual es bastante importante.

Por otro lado, tenemos falsos negativos, es decir, hemos identificado 7 como tumores benignos que realmente estaban etiquetados o que eran tumores malignos. Y por otro lado, hemos identificado 83 como tumores benignos que efectivamente eran tumores benignos, es decir, que estaban etiquetados como tumores benignos. Por lo tanto, bueno, básicamente si nosotros completamos la exactitud de esta predicción en base a estos valores, lo que obtendríamos es un 81%, lo cual es muy bueno para este caso en concreto.

No nos podemos permitir fallar en tantas ocasiones porque estamos hablando de la salud de un paciente o algo que es muy importante, pero podemos observar como utilizando esta neurona de macula aquí Pitts, esta neurona tan antigua, tan simple, ya podemos llegar incluso a obtener un 81 por ciento de precisión.

A disfrutar del Sábado por la noche nerdsss, pasad un bune finde y tomaros algo leyendo este articulo, tan interesante.

--

--