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:tema07-apendices [2022/03/17 19:58] admin [Backpropagation] |
clase:iabd:pia:2eval:tema07-apendices [2024/03/19 17:04] (actual) admin [Más métricas] |
||
---|---|---|---|
Línea 1: | Línea 1: | ||
- | ====== 7. Entrenamiento de redes neuronales | + | ====== 7. Entrenamiento de redes neuronales |
===== Tipos de funciones de coste ===== | ===== Tipos de funciones de coste ===== | ||
Línea 60: | Línea 60: | ||
===== Creación de los gráficos del descenso de gradiente ===== | ===== Creación de los gráficos del descenso de gradiente ===== | ||
- | Pasemos | + | Durante el tema hemos visto los gráficos que explican el descenso de gradiente. Veamos |
- | Como ejemplo vamos a seguir | + | La función que coste que hemos usado es la siguiente |
$$ | $$ | ||
- | loss=3(1-w_0)^2e^{-w_0^2-(w_1+1)^2}-10(\frac{w_0}{5}-w_0^3-w_1^5)e^{-w_0^2-w_1^2}-\frac{1}{3}e^{-(w_0+1)^2-w_1^2} | + | loss(w_0,w_1)=3(1-w_0)^2e^{-w_0^2-(w_1+1)^2}-10(\frac{w_0}{5}-w_0^3-w_1^5)e^{-w_0^2-w_1^2}-\frac{1}{3}e^{-(w_0+1)^2-w_1^2} |
$$ | $$ | ||
Línea 73: | Línea 73: | ||
- | El siguiente código | + | En python |
<sxh python> | <sxh python> | ||
def loss(w_0, | def loss(w_0, | ||
return | return | ||
+ | </ | ||
+ | Y el algoritmo que calcula cada uno de los $w_0,w_1$ del descenso de gradiente es el siguiente: | ||
- | def get_puntos_descenso_gradiente(w_0_init, | + | <sxh python> |
+ | def get_puntos_descenso_gradiente(epochs, | ||
- | | + | |
+ | w_1=w_1_original | ||
- | w_0=w_0_init | + | |
- | | + | |
| | ||
- | for i in range(steps): | + | for epoch in range(epochs): |
h=0.00001 | h=0.00001 | ||
- | | + | |
- | | + | gradiente_w_0=(loss(w_0+h, |
+ | | ||
#Nuevos valores de los pesos | #Nuevos valores de los pesos | ||
- | w_0=w_0-learning_rate*derivada_w_0 | + | w_0=w_0-learning_rate*gradiente_w_0 |
- | w_1=w_1-learning_rate*derivada_w_1 | + | w_1=w_1-learning_rate*gradiente_w_1 |
puntos_descenso_gradiente=np.append(puntos_descenso_gradiente, | puntos_descenso_gradiente=np.append(puntos_descenso_gradiente, | ||
Línea 103: | Línea 107: | ||
- | Si lo ejecutamos | + | Si ejecutamos lo siguiente: |
- | + | ||
- | \begin{align} | + | |
- | w_0 &= -0.35 \\ | + | |
- | w_1 &= -0.67 \\ | + | |
- | learning \: \: rate &= 0.03 \\ | + | |
- | steps &= 5 | + | |
- | \end{align} | + | |
- | + | ||
- | + | ||
- | <note tip>La variable '' | + | |
- | En Keras los '' | + | |
- | + | ||
- | Es decir llamando a la función así: | + | |
<sxh python> | <sxh python> | ||
- | get_puntos_descenso_gradiente(-0.35,-0.67,0.03,5) | + | get_puntos_descenso_gradiente(5,0.03,-0.35,-0.67) |
</ | </ | ||
- | Saldría la siguiente imagen: | + | El resultado es: |
+ | <sxh base> | ||
+ | array([[-0.35 | ||
+ | | ||
+ | | ||
+ | [ 0.0654496 , -1.06459902], | ||
+ | [ 0.24087009, -1.40749396], | ||
+ | [ 0.2657862 , -1.59573582]]) | ||
+ | </ | ||
- | {{ : | + | Que son cada uno de los valores de $w_0,w_1$ que empiezan en '' |
- | + | Pasamos ahora a mostrar | |
- | < | + | |
- | * La estrella roja es desde donde empieza el algoritmo. | + | |
- | * La estrella azul es donde acaba el algoritmo | + | |
- | * Los puntos amarillo son los //pasos// por lo que se va moviendo el algoritmo | + | |
- | </ | + | |
- | + | ||
- | Para poder hacer estas gráficas, hemos creado 2 funciones: | + | |
* '' | * '' | ||
- | * '' | + | * '' |
<sxh python> | <sxh python> | ||
Línea 158: | Línea 150: | ||
</ | </ | ||
+ | Si ejecutamos el código: | ||
+ | <sxh python> | ||
+ | figure=plt.figure(figsize=(16, | ||
+ | axes = figure.add_subplot() | ||
+ | plot_loss_function(axes) | ||
+ | |||
+ | plot_descenso_gradiente(axes, | ||
+ | </ | ||
+ | |||
+ | Vemos la siguiente gráfica donde se muestran los puntos que hemos obtenido de la función '' | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | |||
+ | < | ||
+ | * La estrella roja es desde donde empieza el algoritmo.Es decir, el valor inicial de los parámetros $w_0,w_1$ | ||
+ | * La estrella azul es donde acaba el algoritmo.Es decir, el valor tras el entrenamiento de los parámetros $w_0,w_1$ | ||
+ | * Los puntos amarillo son los //pasos// por lo que se va moviendo el algoritmo. Cada uno de los valores intermedios de los parámetros durante el entrenamiento. | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Optimizadores de Keras ==== | ||
+ | | ||
- | Y ahora el programa que usa las 4 funciones y que dibuja la gráfica es el siguiente: | ||
+ | <sxh python> | ||
+ | def loss_tf(w_0, | ||
+ | return | ||
+ | |||
+ | def get_puntos_descenso_gradiente_optimizer(epochs, | ||
+ | |||
+ | puntos_descenso_gradiente=np.array([[w_0_init, | ||
+ | |||
+ | w_0=w_0_init | ||
+ | w_1=w_1_init | ||
+ | for epoch in range(epochs): | ||
+ | var_w_0=tf.Variable(w_0) | ||
+ | var_w_1=tf.Variable(w_1) | ||
+ | |||
+ | optimizer_function.minimize(lambda: | ||
+ | optimizer_function.minimize(lambda: | ||
+ | |||
+ | w_0=var_w_0.numpy() | ||
+ | w_1=var_w_1.numpy() | ||
+ | |||
+ | puntos_descenso_gradiente=np.append(puntos_descenso_gradiente, | ||
+ | |||
+ | return puntos_descenso_gradiente | ||
+ | </ | ||
+ | |||
+ | Lo que ha cambiado principalmente es la función '' | ||
+ | |||
+ | |||
+ | Si usamos '' | ||
+ | <sxh python> | ||
+ | get_puntos_descenso_gradiente_optimizer(5, | ||
+ | </ | ||
+ | <sxh base> | ||
+ | array([[-0.35 | ||
+ | | ||
+ | | ||
+ | [ 0.06544246, -1.06462073], | ||
+ | [ 0.24086528, -1.40752137], | ||
+ | [ 0.26578248, -1.59573841]]) | ||
+ | </ | ||
+ | Vamos que el resultado es prácticamente el mismo que cuando lo hicimos manualmente. | ||
+ | |||
+ | Y podemos generar de la misma forma el gráfico: | ||
<sxh python> | <sxh python> | ||
figure=plt.figure(figsize=(16, | figure=plt.figure(figsize=(16, | ||
Línea 167: | Línea 224: | ||
plot_loss_function(axes) | plot_loss_function(axes) | ||
- | plot_descenso_gradiente(axes, | + | plot_descenso_gradiente(axes, |
</ | </ | ||
+ | |||
+ | |||
+ | {{ : | ||
+ | |||
+ | Y obviamente el resultado es el mismo | ||
+ | |||
+ | ===== Métricas ===== | ||
+ | Las métricas que ya las hemos explicado en el tema de métricas son: | ||
+ | * Métricas básicas (Sensibilidad, | ||
+ | * Métricas derivadas según el teorema de bayes (PPV,NPV, FDR y FOR) | ||
+ | |||
+ | Las métricas que ahora vamos a ver son métricas que hacen la media entre alguna de las dos métricas que acabamos de indicar. | ||
+ | |||
+ | Para organizar las métricas según 2 criterios: | ||
+ | * Según que métricas juntan | ||
+ | * Métricas básicas (Sensibilidad, | ||
+ | * Métricas derivadas (PPV,NPV, FDR y FOR) | ||
+ | * Métricas mixtas, que usa una básica y otra derivada. | ||
+ | * Según la fórmula que usan: | ||
+ | * Media aritmética | ||
+ | * Media armónica | ||
+ | * Media geométrica | ||
+ | * L1-Norma | ||
+ | * L2-Norma | ||
+ | * Ratio | ||
+ | ==== Juntado dos Métricas Básicas ==== | ||
+ | ^ ^ Fórmula que usan ^^^^^^ | ||
+ | ^ Métricas básicas que usan ^ Media aritmética | ||
+ | | Sensibilidad (TPR) y Especificidad (TNR) | | | | $Informedness=TPR+TNR-1$ | ||
+ | | Sensibilidad (TPR) y FPR | | | | | | ||
+ | | Especificidad (TNR) y FNR | | | | | | ||
+ | | FPR y FNR | | | | ||
+ | |||
+ | |||
+ | ==== Juntado dos Métricas derivadas ==== | ||
+ | |||
+ | ^ ^ Fórmula que usan ^^^^^^ | ||
+ | ^ Métricas básicas que usan ^ Media aritmética | ||
+ | | PPV y NPV | | | | $Markdness=PPV+NPV-1$ | | | | ||
+ | | PPV y FOR | | | | | ||
+ | | NPV y FDR | | | | | ||
+ | | FDR y FOR | | | | | ||
+ | |||
+ | |||
+ | ==== Métricas mixtas ==== | ||
+ | Son métricas que juntan una métrica básica con una métrica derivada. Debido a que existen 16 combinaciones no vamos a mostrar todas las que existen, sino solo las que he considerado interesantes. | ||
+ | |||
+ | * La siguiente tabla son métricas que existen (Tienen nombre) | ||
+ | |||
+ | ^ ^ Fórmula que usan ^^^^^^ | ||
+ | ^ Métricas básicas que usan ^ Media aritmética | ||
+ | | PPV y Sensibilidad (TPR) | | $F_{1}score=\frac{2}{\frac{1}{PPV}+\frac{1}{TPR}}$ | ||
+ | | NPV y Especificidad (TNR) | | | | | ||
+ | |||
+ | ===== Más métricas ===== | ||
+ | |||
+ | |||
+ | ==== Indice Jaccard ==== | ||
+ | Este índice es la división entre 2 probabilidades: | ||
+ | |||
+ | $$ | ||
+ | Indice \; Jaccard=\frac{P(Positivo \cap Enfermo)}{P(Positivo \cup Enfermo)}=\frac{TP}{TP+FP+FN} | ||
+ | $$ | ||
+ | |||
+ | * Se deduce de la siguiente forma: | ||
+ | |||
+ | $$ | ||
+ | \frac{P(Positivo \cap Enfermo)}{P(Positivo \cup Enfermo)}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo)+P(Enfermo)-P(Positivo \cap Enfermo)}=\frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo)+P(Enfermo)-P(Positivo|Enfermo)*P(Enfermo)} | ||
+ | $$ | ||
+ | |||
+ | * Sabiendo que: | ||
+ | |||
+ | $$ | ||
+ | |||
+ | \begin{array} | ||
+ | \\ | ||
+ | P(Enfermo)& | ||
+ | \\ | ||
+ | |||
+ | |||
+ | |||
+ | P(Sano)& | ||
+ | \\ | ||
+ | P(Positivo)& | ||
+ | \\ | ||
+ | P(Negativo)& | ||
+ | \\ | ||
+ | P(Positivo|Enfermo)& | ||
+ | \end{array} | ||
+ | $$ | ||
+ | |||
+ | * Entonces: | ||
+ | |||
+ | $$ | ||
+ | \frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo)+P(Enfermo)-P(Positivo|Enfermo)*P(Enfermo)}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \left ( \frac{TP}{TP+FN}*\frac{TP+FN}{TP+FN+FP+TN} \right ) \div \left (\frac{TP+FP}{TP+FN+FP+TN}+\frac{TP+FN}{TP+FN+FP+TN}-\frac{TP}{TP+FN}*\frac{TP+FN}{TP+FN+FP+TN} \right )= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \left ( \frac{TP}{TP+FN+FP+TN} \right ) \div \left (\frac{TP+FP}{TP+FN+FP+TN}+\frac{TP+FN}{TP+FN+FP+TN}-\frac{TP}{TP+FN+FP+TN} \right )= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \left ( \frac{TP}{TP+FN+FP+TN} \right ) \div \left (\frac{TP+FP+TP+FN-TP}{TP+FN+FP+TN} \right )=\left ( \frac{TP}{TP+FN+FP+TN} \right ) \div \left (\frac{TP+FP+FN}{TP+FN+FP+TN} \right )= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \frac{TP}{TP+FP+FN}=Indice \; Jaccard | ||
+ | $$ | ||
+ | |||
+ | * Sin embargo también podemos definir el Indice Jaccard en función de la sensibilidad, | ||
+ | |||
+ | $$ | ||
+ | P(Positivo)=\frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Enfermo|Positivo)}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \frac{P(Positivo|Enfermo)*P(Enfermo)}{1} \div \frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo|Enfermo)*P(Enfermo)+P(Positivo|Sano)*P(Sano)}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | Sensibilidad*Prevalencia+(1-Especificidad)*(1-Prevalencia) | ||
+ | $$ | ||
+ | |||
+ | |||
+ | * Y ahora usamos la formula de P(Positivo) en la definición del Indice Jaccard | ||
+ | |||
+ | $$ | ||
+ | Indice \; Jaccard=\frac{P(Positivo|Enfermo)*P(Enfermo)}{P(Positivo)+P(Enfermo)-P(Positivo|Enfermo)*P(Enfermo)}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \frac{Sensibilidad*Prevalencia}{Sensibilidad*Prevalencia+(1-Especificidad)*(1-Prevalencia)+Prevalencia-Sensibilidad*Prevalencia}= | ||
+ | $$ | ||
+ | |||
+ | $$ | ||
+ | \frac{Sensibilidad*Prevalencia}{(1-Especificidad)*(1-Prevalencia)+Prevalencia} | ||
+ | $$ | ||
+ | |||
+ | * Por lo tanto | ||
+ | |||
+ | $$ | ||
+ | Indice \; Jaccard=\frac{Sensibilidad*Prevalencia}{(1-Especificidad)*(1-Prevalencia)+Prevalencia} | ||
+ | $$ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Prevalence threshold ==== | ||
+ | La métrica de Prevalence threshold está explicada en [[https:// | ||
+ | |||
+ | Lo único que diremos respecto a la formula es que en el artículo aparece como: | ||
+ | |||
+ | $$ | ||
+ | Prevalence \; threshold=\frac{\sqrt{Sensibilidad(1-Especificidad)}+(Especificidad-1)}{Sensibilidad+Especificidad+1} | ||
+ | $$ | ||
+ | Que jugando un poco con los signos se obtiene la formula equivalente que aparece en Wikipedia: | ||
+ | $$ | ||
+ | Prevalence \; threshold=\frac{\sqrt{Sensibilidad*FPR}-FPR}{Sensibilidad-FPR} | ||
+ | $$ | ||
+ | |||
+ | ==== Diagnostic odds ratio ==== | ||
+ | Se define como la división entre //Positive likelihood ratio (LR+)// y //Negative likelihood ratio (LR-)// | ||
+ | |||
+ | $$ | ||
+ | DOR=\frac{LR+}{LR-}=\frac{TP*TN}{FP*FN} | ||
+ | $$ | ||
+ | |||
+ | * Aunque también se puede definir en función de la sensibilidad y la especificidad | ||
+ | |||
+ | $$ | ||
+ | DOR=\frac{LR+}{LR-}=\frac{\frac{TPR}{1-TNR}}{\frac{1-TPR}{TNR}}=\frac{Sensibilidad*Especificidad}{(1-Sensibilidad)(1-Especificidad)} | ||
+ | $$ | ||
+ | |||
+ | ==== Matthews Correlation Coefficient o MMC ==== | ||
+ | Es otra métrica pero que tiene en cuenta que los datos no estén balanceados. | ||
+ | |||
+ | El MMC tiene un valor entre -1 a 1. Siendo: | ||
+ | * 1 : El clasificador funciona perfectamente | ||
+ | * 0 : El clasificador acierta aleatoriamente | ||
+ | * -1 : El clasificador acierta peor que aleatoriamente, | ||
+ | |||
+ | $$MCC = \frac{ \mathit{TP} \times \mathit{TN} - \mathit{FP} \times \mathit{FN} } {\sqrt{ (\mathit{TP} + \mathit{FP}) ( \mathit{TP} + \mathit{FN} ) ( \mathit{TN} + \mathit{FP} ) ( \mathit{TN} + \mathit{FN} ) } }$$ | ||
+ | |||
+ | |||
+ | Podemos hacer uso de la métrica con la función '' | ||
+ | |||
+ | Ejemplo de uso: | ||
+ | <sxh python> | ||
+ | from sklearn.metrics import matthews_corrcoef | ||
+ | |||
+ | y_true = [1, | ||
+ | y_pred = [1, | ||
+ | print(" | ||
+ | |||
+ | y_true = [1, | ||
+ | y_pred = [1, | ||
+ | print(" | ||
+ | |||
+ | y_true = [1, | ||
+ | y_pred = [0, | ||
+ | print(" | ||
+ | </ | ||
+ | |||
+ | |||
+ | <sxh base> | ||
+ | Valor para una predicción que acierta siempre= 1.0 | ||
+ | Valor para una predicción que acierta la mitad= 0.0 | ||
+ | Valor para una predicción que nunca acierta= -1.0 | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Mas información: | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * {{ : | ||
+ | * [[https:// | ||
+ | |||