Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
clase:iabd:pia:2eval:tema08.metricas_clasificacion [2025/02/15 17:23] admin [Ejercicios] |
clase:iabd:pia:2eval:tema08.metricas_clasificacion [2025/02/26 20:11] (actual) admin [Ejercicios] |
||
---|---|---|---|
Línea 359: | Línea 359: | ||
<sxh python> | <sxh python> | ||
metrics=[tf.keras.metrics.Recall()] | metrics=[tf.keras.metrics.Recall()] | ||
- | metrics=[" | + | metrics=[" |
</ | </ | ||
Línea 367: | Línea 367: | ||
history.history[' | history.history[' | ||
</ | </ | ||
+ | |||
+ | <note important> | ||
+ | En versiones antiguas de Tensorflow, se llamaba '' | ||
+ | </ | ||
Ejemplo: | Ejemplo: | ||
Línea 387: | Línea 391: | ||
<sxh python> | <sxh python> | ||
- | def specificity(y_true, | ||
- | threshold=0.5 | ||
- | y_pred = tf.cast(tf.greater(y_score, | ||
+ | from tensorflow.keras import backend as K | ||
- | true_negatives = tf.logical_and(tf.equal(y_true, 0), tf.equal(y_pred, 0)) | + | def specificity(y_true, |
- | | + | |
+ | y_true = K.cast(y_true, dtype=' | ||
+ | | ||
- | negatives =tf.equal(y_true, | ||
- | num_negatives= tf.reduce_sum(tf.cast(negatives, | ||
+ | y_true = tf.reshape(y_true, | ||
+ | y_pred = tf.reshape(y_pred, | ||
+ | |||
+ | |||
+ | TN = K.sum((1 - y_true) * (1 - y_pred)) | ||
+ | FP = K.sum((1 - y_true) * y_pred) | ||
+ | |||
+ | specificity = TN / (TN + FP + K.epsilon()) | ||
- | specificity = num_true_negatives / (num_negatives + tf.keras.backend.epsilon()) | ||
- | | ||
return specificity | return specificity | ||
</ | </ | ||
Línea 427: | Línea 435: | ||
</ | </ | ||
+ | El motivo de éstas 2 líneas de código | ||
+ | <sxh python> | ||
+ | TN = K.sum((1 - y_true) * (1 - y_pred)) | ||
+ | FP = K.sum((1 - y_true) * y_pred) | ||
+ | </ | ||
+ | se puede ver en la siguiente tabla de verdad: | ||
+ | |||
+ | ^ Entradas | ||
+ | ^ '' | ||
+ | | 1 | ||
+ | | 0 | ||
+ | | 0 | ||
+ | | 1 | ||
+ | |||
+ | |||
+ | Y se puede calcular de 2 maneras distintas: | ||
+ | |||
+ | * Aritméticamente | ||
+ | |||
+ | <sxh python> | ||
+ | TP = sum(y_true * y_pred) | ||
+ | TN = sum((1 - y_true) * (1 - y_pred)) | ||
+ | FP = sum((1 - y_true) * y_pred) | ||
+ | FN = sum(y_true * (1 - y_pred)) | ||
+ | </ | ||
+ | |||
+ | |||
+ | * Lógicamente | ||
+ | <sxh python> | ||
+ | TP = sum((y_true==1) & (y_pred==1)) | ||
+ | TN = sum((y_true==0) & (y_pred==0)) | ||
+ | FN = sum((y_true==1) & (y_pred==0)) | ||
+ | FP = sum((y_true==0) & (y_pred==1)) | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
Línea 456: | Línea 501: | ||
Para mostrar la matriz de confusión se usará la siguiente función que usa de '' | Para mostrar la matriz de confusión se usará la siguiente función que usa de '' | ||
<sxh python> | <sxh python> | ||
- | def plot_matriz_confusion(axes, | + | def plot_matriz_confusion(axes, |
success_color=matplotlib.colors.to_rgb('# | success_color=matplotlib.colors.to_rgb('# | ||
failure_color=matplotlib.colors.to_rgb("# | failure_color=matplotlib.colors.to_rgb("# | ||
Línea 462: | Línea 507: | ||
- | if ((vpp is not None) | | + | if ((vpp is not None) | |
- | (vpn is not None) | | + | (vpn is not None) | |
(sensibilidad is not None) | | (sensibilidad is not None) | | ||
- | (especificidad is not None) | | + | (especificidad is not None) | |
(prevalencia is not None) | | (prevalencia is not None) | | ||
- | (f1_score is not None) | | + | (f1_score is not None) | |
(mcc is not None) | | (mcc is not None) | | ||
(auc is not None) ): | (auc is not None) ): | ||
Línea 481: | Línea 526: | ||
+ | if titulo==None: | ||
+ | titulo=" | ||
+ | else: | ||
+ | titulo=titulo+" | ||
labels = [' | labels = [' | ||
Línea 489: | Línea 538: | ||
axes.set_yticklabels(labels, | axes.set_yticklabels(labels, | ||
axes.text(0, | axes.text(0, | ||
- | axes.text(0, | + | axes.text(0, |
axes.text(1, | axes.text(1, | ||
- | axes.text(1, | + | axes.text(1, |
axes.xaxis.tick_top() | axes.xaxis.tick_top() | ||
- | axes.set_xlabel(' | + | axes.set_xlabel(titulo, fontsize=fontsize, |
- | axes.xaxis.set_label_position(' | + | axes.xaxis.set_label_position(' |
- | axes.set_ylabel(' | + | axes.set_ylabel(' |
Línea 506: | Línea 555: | ||
axes.text(1, | axes.text(1, | ||
if (sensibilidad is not None): | if (sensibilidad is not None): | ||
- | axes.text(2, | + | axes.text(2, |
if (especificidad is not None): | if (especificidad is not None): | ||
- | axes.text(2, | + | axes.text(2, |
metricas_generales="" | metricas_generales="" | ||
Línea 514: | Línea 563: | ||
metricas_generales=metricas_generales+f" | metricas_generales=metricas_generales+f" | ||
if (f1_score is not None): | if (f1_score is not None): | ||
- | metricas_generales=metricas_generales+f" | + | metricas_generales=metricas_generales+f" |
if (mcc is not None): | if (mcc is not None): | ||
metricas_generales=metricas_generales+f" | metricas_generales=metricas_generales+f" | ||
if (auc is not None): | if (auc is not None): | ||
- | metricas_generales=metricas_generales+f" | + | metricas_generales=metricas_generales+f" |
- | axes.text(2, | + | axes.text(2, |
</ | </ | ||
Línea 611: | Línea 660: | ||
Crea una red neuronal con los datos de //bread cancer// con las siguientes características: | Crea una red neuronal con los datos de //bread cancer// con las siguientes características: | ||
- | * neuronas por capa:'' | + | * neuronas por capa:'' |
- | * Función de activation: '' | + | * Función de activation: '' |
- | * Nº de epocas: '' | + | * Nº de epocas: '' |
- | * Optimizador: | + | * Optimizador: |
Muestra las siguientes métricas durante el entrenamiento y validación (para cada una de las épocas): | Muestra las siguientes métricas durante el entrenamiento y validación (para cada una de las épocas): | ||
Línea 634: | Línea 683: | ||
En este ejercicio vamos a mostrar la matriz de confusión de la red que acabamos de crear. | 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: | + | Para ello vamos a usar los valores de validación |
- | * '' | + | * '' |
- | * '' | + | * '' |
- | La variable '' | + | La variable '' |
Para ello sigue los siguientes pasos: | Para ello sigue los siguientes pasos: | ||
* Crea una función llamada '' | * Crea una función llamada '' | ||
* Crea una función llamada '' | * Crea una función llamada '' | ||
- | * Calcula '' | + | * Calcula '' |
- | * Haz que '' | + | * Haz que '' |
* Llama a la función '' | * Llama a la función '' | ||
* Muestra la matriz de confusión | * Muestra la matriz de confusión | ||
Línea 684: | Línea 733: | ||
{{: | {{: | ||
- | ¿Qué valor de umbral dejarías? Elige uno que no sea '' | ||
<note important> | <note important> | ||
Línea 692: | Línea 740: | ||
==== Ejercicio 5.B ==== | ==== Ejercicio 5.B ==== | ||
- | Vuelve a mostrar la matriz | + | Muestra varias matrices |
+ | {{: | ||
+ | |||
+ | |||
+ | ¿Que es mejor una alta precisión alta (VPP) o un alto VPN? Elije el umbral | ||
<note important> | <note important> | ||
Usa los datos de **test** para obtener las métricas. | Usa los datos de **test** para obtener las métricas. | ||
</ | </ | ||
+ | |||
+ | ==== Ejercicio 5.C ==== | ||
+ | Ahora calcula una tabla similar a esta para ver resultado de 8 pacientes. | ||
+ | |||
+ | <sxh python> | ||
+ | Paciente | ||
+ | | ||
+ | ---------- | ||
+ | Nº 347 0.32628 | ||
+ | Nº 270 0.95804 | ||
+ | Nº 213 0.958995 | ||
+ | Nº 3 0.31489 | ||
+ | Nº 214 0.286227 | ||
+ | Nº 265 0 | ||
+ | Nº 92 | ||
+ | Nº 476 0.275804 | ||
+ | </ | ||
+ | |||
+ | Responde ahora a estas preguntas: | ||
+ | * ¿Que tiene de extraño el valor de algunos resultados? | ||
+ | * ¿Es útil el '' | ||
+ | * Porque $P(Enfermo|Positivo)=VPP=Precisión$ es siempre la misma? | ||
+ | * Porque $P(Sano|Negativo)=VPN$ es siempre la misma? | ||
+ | |||
+ | Para saber con que pacientes debe probar concretamente en tu modelo, usa la función '' | ||
+ | |||
+ | <sxh python> | ||
+ | def get_paciente_a_probar(indices, | ||
+ | y_pred_values = y_pred[indices] | ||
+ | sorted_indices = indices[0][np.argsort(order*y_pred_values)] | ||
+ | |||
+ | return sorted_indices[0] | ||
+ | |||
+ | def get_pacientes_a_probar(model): | ||
+ | breast_cancer=load_breast_cancer() | ||
+ | tolerancia=0.07 | ||
+ | desc=-1 | ||
+ | asc=1 | ||
+ | numeros_pacientes=[] | ||
+ | |||
+ | y_pred=model.predict(breast_cancer.data, | ||
+ | |||
+ | #TP Malo: | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==1) & (y_pred> | ||
+ | #TP Bueno | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==1) & (y_pred> | ||
+ | |||
+ | #FP Malo | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==0) & (y_pred> | ||
+ | #FP Casi bueno | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==0) & (y_pred> | ||
+ | |||
+ | #TN Malo | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==0) & (y_pred> | ||
+ | #TN Bueno | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==0) & (y_pred> | ||
+ | |||
+ | #FN Malo | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==1) & (y_pred> | ||
+ | #FN Casi bueno | ||
+ | numeros_pacientes.append(get_paciente_a_probar(np.where((breast_cancer.target==1) & (y_pred> | ||
+ | |||
+ | return numeros_pacientes | ||
+ | </ | ||
==== Ejercicio 6 ==== | ==== Ejercicio 6 ==== | ||
- | Indica en los siguientes problemas si subirías | + | Indica en los siguientes problemas si es mejor una precisión alta (VPP) o un alto VPN |
* Una IA que detecta si hay petroleo en el subsuelo | * Una IA que detecta si hay petroleo en el subsuelo | ||
Línea 705: | Línea 821: | ||
* Una IA que decide si te concede un préstamo | * Una IA que decide si te concede un préstamo | ||
* Una IA que decide una persona en un juicio es inocente | * 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 | + | * Una IA que corrige automáticamente un examen y dice si se ha aprobado |
- | |||
- | ==== Ejercicio 7 ==== | ||
- | Haz ahora un pequeño programa en modo texto en python en el que: | ||
- | * Se pregunte al usuario los datos del "// | ||
- | * Para facilitar la entrada que ponga valores por defecto para cada //x// y que indique el rango que tenemos en los posibles valores. | ||
- | * La prevalencia. Si la deja en blanco serán las de los datos | ||
- | * Que indique si tiene o no cáncer. | ||
- | * Si tiene cáncer que indique al usuario la probabilidad de que esta IA haya acertado (VPP) | ||
- | * Si no tiene cáncer que indique al usuario la probabilidad de que esta IA haya acertado (VPN) | ||
- | |||
- | <note important> | ||
- | Ahora hazte las siguientes preguntas | ||
- | * ¿Deberíamos haber preguntado al usuario el umbral? | ||
- | * ¿Deberíamos mostrar al usuario el '' | ||
- | </ | ||