Processing math: 63%

Herramientas de usuario

Herramientas del sitio


clase:iabd:pia:2eval:tema07.metricas

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
clase:iabd:pia:2eval:tema07.metricas [2024/03/19 22:12]
admin [Ejercicios]
— (actual)
Línea 1: Línea 1:
-====== 7. Entrenamiento de redes neuronales c) Métricas ====== 
- 
-===== Métricas ===== 
-Hasta ahora hemos visto como definir una red neuronal y como entrenarla. El último paso que nos queda es saber si la red ha funcionado correctamente.  Pero ¿Eso no se hacía con la función de coste? Pues no exactamente. La función de coste se usa para ayudar a ajustar los parámetros durante el entrenamiento mediante los datos de entrada pero no para saber si el modelo es bueno. Para saber si el modelo es bueno , se usan las métricas. 
- 
-Las métricas son muy parecidas a las funciones de coste pero hay métricas que no existen como función de coste. El muchos casos la métrica será la misma que la función de coste. 
- 
- 
-En el método ''fit'' de Keras tenemos un nuevo parámetro para indicar la métrica llamado ''metrics'' que contiene un array con todas las métricas que queremos tener en nuestra red mientras se va entrenando 
- 
-<sxh python> 
-model.compile(loss="binary_crossentropy",optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),metrics=["AUC"]) 
-history=model.fit(x,y_true,epochs=20,verbose=False) 
-</sxh> 
- 
-Para obtener los valores de la métrica en cada época se usa la siguiente línea 
- 
-<sxh python> 
-history.history['auc'] 
-history.history['val_auc'] 
-</sxh> 
- 
- 
-===== Validación ===== 
-Acabamos de ver que entrenando la red neuronal , el error se consigue bajar a prácticamente cero. Es decir que los valores de los parámetros , pesos (weight) y sesgos bias, debe ser muy buenos. No exactamente. Resulta que los parámetros se han ajustado a los datos que le hemos pasado, pero ¿Como es de bueno el modelo para nuevos datos que no ha visto? **Realmente ver como se comporta con datos nuevos y con los datos que ha ya visto es lo que nos va a decir como es de bueno nuestro modelo**. Así que pasemos a ver como sacar las métricas también con datos nuevos. 
- 
-Lo primero es averiguar de donde obtenemos nuevos datos. Normalmente no tenemos nuevos datos así que lo que hacemos es que solo vamos a entrenar nuestra red neuronal con el 80% de los datos y el 20% restante los guardaremos para validar la red neuronal. Eso lo vamos a hacer con la función [[https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html|train_test_split]] de [[https://scikit-learn.org/|scikit-learn]] 
- 
-<sxh python> 
-from sklearn.model_selection import train_test_split 
- 
-x_train, x_test, y_train, y_test = train_test_split(x, y_true, test_size=0.2, random_state=42) 
-</sxh> 
- 
-La función ''train_test_split'' tiene los siguientes argumentos: 
-  * Los primeros arrays son los datos a //dividir// entre los datos de entrenamiento o de validación (//test// en inglés). 
-  * ''test_size'': La fracción de datos que se va a usar para la validación.Es un valor de 0.0 a 1.0. Siendo 0.0 que no hay datos para validación y 1.0 que todos sería para validación.Un valor aceptable de ''test_size'' es entre ''0.2'' a ''0.3'' 
-  * ''random_state'': Es para que sea reproducible el generador de los números aleatorios.  
-  * retorna los 4 array: 
-    * ''x_train'': Array con la ''x'' de los datos de entrenamiento 
-    * ''x_test'': Array con la ''x'' de los datos de validación  
-    * ''y_train'': Array con la ''y'' de los datos de entrenamiento 
-    * ''y_test'': Array con la ''y'' de los datos de validación 
- 
-Y ahora a Keras se los tenemos que pasar así: 
- 
-<sxh python> 
-history=model.fit(x_train,y_train,validation_data=(x_test,y_test),epochs=epochs,verbose=False) 
-</sxh> 
- 
-Lo datos de entrenamiento se pasan igual que antes pero los de validación se pasan en en un tupla en un parámetro llamado ''validation_data''. 
- 
-Por último tenemos que obtener la métrica para los datos de validación. Se obtiene igual que antes pero el nombre de la métrica empieza por ''val_'' 
- 
-<sxh python> 
-history.history['val_binary_accuracy'] 
-</sxh> 
- 
-Veamos un ejemplo completo: 
- 
-<sxh python> 
-import numpy as np 
-import tensorflow as tf 
-import numpy as np 
-import pandas as pd 
-import keras 
-import random 
-from keras.models import Sequential 
-from keras.layers import Dense 
-from sklearn.datasets import load_iris 
-import matplotlib.pyplot as plt 
-from sklearn.model_selection import train_test_split 
- 
-iris=load_iris() 
-x=iris.data[0:99,2] 
-y_true=iris.target[0:99] 
- 
-np.random.seed(5) 
-tf.random.set_seed(5) 
-random.seed(5)   
- 
-x_train, x_test, y_train, y_test = train_test_split(x, y_true, test_size=0.2, random_state=42) 
- 
-model=Sequential() 
-model.add(Dense(3, input_dim=1,activation="sigmoid",kernel_initializer="glorot_normal")) 
-model.add(Dense(1,activation="sigmoid",kernel_initializer="glorot_normal")) 
-model.compile(loss="binary_crossentropy",optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),metrics=["binary_accuracy"]) 
-history=model.fit(x_train,y_train,validation_data=(x_test,y_test),epochs=40,verbose=False) 
- 
-figure=plt.figure(figsize=(8,6)) 
-axes = figure.add_subplot() 
- 
-axes.plot(history.history['binary_accuracy'],label="Entrenamiento "+str(history.history['binary_accuracy'][-1])) 
-axes.plot(history.history['val_binary_accuracy'],label="Validación "+str(history.history['val_binary_accuracy'][-1])) 
- 
-axes.legend() 
-axes.set_xlabel('Época', fontsize=15,labelpad=20,color="#003B80")   
-axes.set_ylabel('Valor métrica', fontsize=15,labelpad=20,color="#003B80") 
-axes.set_facecolor("#F0F7FF") 
-axes.grid(b=True, which='major', axis='both',color="#FFFFFF",linewidth=1) 
-</sxh> 
- 
-{{ :clase:iabd:pia:2eval:metricas_test_train.png?direct |}} 
- 
-Podemos ver en el gráfico que la métrica es muy similar con los datos de validación que con los de entrenamiento. otro detalle importante es que las métricas suelen ser buenas si su valor es 1 (al contrario de las funciones de pérdida en la que lo bueno era un 0) 
- 
-===== Tipos de métricas ===== 
-Para acabar el tema vamos a ver las distintas métricas que existen. Lo primero es indicar nombres tanto en inglés como en español ya que vamos a usar los nombres en inglés 
- 
- 
-^  Inglés  ^  Español  ^ 
-| Precision  | Precisión  | 
-| Recall  | Exhaustividad  | 
-| F1-score  | Valor-F  | 
-| Accuracy  | Exactitud  | 
-| Sensitivity  | Sensibilidad  | 
-| Confusion Matrix  | Matriz de Confusión  | 
-| True Positive  | Positivos Verdaderos  | 
-| True Negative  | Negativos Verdaderos  | 
-| False Positive  | Positivos Falsos  | 
-| False Negative  | Negativos Falsos  | 
- 
-  * Regresión 
-    * Mean Absolute Error (MAE) 
-    * Mean Squared Error (MSE) 
-    * Distancia del coseno 
-    * Root Mean Squared Error (RMSE) 
-    * Coeficiente de determinación o R² 
-  * Clasificación con 2 posibles valores 
-    * Binary Crossentropy 
-    * Accuracy 
-    * Precision 
-    * Recall o Sensitivity 
-    * F1-score 
-    * Area under the curve (AUC) 
-  * Clasificación con más de 2 posibles valores 
-    * Categorical Crossentropy  
-    * Categorical Accuracy 
- 
-Hay métricas que son exactamente iguales a las funciones de coste como MEA o MSE en los problemas de regresión MAE, MSE. Si ya las usamos como función de coste y queremos usarlas como métricas no es necesario indicarlas como métricas, se puede acceder a ellas de la siguiente forma: 
- 
-Para mostrar la función de coste en el entrenamiento: 
-<sxh python> 
-history.history['loss'] 
-</sxh> 
- 
- 
-Para mostrar la función de coste en la validación: 
-<sxh python> 
-history.history['val_loss'] 
-</sxh> 
- 
- 
-===== Métricas de regresión ===== 
-Son las métricas que se usan en problemas de regresión. Son casi las mismas que usábamos como funciones de coste.  
- 
-==== Mean Absolute Error (MAE) ==== 
-Es igual que la función de coste de Mean Absolute Error (MAE), así que no explicaremos nada mas sobre ella excepto como se usa en Keras como métrica 
- 
-Se define como: 
-<sxh python> 
-metrics=[tf.keras.metrics.MeanAbsoluteError()] 
-metrics=["mean_absolute_error"] 
- 
-metrics=["mae"] 
-</sxh> 
- 
-y usarla como 
-<sxh python> 
-history.history['mean_absolute_error'] 
-history.history['val_mean_absolute_error'] 
- 
-history.history["mae"] 
-history.history["val_mae"] 
-</sxh> 
- 
- 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/regression_metrics/#meanabsoluteerror-class|MeanAbsoluteError class]] 
- 
- 
-==== Mean Squared Error (MSE) ==== 
-Es igual que la función de coste de Mean Squared Error (MSE), así que no explicaremos nada mas sobre ella excepto como se usa en Keras como métrica 
- 
-Se define como: 
-<sxh python> 
-metrics=[tf.keras.metrics.MeanSquaredError()] 
-metrics=["mean_squared_error"] 
- 
-metrics=["mse"] 
-</sxh> 
- 
- 
-y usarla como 
-<sxh python> 
-history.history['mean_squared_error'] 
-history.history['val_mean_squared_error'] 
- 
-history.history["mse"] 
-history.history["val_mse"] 
-</sxh> 
- 
- 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/regression_metrics/#meansquarederror-class|MeanSquaredError class]] 
- 
- 
- 
-==== Distancia del coseno ==== 
-Es igual que la función de coste de Distancia del coseno, así que no explicaremos nada mas sobre ella excepto como se usa en Keras como métrica 
- 
-Se define en Keras como: 
-<sxh python> 
-metrics=[tf.keras.metrics.CosineSimilarity()] 
-metrics=["cosine_similarity"] 
-</sxh> 
- 
-y se usa como 
-<sxh python> 
-history.history['cosine_similarity'] 
-history.history['val_cosine_similarity'] 
-</sxh> 
- 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/regression_metrics/#cosinesimilarity-class|CosineSimilarity class]] 
- 
- 
-==== Root Mean Squared Error (RMSE) ==== 
-La Root Mean Squared Error (RMSE) o Raiz cuadrada del error cuadrático medio se calcula igual que el MSE pero se le aplica la raíz cuadrada. 
- 
-Por lo tanto su fórmula es 
- 
-RMSE=MSE=1NNi=1(yi^yi)2 
- 
-Ahora vamos a explicar algunas cosas de RMSE. 
-  * ¿Por qué se hace la raíz cuadrada? Pues porque antes habíamos elevado al cuadrado los errores 
-  * ¿Pero que ventaja tiene esa raíz cuadrada? La raíz cuadrada se hace para que el error esté en las mismas unidades que los datos. Es para que como //humanos// entendamos mejor el valor. Es decir que nosotros entendemos mejor el resultado de RMSE que el de MSE 
-  * ¿Por qué no existe la RMSE como función de coste? Por ahorrarnos el trabajo de hacer la raíz cuadrada. Como función de coste nos da igual el valor de MSE que la raíz cuadrada de MSE, la red va a funcionar igual. 
-  * ¿Por qué no existe RMAE? Por que con MAE no elevábamos nada al cuadrado así que no tiene sentido RMAE 
-  * A veces se intenta comprar los resultados de RMSE con MAE ya que ambos están en las mismas unidades. 
-  * Por lo que si queremos usar MSE como métrica es mejor usar RMSE   y como función de coste es mejor MSE 
- 
- 
-Se define en Keras como: 
-<sxh python> 
-metrics=[tf.keras.metrics.RootMeanSquaredError()] 
-</sxh> 
- 
-y se usa como 
-<sxh python> 
-history.history['root_mean_squared_error'] 
-history.history['val_root_mean_squared_error'] 
-</sxh> 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/regression_metrics/#rootmeansquarederror-class|RootMeanSquaredError class]] 
- 
- 
-==== Coeficiente de determinación o R² ==== 
-El coeficiente de determinación o R² se calcula de la siguiente forma: 
- 
- 
-R2=1Ni=1(yi^yi)2Ni=1(yiˉy)2 
-ˉy=1NNi=1yi^yi 
- 
-Siendo: 
- 
- 
-Ahora vamos a explicar algunas cosas de R² 
-  * MAE, MSE y RMSE son mejor cuanto menor es el valor, mientras que R² es mejor cuanto más se acerca a 1. 
-  * Un problema de R² es que aumenta su valor cuantas más variables tengamos de entrada (es decir el tamaño del vector de cada muestra) por eso se suele usar la métrica de R² ajustada. Para ello en Keras le pasaremos el argumento ''num_regressors'' a la clase ''RSquare'' 
- 
- 
-Se define en Keras como: 
-<sxh python> 
-metrics=[tfa.metrics.RSquare()] 
-</sxh> 
- 
-y se usa como 
-<sxh python> 
-history.history['r_square'] 
-</sxh> 
- 
-Mas información: 
-  * [[https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/RSquare|tfa.metrics.RSquare]] 
-  * {{:clase:iabd:pia:2eval:errores_frecuentes_interpretacion_coeficiente_determinacion.pdf|Errores frecuentes en la interpretación del coeficiente de determinación lineal}} 
- 
- 
-==== Selección de métricas de regresión ==== 
-La elección de una métrica u otra se puede ver en [[https://medium.com/analytics-vidhya/mae-mse-rmse-coefficient-of-determination-adjusted-r-squared-which-metric-is-better-cd0326a5697e|MAE, MSE, RMSE, Coefficient of Determination, Adjusted R Squared — Which Metric is Better?]] y [[https://www.analyticsvidhya.com/blog/2021/05/know-the-best-evaluation-metrics-for-your-regression-model/|Know The Best Evaluation Metrics for Your Regression Model]] 
- 
-  * RMSE es mejor que MSE ya que está en las mismas unidades que el resultado y no al cuadrado. 
-  * MAE vs MSE: 
-      * MAE es mas robusto que MSE ante datos anómalos, es decir que los tiene menos en cuenta 
-      * MSE eleva el error al cuadrado y la regresión al intentar minimizar dicho error , tiende a ir hacia ese dato anómalo. Por lo que MSE tiene más en cuenta los datos anómalos. 
-      * Por lo tanto si los datos "anómalos" realmente no son anómalos sino situaciones "normales" pero poco frecuentes, deberíamos usar MSE, mientras que si los datos "anómalos" realmente son cosas "extrañas" que no deberíamos tener en cuenta, es mejor usar MAE. 
- 
- 
- 
-===== Métricas de clasificación con 2 posibles valores ===== 
-Clasificación con 2 posibles valores es cuando la salida de nuestra red neuronal solo puede tener 2 posibles valores. 
- 
-Antes de entrar a ver las métricas , es necesario entender lo que son: 
-  * True Positives (TP) 
-  * True Negatives (TN) 
-  * False Positives (FP): También llamados errores de Tipo I 
-  * False Negatives (FN): También llamados errores de Tipo II 
- 
- 
- 
- 
-| ^^  Predicción  ^^ 
-| ^^  Positivo  ^  Negativo  ^ 
-^  Realidad  ^  Enfermo  |  TP  |  FN  | 
-^ ::: ^  Sano  |  FP  |  TN  | 
- 
- 
- 
- 
- 
- 
-{{ :clase:iabd:pia:2eval:metricas_falsos.png?direct |}} 
- 
-Para explicar todos estos conceptos véase los artículos: 
-  * [[https://www.iartificial.net/precision-recall-f1-accuracy-en-clasificacion/|Precision, Recall, F1, Accuracy en clasificación]] 
-  * [[https://towardsdatascience.com/should-i-look-at-precision-recall-or-specificity-sensitivity-3946158aace1|Data Science in Medicine — Precision & Recall or Specificity & Sensitivity?]] 
- 
-Más información: 
-  * [[https://en.wikipedia.org/wiki/Confusion_matrix|Confusion matrix]] 
-  * [[https://neptune.ai/blog/evaluation-metrics-binary-classification|24 Evaluation Metrics for Binary Classification (And When to Use Them)]] 
-  * {{ :clase:iabd:pia:2eval:binary_classification_metrics_cheathsheet.pdf |Binary classification metrics Cheathsheet}} 
- 
- 
-===== Umbral o Threshold ===== 
-En la clasificación binaria los posibles valores son ''1'' y ''0'' o ''True'' y ''False''. Sin embargo nuestra red neuronal suele sacar un valor entre ''0'' y ''1''. 
-A ese valor se le llama ''y_score'' y en función de un ''threshold'' lo transformamos en el valor predicho o ''y_pred''. 
- 
-Si el valor del ''score'' es mayor que el ''threshold'' el valor predicho será un ''True'' mientras que si el valor del ''score'' es menor que el ''threshold'' el valor predicho será un ''False'' 
- 
-Veamos un ejemplo de ello: 
-<sxh python> 
-y_score=np.array([0.27, 0.45,  0.76,  0.55,  0.28, 0.04, 0.34,0.4, 0.66, 0.88, 0.94,0.47,0.2]) 
-y_pred=y_score>0.5 
-print(y_pred) 
-</sxh> 
- 
-Siendo el resultado 
-<sxh python> 
-[False False  True  True False False False False  True  True  True False False] 
-</sxh> 
- 
-Por ello la mayoría de nuestras métricas son dependientes del valor que indiquemos de ''threshold''. Excepto la métrica de ''AUC'' que es independiente del valor de ''threshold''. 
- 
-Un ejemplo de lo que acabamos de ver está en las métricas de ''f1-score'' y ''AUC'' de sklearn.  
-En [[https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html]] los parámetros de entrada son ''y_true'' e ''y_pred''  
-mientras que en [[https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html]] los parámetros de entrada son ''y_true'' e ''y_score'' ya que no necesita el umbral 
- 
- 
-===== Probabilidad condicional ===== 
-La probabilidad condicional se expresa de la siguiente forma //P(A|B)// que significa , la probabilidad de que ocurra //A// sabiendo que ya ocurrido //B//. ¿Y que tiene que ver ésto con las métricas? Realmente las métricas se pueden expresar como probabilidades condicionales. Lo bueno de usar probabilidades condicionales es que se entienden mejor. 
- 
-Para explicar las métricas vamos a imaginar los test de COVID que comprobamos en las farmacias , que nos decían si teníamos o no COVID. El ejemplo es igual que si fuera una red neuronal que dado una radiografía nos dijera si teníamos o no COVID. Pero se usa el test de farmacia de COVID para hacer más comprensible la explicación. 
- 
-Para poner la probabilidad condicional vamos a usar la siguiente nomenclatura: 
-  * Positivo: El test ha dado un valor positivo. Umbral >= 0.5 
-  * Negativo: El test ha dado un valor negativo. Umbral < 0.5 
-  * Enfermo: El paciente está enfermo ya que se ha usado el {{https://es.wikipedia.org/wiki/Gold_standard_(test)|test de referencia}} (distinta a nuestro test) que sabemos que acierta el 100% de las veces. 
-  * Sano: El paciente está sano ya que se ha usado el {{https://es.wikipedia.org/wiki/Gold_standard_(test)|test de referencia}} (distinta a nuestro test) que sabemos que acierta el 100% de las veces.  
- 
-Veamos ahora unas probabilidades condicionales. 
- 
-  * P(Positivo|Enfermo): Sabiendo que una persona ya está enferma  y le hacemos el test, obtendríamos la probabilidad de que el test de positivo para esa persona. 
-  * P(Enfermo|Positivo): Sabiendo que la persona ha dado positivo en el test obtendríamos la probabilidad de que la persona esté enferma. 
- 
-Detengámonos un momento. ¿Cual de las 2 probabilidades nos interesa?. P(Positivo|Enferma) o P(Enferma|Positivo). Si lo pensamos , ¿para que queremos saber P(Positivo|Enferma)? Si ya sabemos que la persona está enferma, ¿para que querríamos usar el test? ¡¡Ya sabemos que está enferma!!!! Así que realmente nos interesa P(Enferma|Positivo) 
- 
-===== Cálculo de las métricas ===== 
-Pongamos ahora todas las combinaciones de probabilidades posibles de las métricas que realmente nos interesan. 
- 
-  * P(Enfermo|Positivo): Sabiendo que es test da **Positivo** , obtendríamos la probabilidad de que la persona esté **Enfermo**. 
-  * P(Sano|Positivo): Sabiendo que es test da **Positivo** , obtendríamos la probabilidad de que la persona esté **Sano**. 
-\\ 
-  * P(Sano|Negativo): Sabiendo que es test da **Negativo** , obtendríamos la probabilidad de que la persona esté **Sano**.  
-  * P(Enfermo|Negativo): Sabiendo que es test da **Negativo** , obtendríamos la probabilidad de que la persona esté **Enfermo**. 
- 
- 
-Mientras que las 4 siguientes aparentemente no nos interesan lo más mínimo: 
- 
-  * P(Positivo|Enfermo): Sabiendo que la persona esté **Enfermo**, obtendríamos la probabilidad de que el test de **Positivo**. 
-  * P(Negativo|Enfermo): Sabiendo que la persona esté **Enfermo**, obtendríamos la probabilidad de que el test de **Negativo**. 
-\\ 
-  * P(Negativo|Sano): Sabiendo que la persona esté **Sano**, obtendríamos la probabilidad de que el test de **Negativo**. 
-  * P(Positivo|Sano): Sabiendo que la persona esté **Sano**, obtendríamos la probabilidad de que el test de **Positivo**. 
- 
- 
-Volvamos a la matriz de confusión: 
-| ^^  Predicción  ^^ 
-| ^^  Positivo (PP)  ^  Negativo (PN)  ^ 
-^  Realidad  ^  Enfermo (P)  |  TP  |  FN  | 
-^ ::: ^  Sano  (N)  |  FP  |  TN  | 
- 
-$$ 
-\begin{array} 
-\\ 
-E&=&TP+FN&=&Nº \; de \; enfermos 
-\\ 
-S&=&FP+TN&=&Nº \; de \; sanos 
-\\ 
-PP&=&TP+FP&=&Nº \; predichos \; positivos 
-\\ 
-PN&=&FN+TN&=&Nº \; predichos \; negativos 
-\\ 
-\end{array} 
-$$ 
- 
- 
-Y siendo un poco perspicaces podremos ver como se calculan las 8 probabilidades y los nombres que tienen: 
- 
- 
-$$ 
-\begin{array} 
-\\ 
-P(Enfermo|Positivo)&=&\frac{TP}{PP}&=&\frac{TP}{TP+FP}&=&Positive \; Predictive \; Value \; (PPV)&=&Precisión& 
-\\ 
-P(Sano|Positivo)&=&\frac{FP}{PP}&=&\frac{FP}{TP+FP}&=&False \; Discovery \; Rate \; (FDR)&=&1-Precisión 
-\\ 
-\\ 
-P(Sano|Negativo)&=&\frac{TN}{PN}&=&\frac{TN}{FN+TN}&=&Negative \; Predictive \; Value \; (NPV)&& 
-\\ 
-P(Enfermo|Negativo)&=&\frac{FP}{PN}&=&\frac{FP}{FN+TN}&=&False \; Omission \; Rate \; (FOR)&=&1-NPV 
-\\ 
-\end{array} 
-$$ 
-\\ 
-\\ 
-$$ 
-\begin{array} 
-\\ 
-P(Positivo|Enfermo)&=&\frac{TP}{E}&=&\frac{TP}{TP+FN}&=&True \; Positive \; Rate (TPR) &=&Sensibilidad 
-\\ 
-P(Negativo|Enfermo)&=&\frac{FN}{E}&=&\frac{FN}{TP+FN}&=&False \; Negative \; Rate \; (FNR)&=&1-Sensibilidad 
-\\ 
-\\ 
-P(Negativo|Sano)&=&\frac{TN}{S}&=&\frac{TN}{FP+TN}&=&True \; Negative \; Rate (TNR) &=&Especificidad 
-\\ 
-P(Positivo|Sano)&=&\frac{FP}{S}&=&\frac{FP}{FP+TN}&=&False \; Positive \; Rate \; (FPR)&=&1-Especificidad 
-\\ 
-\end{array} 
-$$ 
-\\ 
-\\ 
-| ^^  Predicción  ^^ ::: ^^ 
-| ^^  Positivo (PP)  ^  Negativo (PN)  ^   Métricas   ^^ 
-^  Realidad  ^  Enfermo (E)  |  TP  |  FN  |  P(Positivo|Enfermo)=TPE P(Negativo|Enfermo)=FNE  | 
-^ ::: ^  Sano  (S)  |  FP  |  TN  |  P(Positivo|Sano)=FPS P(Negativo|Sano)=TNS  | 
-^    ^  Métricas P(Enfermo|Positivo)=TPPP P(Enfermo|Negativo)=FNPN  |    |    | 
-^ ::: ^  :::  |  P(Sano|Positivo)=FPPP P(Sano|Negativo)=TNPN  |    |    | 
- 
-| ^^  Predicción  ^^ ::: ^^ 
-| ^^  Positivo (PP)  ^  Negativo (PN)  ^   Métricas   ^^ 
-^  Realidad  ^  Enfermo (E)  |  TP  |  FN  |  TPR=TPE FNR=FNE  | 
-^ ::: ^  Sano  (S)  |  FP  |  TN  |  FPR=FPS TNR=TNS  | 
-^    ^  Métricas PPV=TPPP FOR=FNPN  |    |    | 
-^ ::: ^  :::  |  FDR=FPPP NPV=TNPN  |    |    | 
- 
-| ^^  Predicción  ^^ ::: ^^ 
-| ^^  Positivo (PP)  ^  Negativo (PN)  ^   Métricas   ^^ 
-^  Realidad  ^  Enfermo (E)  |  TP  |  FN  |  Sensibilidad=TPE FNR=FNE  | 
-^ ::: ^  Sano  (S)  |  FP  |  TN  |  FPR=FPS Especificidad=TNS  | 
-^    ^  Métricas Precisión=\frac{TP}{PP} FOR=\frac{FN}{PN}  |    |    | 
-^ ::: ^  :::  |  FDR=\frac{FP}{PP} NPV=\frac{TN}{PN}  |    |    | 
- 
- 
-===== Selección de métricas ===== 
-Volvamos ahora a recapacitar otra vez sobre el significado de las métricas. En un test perfecto realmente lo que nos interesa es: 
-  * P(Enfermo|Positivo)=1: Si el test da **Positivo** que la probabilidad de estar **Enfermo** sea **1**. 
-  * P(Sano|Negativo)=1: Si el test da **Negativo** que la probabilidad de estar **Sano** sea **1**. 
- 
-A esas 2 métricas se les llama: 
-  * P(Enfermo|Positivo)=Valor \; Predictivo \; Positivo \; (VPP)=Positive \; Predictive \; Value \; (PPV)=Precisión 
-  * P(Sano|Negativo)=Valor \; Predictivo \; Negativo \; (VPN)=Negative \; Predictive \; Value \; (NPV) 
- 
-Se llaman así porque realmente son las 2 métricas que predicen si estás enfermo o sano cuando el test da positivo o negativo respectivamente. Y a la primera de ellas se le llama también **precisión** 
- 
- 
-===== Teorema de Bayes ===== 
-El problema de calcular la precisión y el VPN es que sus valores dependen de la cantidad de enfermos y de sanos que tengamos al entrenar nuestra red. Por lo tanto del valor de E y S. Es decir que dependen de lo balanceados que tengamos nuestras clases. 
- 
-Para calcular como de balanceadas están las clases se usa la Prevalencia \; o \; P(Enfermo) , y es un dato muy importante que se calcula de la siguiente forma: 
- 
- 
-$$ 
-Prevalencia=P(Enfermo)=\frac{TP+FN}{TP+FN+FP+TN}=\frac{E}{E+S} 
-$$ 
- 
-Además están otras probabilidades que son: 
- 
-$$ 
- 
-\begin{array} 
-\\ 
-P(Enfermo)&=&\frac{TP+FN}{TP+FN+FP+TN}&=&\frac{E}{E+S}&=&Prevalencia 
-\\ 
-P(Sano)&=&\frac{FP+TN}{TP+FN+FP+TN}&=&\frac{S}{E+S}&=&1-Prevalencia 
-\\ 
-P(Positivo)&=&\frac{TP+FP}{TP+FN+FP+TN}&=&\frac{PP}{PP+PN} 
-\\ 
-P(Negativo)&=&\frac{FN+TN}{TP+FN+FP+TN}&=&\frac{PN}{PP+PN}&=&1-P(Positivo) 
-\end{array} 
-$$ 
- 
-Recordar que: 
-$$ 
-E+S=PP+PN=Total 
-$$ 
- 
-En la siguiente imagen vamos a obtener las métricas y vamos a ver como varían las métricas si aumenta o disminuye el número de positivos. Es decir vamos a ver como dependen la precisión y el VPN según la prevalencia. 
- 
-{{ :temp:metricas_vs_prevalencia.png?nolink |}} 
- 
-Vemos que si aumentamos el número de positivos (por lo tanto aumentando la prevalencia), se modifican las  métricas de Precisión (VPP) y VPN de la siguiente forma: 
-  * Si aumentamos la prevalencia:  
-    * Mejora la precisión (VPP) ya que ha pasado de 0.89 a 0.96 
-    * Empeora el VPN ya que ha pasado de 0.93 a 0.82 
-  * Si disminuimos la prevalencia:  
-    * Empeora la precisión (VPP) ya que ha pasado de 0.89 a 0.74 
-    * Mejora el VPN ya que ha pasado de 0.93 a 0.97 
- 
- 
- 
-Por lo tanto se podría hacer trampa y sin modificar el modelo pero variando la prevalencia de los datos de validación, conseguir mejorar el VPP o el PPN. 
- 
-¿Cual es entonces la solución? Pues usar métricas que no dependan de la prevalencia. Y esas métricas son la sensibilidad y la especificidad que habíamos descartado. ¿Y para que las queremos? Pues esas 2 métricas nos dicen lo bueno que es nuestro modelo cuando lo estamos desarrollando ya que nos decían cuanto acertaban o fallaban cuando sabíamos lo que debía dar y son métricas independientes de la prevalencia de nuestros datos. Podemos ver que esas métricas no han variado aunque se haya modificado la prevalencia. 
- 
-Vale, pero nosotros lo que queremos es saber la precisión y la VPN. Pues resulta que el teorema de bayes es una fórmula matemática que nos calcula la precisión y la VPN en base a la sensibilidad y la especificidad y además según la prevalencia. 😍😍😍😍😍😍 
- 
- 
-$$ 
-P(Enfermo|Positivo)=\frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo|Enfermo)*P(Enfermo)+P(Positivo|Sano)*P(Sano)}  $$ 
- 
- 
-$$ 
-P(Sano|Negativo)=\frac{P(Negativo|Sano)*P(Sano)}{P(Negativo|Sano)*P(Sano)+P(Negativo|Enfermo)*P(Enfermo)} 
-$$ 
- 
-y usando los nombres //normales// de las métricas las fórmulas quedarían así: 
- 
- 
-$$ 
-Precisión=VPP=\frac{Sensibilidad*Prevalencia}{Sensibilidad*Prevalencia+(1-Especificidad)*(1-Prevalencia)}  $$ 
- 
- 
-$$ 
-VPN=\frac{Especificidad*(1-Prevalencia)}{Especificidad*(1-Prevalencia)+(1-sensibilidad)*Prevalencia}   
-$$ 
- 
- 
-**Todo ellos nos lleva a que al desarrollar nuestra red neuronal solo nos interesan que los valores de Sensibilidad y de Especificidad sean lo más altos posibles. Y cuando vayamos a predecir, nos tendrán que indicar el valor de la prevalencia y en ese caso podremos calcular si ha salid positivo el valor de Precisión \; (VPP) y si ha salido negativo calcularemos el valor de VPN.** 
- 
-Por ello en los prospectos de los test de covid, los valores que siempre se calculaban son el de Sensibilidad y de Especificidad: {{ :clase:iabd:pia:2eval:sars-cov-2_rapid_antigen_test_es.pdf |}} 
- 
-<note important> 
-¿Y como sabemos el valor de la prevalencia? Pues nos lo tiene que dar el que hace la predicción o sino en el peor de los casos usar la prevalencia que usamos en nuestros datos. Por lo que en ese caso serían los fórmulas originales de precisión y VPN. 
- 
-En los siguientes 2 artículos vemos investigaciones para calcular la prevalencia del COVID según distintas circunstancias: 
-  * {{ :clase:iabd:pia:2eval:riesgo_de_contagio_por_covid-19_en_funcion_del_tipo_de_contacto_y_de_la_renta_familiar.pdf |Riesgo de contagio por COVID-19 en función del tipo de contacto y de la renta familiar}} 
-  * {{ :clase:iabd:pia:2eval:prevalencia_de_infeccion_por_coronavirus_sars-cov-2_en_pacientes_y_profesionales_de_un_hospital_de_media_y_larga_estancia_en_espana.pdf |Prevalencia de infección por coronavirus SARS-CoV-2 en pacientes y profesionales de un hospital de media y larga estancia en España}} 
- 
- 
-</note> 
- 
-===== Mejores valores de las métricas ===== 
-Ahora ya sabemos que **VPP** y **VPN** son las métricas que nos interesan realmente y que sus valores deben ser lo más cercanas a 1. Pero también sabemos que esas métricas dependen de la **Prevalencia** (que no depende de lo bueno que sea nuestro modelo ) y de las métricas de **Sensibilidad** y **Especificidad** (Que si que dependen de lo bueno que sea nuestro modelo). Así que para obtener los mejores valores del VPP y VPN tenemos que conseguir en nuestro modelo consigamos los mejores valores de **Sensibilidad** y **Especificidad**. 
- 
- 
-Como ya hemos visto hay las siguientes relaciones entre métricas: 
- 
-$$ 
-FNR=1-Sensibilidad 
-$$ 
-\\ 
-$$ 
-FPR=1-Especificidad 
-$$ 
- 
-Además de  
- 
-$$ 
-FDR=1-VPP 
-$$ 
-\\ 
-$$ 
-FOR=1-VPN 
-$$ 
- 
-Como esas métricas no son independientes de las anteriores, volvamos ahora a poner la tabla de confusión únicamente con las métricas que nos interesan y además los valores ideales que nos interesarían. 
- 
- 
-| ^^  Predicción  ^^ ::: ^^ 
-| ^^  Positivo (PP)  ^  Negativo (PN)  ^   Métricas   ^^ 
-^  Realidad  ^  Enfermo (E)  |  TP  |  FN  |  Sensibilidad=1  |   | 
-^ ::: ^  Sano  (S)  |  FP  |  TN  |    |  Especificidad=1  | 
-^    ^  Métricas VPP=1  |      |    | 
-^ ::: ^  :::  |    |  VPN=1  |    |    | 
- 
-Y por lo tanto el resto de las métricas nos interesarían que fueran 0 pero al depender de la que hemos mostrado , ni las mediremos. 
- 
- 
-==== Resumen ==== 
-{{ :clase:iabd:pia:2eval:metricas.png }} 
- 
- 
-Más información en: 
-  * [[https://en.wikipedia.org/wiki/Confusion_matrix|Matriz de confusión en Wikipedia]] 
-  * [[tema07-apendices-metricas]] 
- 
- 
- 
-=====  Metricas en Keras ===== 
-Veamos como calcular en Keras las métricas que necesitamos 
- 
-==== Sensibilidad ==== 
-La sensibilidad en inglés es //Sensibility// pero también se llama //Recall// que es como se usa en Keras. 
- 
-Su uso en Keras es 
-<sxh python> 
-metrics=[tf.keras.metrics.Recall()] 
-metrics=["Recall"] 
-</sxh> 
- 
-y usarla como 
-<sxh python> 
-history.history['recall'] 
-history.history['val_recall'] 
-</sxh> 
- 
-Ejemplo: 
-<sxh python> 
-y_true = np.array([1,1,1,1,1]) 
-y_pred = np.array([0.9, 0.2, 0.3, 0.8,0.6]) 
-metric = tf.keras.metrics.Recall() 
-metric(y_true, y_pred).numpy() 
-</sxh> 
- 
-<sxh python> 
-0.6 
-</sxh> 
- 
-Más información: 
-  * [[https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Recall|Recall class]] 
- 
-==== Especificidad ==== 
-Inexplicablemente esta métrica no existe en keras. Pero la podemos definir con el siguiente código: 
- 
-<sxh python> 
-def specificity(y_true, y_score): 
-    threshold=0.5 
-    y_pred = tf.cast(tf.greater(y_score, threshold), tf.float32) 
- 
- 
-    true_negatives = tf.logical_and(tf.equal(y_true, 0), tf.equal(y_pred, 0)) 
-    num_true_negatives=tf.reduce_sum(tf.cast(true_negatives, tf.float32)) 
- 
- 
-    negatives =tf.equal(y_true, 0) 
-    num_negatives= tf.reduce_sum(tf.cast(negatives, tf.float32)) 
- 
- 
-    specificity = num_true_negatives / (num_negatives + tf.keras.backend.epsilon()) 
-     
-    return specificity 
-</sxh> 
- 
-Su uso en Keras es 
-<sxh python> 
-metrics=[specificity] 
-</sxh> 
- 
-y usarla como 
-<sxh python> 
-history.history['specificity'] 
-history.history['val_specificity'] 
-</sxh> 
- 
-Ejemplo: 
-<sxh python> 
-y_true = np.array([0,0,0,0,0]) 
-y_pred = np.array([0.9, 0.7, 0.3, 0.3,0.6]) 
-specificity(y_true, y_pred).numpy() 
-</sxh> 
- 
-<sxh python> 
-0.4 
-</sxh> 
- 
- 
- 
- 
-==== Area under the curve (AUC) ==== 
-La Area under the curve (AUC) es una métrica que nos dice el área de una curva ROC. Pero pasemos primero a explicar que es una curva ROC. 
- 
-Lo primero es que cuando predecimos que ciertos valores son Positivos o Negativos, lo hacemos en base a un umbral. Normalmente si algo es menor o igual que 0.5 decimos que es ''Negativo'' y si es mayor que 0.5 decimos que es ''Positivo''. Pero ese umbral es arbitrario. 
- 
- 
-En las siguientes gráficas vamos a ver como afecta a nuestro modelo el variar el umbral. 
- 
-{{ :clase:iabd:pia:2eval:metricas_curva_roc_auc.png?direct |}} 
- 
-Vamos a explicar cada columna de la imagen anterior: 
-  * 1º Columna: Se muestra la distribución de los Positivos y los Negativos que ha hecho el modelo. Pero según el umbral podrán ser  True Positive (TP), True Negative (TN),False Positive (FP) y False Negative (FN) 
-  * 2º Columna: Se muestra como evolucionan  los True Positive (TP), True Negative (TN),False Positive (FP) y False Negative (FN) según se modificara el umbral. Para ello para cada umbral entre 0 y 1:  
-    * Se cuenta cuantos Positivos hay bajo el umbral que serán los False Positive (FP) 
-    * Se cuenta cuantos Positivos hay sobre el umbral que serán los True Positive (TP) 
-    * Se cuenta cuantos Negativos hay bajo el umbral que serán los True Negative (TN) 
-    * Se cuenta cuantos Negativos hay sobre el umbral que serán los False Negative (FN) 
-  * 3º Columna: Se calculan las métricas de //True Positive Rate (TPR)// y //False Positive Rate (FPR)// según las siguientes fórmulas: 
- 
- 
-\begin{align} 
-True \: Positive \: Rate \: (TPR) &= \frac{TP}{TP+FN} \\ False \: Positive \: Rate \: (FPR)  &= \frac{FP}{FP+TN} 
-\end{align} 
- 
-  * 4º Columna: Muestra el  //True Positive Rate (TPR)// frente a //False Positive Rate (FPR)//. Es decir que cada punto la ''X'' de la gráfica es el FPR y la ''Y'' de la gráfica es el TPR. 
- 
-Cada una de las filas de la imagen son predicciones distintas, siendo: 
-  * 1º Fila: Una predicción perfecta. 
-  * 2º Fila: Una predicción buena 
-  * 3º Fila: Una predicción mala en la que falla lo mismo que acierta. Sería como hacerlo aleatorio con un 50% de probabilidades de acertar. 
-  * 4º Fila: Una predicción nefasta que falla la mayoría de las veces. 
-  * 5º Fila: Una predicción lamentable que nunca acierta. 
- 
-Entonces, ¿Que es la Area under the curve (AUC)? **Es el área de la curva ROC** es decir el área rosa de las gráficas de la última columna. Si nos fijamos cuanto mejor es la predicción, mayor es el área rosa y por lo tanto mayor es la métrica de AUC. 
- 
-{{ :clase:iabd:pia:2eval:metricas_curva_roc_auc_02.png?direct |}} 
- 
-<note tip> 
-Destacar que se hace uso de la métrica AUC que es una métrica como cualquier otra que tiende a 1 si es buena y a 0 si es mala pero lo que no vas a ver al usar la métrica de AUC es la curva ROC. La curva ROC se muestra para entender que significa la métrica AUC pero no se dibuja normalmente. 
-</note> 
- 
-En keras podemos usar la métrica de AUC de la siguiente forma: 
-Su uso en Keras es 
-<sxh python> 
-metrics=[tf.keras.metrics.AUC()] 
-metrics=["AUC"] 
-</sxh> 
- 
-y usarla como 
-<sxh python> 
-history.history['auc'] 
-history.history['val_auc'] 
-</sxh> 
- 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/classification_metrics/#auc-class|AUC class]] 
-  * [[https://aprendeia.com/curvas-roc-y-area-bajo-la-curva-auc-machine-learning/|Curvas ROC y Área bajo la curva (AUC)]] 
-  * [[https://towardsdatascience.com/an-understandable-guide-to-roc-curves-and-auc-and-why-and-when-to-use-them-92020bc4c5c1|An Understandable Guide to ROC Curves And AUC and Why and When to use them?]] 
-  * [[https://towardsdatascience.com/understanding-auc-roc-curve-68b2303cc9c5|Understanding AUC - ROC Curve]] 
-  * [[https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-classification-in-python/|How to Use ROC Curves and Precision-Recall Curves for Classification in Python]] 
-  * {{ :clase:iabd:pia:2eval:receiver_operating_characteristic_roc_curves._an_analysis_tool_for_detection_performance.pdf |Receiver Operating Characteristic (ROC) Curves: An Analysis Tool for Detection Performance}} 
-  * {{ :clase:iabd:pia:2eval:predicting_receiver_operating_characteristic_curve_area_under_curve_and_arithmetic_means_of_accuracies_based_on_the_distribution_of_data_samples.pdf |Predicting Receiver Operating Characteristic curve, area under curve , and arithmetic means of accuracies based on the distribution of data samples}} 
-  * {{ :clase:iabd:pia:2eval:a_variable_selection_method_for_multiclass_classification_problems_using_two-class_roc_analysis.pdf |A variable selection method for multiclass classification problems using two-class ROC analysis}} 
-  * [[https://neptune.ai/blog/f1-score-accuracy-roc-auc-pr-auc|F1 Score vs ROC AUC vs Accuracy vs PR AUC: Which Evaluation Metric Should You Choose?]] 
-  * [[https://stackoverflow.com/questions/44172162/f1-score-vs-roc-auc|F1 Score vs ROC AUC]]  
- 
- 
- 
-===== Métricas de clasificación con más de 2 posibles valores ===== 
- 
-==== Categorical Accuracy ==== 
-Accuracy nos indica la proporción de aciertos que ha tenido. Es decir el porcentaje (en tanto por uno) de verdaderos positivos y verdaderos negativos 
- 
-Su uso en keras es: 
-<sxh python> 
-metrics=[tf.keras.metrics.CategoricalAccuracy()] 
-metrics=["categorical_accuracy"] 
-</sxh> 
- 
-y usarla como 
-<sxh python> 
-history.history['categorical_accuracy'] 
-history.history['val_categorical_accuracy'] 
-</sxh> 
- 
-Mas información: 
-  * [[https://keras.io/api/metrics/accuracy_metrics/#categoricalaccuracy-class|CategoricalAccuracy class]] 
- 
-===== Ejercicios ===== 
- 
-<note> 
-Para mostrar la matriz de confusión se usará la siguiente función que usa de ''matplotlib'' 
-<sxh python> 
-def plot_matriz_confusion(axes,TP=0,TN=0,FP=0,FN=0,fontsize=15,vpp=None,vpn=None,sensibilidad=None,especificidad=None,f1_score=None,mcc=None,auc=None,prevalencia=None): 
-    success_color=matplotlib.colors.to_rgb('#9EE548') 
-    failure_color=matplotlib.colors.to_rgb("#C32240") 
-    blanco_color=matplotlib.colors.to_rgb("#FFFFFF") 
- 
- 
-    if ((vpp is not None) | 
-        (vpn is not None) | 
-        (sensibilidad is not None) | 
-        (especificidad is not None) | 
-        (prevalencia is not None) | 
-        (f1_score is not None) | 
-        (mcc is not None) | 
-        (auc is not None) ): 
-        show_metrics=True 
-    else: 
-        show_metrics=False 
- 
- 
-    if show_metrics==False: 
-        axes.imshow([[success_color,failure_color],[failure_color,success_color]]) 
-    else: 
-        axes.imshow([[success_color,failure_color,blanco_color],[failure_color,success_color,blanco_color],[blanco_color,blanco_color,blanco_color]]) 
- 
- 
- 
-    labels = ['Positivo','Negativo'] 
-    xaxis = np.arange(len(labels)) 
-    axes.set_xticks(xaxis) 
-    axes.set_yticks(xaxis) 
-    axes.set_xticklabels(labels, fontsize=13, color="#003B80") 
-    axes.set_yticklabels(labels, fontsize=13, color="#003B80") 
-    axes.text(0, 0, str(TP)+" TP",ha="center", va="center", color="#0A2102",fontsize=fontsize) 
-    axes.text(0, 1, str(FP)+" FP",ha="center", va="center", color="#FAEAEA",fontsize=fontsize) 
-    axes.text(1, 0, str(FN)+" FN",ha="center", va="center", color="#FAEAEA",fontsize=fontsize) 
-    axes.text(1, 1, str(TN)+" TN",ha="center", va="center", color="#0A2102",fontsize=fontsize)         
-    axes.xaxis.tick_top() 
-    axes.set_xlabel('Predicción', fontsize=fontsize, color="#003B80") 
-    axes.xaxis.set_label_position('top') 
-    axes.set_ylabel('Realidad', fontsize=fontsize, color="#003B80") 
- 
- 
-    if show_metrics==True: 
- 
- 
-        if (vpp is not None): 
-            axes.text(0, 2, f"Precision\n{vpp:.2f}",ha="center", va="center", color="#0A2102",fontsize=fontsize-4) 
-        if (vpn is not None): 
-            axes.text(1, 2, f"VPN\n{vpn:.2f}",ha="center", va="center", color="#0A2102",fontsize=fontsize-4) 
-        if (sensibilidad is not None): 
-            axes.text(2, 0, f"Sensibilidad\n{sensibilidad:.2f}",ha="center", va="center", color="#0A2102",fontsize=fontsize-4) 
-        if (especificidad is not None): 
-            axes.text(2, 1, f"Especificidad\n{especificidad:.2f}",ha="center", va="center", color="#0A2102",fontsize=fontsize-4) 
- 
-        metricas_generales="" 
-        if (prevalencia is not None): 
-            metricas_generales=metricas_generales+f"Prevalencia\n{prevalencia:.2f}\n"         
-        if (f1_score is not None): 
-            metricas_generales=metricas_generales+f"F1-score\n{f1_score:.2f}\n"   
-        if (mcc is not None): 
-            metricas_generales=metricas_generales+f"MCC\n{mcc:.2f}\n"   
-        if (auc is not None): 
-            metricas_generales=metricas_generales+f"AUC\n{auc:.2f}"             
- 
-        axes.text(2, 2, metricas_generales,ha="center", va="center", color="#0A2102",fontsize=fontsize-4)   
-</sxh> 
- 
-</note> 
- 
-==== Ejercicio 1 ==== 
-Si una red neuronal para detectar si una radiografía es de un tórax ha predicho lo siguiente: 
-  * Para 13 radiografías que eran de tórax , en 8 ha dicho que era un tórax y en 5 ha dicho que no lo era. 
-  * Para 7 radiografías que no eran un tórax , en 4 ha dicho que no era un tórax y en 3 ha dicho que lo era. 
- 
-Indica el nº de: 
-  * Verdaderos Positivos (TP) 
-  * Verdaderos Negativos (TN) 
-  * Falsos Positivos (FP) 
-  * Falsos Negativos (FN) 
- 
-Dibuja la matriz de confusión 
- 
-==== Ejercicio 2.A ==== 
-Seguimos con la red neuronal que predice si una radiografía es de tórax. 
- 
-Si para 10 imágenes ha sacado los siguientes resultados: 
- 
-<sxh python> 
-y_score=np.array([0.27, 0.45,  0.76,  0.55,  0.28, 0.04, 0.34,0.4, 0.66, 0.88, 0.94,0.47,0.2]) 
-</sxh> 
- 
-Indica para cada valor predicho , si ha predicho que era una imagen de tórax o no. 
- 
- 
-==== Ejercicio 2.B ==== 
-Seguimos con la red neuronal que predice si una radiografía es de tórax. 
- 
-Si para 10 imágenes ha sacado los siguientes resultados: 
- 
-<sxh python> 
-y_score=np.array([0.27, 0.45,  0.76,  0.55,  0.28, 0.04, 0.34,0.4, 0.66, 0.88, 0.94,0.47,0.2]) 
-</sxh> 
- 
- 
-Pero los valores verdaderos son los siguientes: 
-<sxh python> 
-y_true=np.array([1,0,1,0,0,0,1,0,1,1,1,1,0]) 
-</sxh> 
- 
- 
-Indica el nº de: 
-  * Verdaderos Positivos (TP) 
-  * Verdaderos Negativos (TN) 
-  * Falsos Positivos (FP) 
-  * Falsos Negativos (FN) 
- 
-Dibuja la matriz de confusión 
- 
-==== Ejercicio 2.C ==== 
-Siguiendo con los datos anteriores y suponiendo que el umbral es 0.5: 
- 
-<sxh python> 
-y_true=np.array([1,0,1,0,0,0,1,0,1,1,1,1,0]) 
-y_score=np.array([0.27, 0.45,  0.76,  0.55,  0.28, 0.04, 0.34,0.4, 0.66, 0.88, 0.94,0.47,0.2]) 
- 
-</sxh> 
- 
-Calcula directamente las siguientes métricas: 
-  * Prevalencia  
-  * Sensibilidad 
-  * Especificidad 
-  * VPP 
-  * VPN 
-  
- 
-==== Ejercicio 2.D ==== 
-Calcula ahora los valores de: 
-  * VPP 
-  * VPN 
- 
-pero usando el teorema de bayes en base a los valores de: 
-  * Prevalencia  
-  * Sensibilidad 
-  * Especificidad 
- 
-==== Ejercicio 2.E ==== 
-Muestra ahora una gráfica con matplolib en la que se vea como evolucionan los valores de VPP y VPN según la prevalencia. 
- 
-Esa misma gráfica se puede mostrar en [[https://kennis-research.shinyapps.io/Bayes-App/|Bayesian Clinical Diagnostic Model]] 
- 
-{{:clase:iabd:pia:2eval:prevalencia-sensibilidad-especificidad.png?direct|}} 
- 
-==== Ejercicio 3.A ==== 
-Crea una red neuronal con los datos de //bread cancer// con las siguientes características: 
- 
-  * neuronas por capa:''[30,64,32,16,8,1]'' 
-  * Función de activation: ''ELU'' 
-  * Nº de epocas: ''20'' 
-  * Optimizador: ''Adam'' con tasa de aprendizaje de ''0,0001'' 
- 
-Muestra las siguientes métricas durante el entrenamiento (para cada una de las épocas): 
-  * Loss 
-  * Sensibilidad 
-  * Especificidad 
- 
-{{:clase:iabd:pia:2eval:metricas-epocas.png?direct|}} 
- 
-==== Ejercicio 3.B ==== 
-En este ejercicio vamos a mostrar la matriz de confusión de la red que acabamos de crear. 
- 
-Para ello vamos a usar los valores de test que los tenemos en las siguientes variables del ejercicio anterior: 
-  * ''x_test'' 
-  * ''y_test'' 
- 
-La variable ''y_test'' es lo que llamamos ''y_true'' mientras que con ''x_test'' obtendremos ''y_score''. 
- 
-Para ello sigue los siguientes pasos: 
-  * Crea una función llamada ''get_matriz_confusion(y_true,y_score,threshold)'' que retorne ''TP'' ,''TN'', ''FP'' y ''FN'' 
-  * Calcula ''y_score'' usando el método ''predict'' del modelo y usando la variable ''x_test'' 
-  * Haz que ''y_true'' sea igual a ''y_test'' 
-  * Llama a la función ''get_matriz_confusion'' 
-  * Muestra la matriz de confusión  
- 
-==== Ejercicio 3.C ==== 
-Crea una función llamada ''get_metrics(TP,TN,FP,FN,Prevalencia=None)'' que retorne las siguientes métricas: 
-  * Sensibilidad 
-  * Especificidad 
-  * VPP 
-  * VPN 
-  * Prevalencia 
- 
-Para calcular VPP y VPN se debe usar la prevalencia. Si no se pasa el valor de prevalencia ( Es decir 'prevalencia==None', se usará el de los datos y sino se usará la prevalencia que se pase como argumento. 
- 
- 
-Usando los valores de ''TP'' ,''TN'', ''FP'' y ''FN'' del ejercicio anterior, muestra las métricas que retorna ''get_metrics'' 
- 
-Muestra todo en la matriz de confusión. 
- 
-==== Ejercicio 3.D ==== 
-Guarda el modelo a disco 
- 
-  
- 
-==== Ejercicio 3.E ==== 
-En un nuevo jupyter notebook, carga el modelo y con los datos de test , vuelve a mostrar la matriz de confusión con todas las métricas. 
- 
- 
- 
-==== Ejercicio 3.F ==== 
-Muestra ahora 1 gráfica, en la que se mostrará: 
- 
-  * El valor de la sensibilidad y la especificidad según el valor del umbral 
- 
-{{:clase:iabd:pia:2eval:threshold-metricas.png?direct|}} 
- 
-¿Que valor de umbral dejarías? 
- 
-==== Ejercicio 3.G ==== 
-Muestra una gráfica similar a las anteriores pero ahora sea la suma los valores de sensibilidad y la especificidad menos 1.  
- 
-A la suma de los 2 valores para obtener el máximo pero restando 1 se le llama Informedness 
- 
-$$ 
-Informedness=Sensibilidad+Especificidad-1 
-$$ 
- 
-Muestra un punto con el máximo de la gráfica y el threshold correspondiente al máximo.Además para ese nivel de threshold, **imprime la sensibilidad y la especificidad** 
- 
-{{:clase:iabd:pia:2eval:threshold-markedness-informedness.png?direct|}} 
- 
- 
- 
-==== Ejercicio 4 ==== 
-Indica en los siguientes problemas si subirías o bajarías el umbral 
- 
-  * Una IA que detecta si hay petroleo en el subsuelo 
-  * Una IA que predice si un usuario en Amazon está cometiendo fraude 
-  * Una IA que decide si te concede un préstamo 
-  * Una IA que decide una persona en un juicio es inocente 
-  * Una IA que corrige automáticamente un examen y te dice si has aprobado 
- 
- 
- 
-==== Ejercicio 5.A ==== 
-Crea una nueva red neuronal para el problema del //bread cancer// 
- 
-Ahora razona con cual de las 2 redes te quedarías y que threshold elegirías para cada uno de ellos. 
- 
-Para elegir debes mostrar gráficas , una al lado de la otra para comparar lo siguiente: 
-  * Gráficos de perdida, sensibilida y especificidad durante el entrenamiento 
-  * Matriz de confusión con las métricas: Sensibilidad, Especificidad, VPP, VPN, Prevalencia 
-  * Threshold vs (Sensibilidad y Especificidad) 
-  * Threshold vs Informedness (Muestra en el label el máximo) 
- 
- 
-¿Con que red te quedarías? 
- 
-{{:clase:iabd:pia:2eval:comparar_redes.png?direct|}} 
- 
-Además para el nivel de threshold de la red que ha "ganado", **imprime la sensibilidad y la especificidad** 
- 
-==== Ejercicio 5.B ==== 
-Con el modelo elegido, guarda el modelo a disco 
- 
- 
-==== Ejercicio 5.C ==== 
-Con modelo que has elegido, cargalo en otro Jupyter notebook y realiza inferencia de 10 pacientes.  
- 
-Para cada paciente: 
-  * Indica su prevalencia (te la tienes que inventar de forma aleatoria) 
-  * Indica la probabilidad de que la red haya acertado. 
- 
  
clase/iabd/pia/2eval/tema07.metricas.1710882756.txt.gz · Última modificación: 2024/03/19 22:12 por admin