Herramientas de usuario

Herramientas del sitio


clase:iabd:pia:2eval:tema08.intervalo_confianza

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:tema08.intervalo_confianza [2024/05/09 17:22]
admin [Cálculo del intervalo de confianza]
clase:iabd:pia:2eval:tema08.intervalo_confianza [2024/05/22 12:14] (actual)
admin [Comparación avanzada de métricas]
Línea 74: Línea 74:
  
 <sxh python> <sxh python>
-import statsmodels.stats.proportion as smp+from statsmodels.stats.proportion import proportion_confint
  
 # Número de éxitos # Número de éxitos
-count = 111+success = 111
 # Número total de ensayos # Número total de ensayos
-nobs = 115+total = 115
 # Nivel de confianza deseado # Nivel de confianza deseado
 confianza=95 confianza=95
Línea 85: Línea 85:
 methods=['normal','beta','wilson','jeffreys','agresti_coull'] methods=['normal','beta','wilson','jeffreys','agresti_coull']
 for method in methods: for method in methods:
-    lower, upper = smp.proportion_confint(countnobs, alpha=1-(confianza/100), method=method)+    lower, upper = proportion_confint(successtotal, alpha=1-(confianza/100), method=method)
  
     print(f"Intervalo de confianza al {confianza}% con el método \"{method}\"= [{lower:.4f}, {upper:.4f}]")     print(f"Intervalo de confianza al {confianza}% con el método \"{method}\"= [{lower:.4f}, {upper:.4f}]")
Línea 101: Línea 101:
 Y podemos observar que el cálculo del intervalo del test de COVID se hizo con ''Clopper-Pearson'' Y podemos observar que el cálculo del intervalo del test de COVID se hizo con ''Clopper-Pearson''
  
-<note tip>+===== Elección del método =====
 De forma general y sin querer entrar en detalles el método que deberemos usar en las métricas será el Jeffreys (''jeffreys'') De forma general y sin querer entrar en detalles el método que deberemos usar en las métricas será el Jeffreys (''jeffreys'')
  
-¿Porque Jeffreys? Porque es el que usa estadística bayesiana para calcular el intervalo de confianza.+¿Porque Jeffreys? Porque es el que usa estadística bayesiana para calcular el intervalo de confianza. Así que realmente no es un intervalo de confianza sino un intervalo de credibilidad. ¿cual es la diferencia? Vamos a explicarlo con el ejemplo que estamos usando:  
 +  * **Intervalo de confianza**  de ''Clopper-Pearson'' de ''[0.9133, 0.9904]'' significa que hay un 95% de probabilidad de que ese intervalo contenga al valor real que estamos buscando. 
 +  * **Intervalo de credibilidad**  de ''Jeffreys'' de ''[0.9194, 0.9881]'' significa que hay un 95% de probabilidad de que el valor real que estamos buscando esté en ese intervalo.
  
-En el siguiente código se puede ver como da el mismo resultado usando ''proportion_confint(method="jeffreys")'' que calculándolo mediante el teorema de bayes y usando como prior una Beta(0.5,0.5).(La explicación del cálculo exacto bayesiano va más allá del ámbito de este curso de estadística)+En el siguiente código se puede ver como da el mismo resultado usando ''proportion_confint(method="jeffreys")'' que calculándolo mediante el teorema de bayes y usando como prior una $Beta(0.5,0.5)$Y por lo tanto ''Jeffreys'' es un **Intervalo de credibilidad** ya que es lo que se calcula en la estadística bayesiana. 
 + 
 +**NOTA:La explicación del cálculo bayesiano va más allá del ámbito de este curso de especialización.**
  
 <sxh python> <sxh python>
Línea 117: Línea 121:
  
 lower,upper=proportion_confint(success,total,method="jeffreys",alpha=1-confidence) lower,upper=proportion_confint(success,total,method="jeffreys",alpha=1-confidence)
-print(f"Intervalo de confianza usando \"Jeffreys\"\t\t\t=[{lower:.4f} - {upper:.4f}]")+print(f"Intervalo de confianza usando \"Jeffreys\"\t\t\t=[{lower:.6f} - {upper:.6f}]")
 beta_a=0.5+success beta_a=0.5+success
 beta_b=0.5+total-success beta_b=0.5+total-success
 lower,upper=beta.interval(confidence,beta_a,beta_b) lower,upper=beta.interval(confidence,beta_a,beta_b)
-print(f"Intervalo de confianza usando Bayes con prior Beta(0.5,0.5)\t=[{lower:.4f} - {upper:.4f}]")+print(f"Intervalo de confianza usando Bayes con prior Beta(0.5,0.5)\t=[{lower:.6f} - {upper:.6f}]") 
 </sxh> </sxh>
  
 <sxh base> <sxh base>
-Intervalo de confianza usando "Jeffreys" =[0.9194 - 0.9881+Intervalo de confianza usando "Jeffreys" =[0.919431 - 0.988148
-Intervalo de confianza usando Bayes con prior Beta(0.5,0.5) =[0.9194 - 0.9881]+Intervalo de confianza usando Bayes con prior Beta(0.5,0.5) =[0.919431 - 0.988148]
 </sxh> </sxh>
-</note>+ 
 +¿Y cuando se podrían usar otros? El resto no son bayesianos así que dan "peor" información pero en lineas generales, podemos decir que: 
 +  * Clopper-Pearson o Jeffreys: Tamaño de muestra pequeño 
 +  * Wilson o Agresti-Coull: Tamaño de muestra grande y proporción no extrema 
 +  * Normal (Wald): No es recomendable
  
  
Línea 139: Línea 148:
   * Dos modelos tienen la **misma** métrica si sus intervalos **se solapan** en algún punto   * Dos modelos tienen la **misma** métrica si sus intervalos **se solapan** en algún punto
   * Dos modelos tienen **distinta** métrica si sus intervalos **no se solapan** en ningún punto   * Dos modelos tienen **distinta** métrica si sus intervalos **no se solapan** en ningún punto
 +  * En caso de **"empate"**, se elige el modelo con la menor variabilidad
  
 Veamos un ejemplo. Veamos un ejemplo.
Línea 165: Línea 175:
  
 Se puede apreciar que: Se puede apreciar que:
-  * Los modelos 1 y 2 son iguales +  * Los modelos 1 y 2 son iguales aunque es mejor el 1 ya que tiene menor variabilidad. 
-  * Los modelos 3 y 4 son iguales+  * Los modelos 3 y 4 son iguales aunque es mejor el 3 ya que tiene menor variabilidad. 
 + 
 +Por lo que el orden de los modelos de mejor a peor es: **1, 2, 5, 3 y 4**
  
-Por lo que: 
-  * Los mejores modelos son el 1 y el 2 
-  * Después va el modelo 5 
-  * Y los 2 peores modelos son el 3 y el 4. 
  
 La siguiente función en Python crea un gráfico para poder comparar intervalos de confianza: La siguiente función en Python crea un gráfico para poder comparar intervalos de confianza:
Línea 211: Línea 219:
 </sxh>  </sxh> 
  
-<note tip>+
 Otra forma de hacer el gráfico es poner lineas en los extremos de los intervalos, que aunque se ve mejor, queda un gráfico muy recargado. Otra forma de hacer el gráfico es poner lineas en los extremos de los intervalos, que aunque se ve mejor, queda un gráfico muy recargado.
  
 <sxh python> <sxh python>
-def plot_intervals(axes,intervalos,title,xlabel,ylabels):+def plot_intervals_with_guides(axes,intervalos,title,xlabel,ylabels):
     for index, (inferior, superior) in enumerate(intervalos):     for index, (inferior, superior) in enumerate(intervalos):
         position=len(intervalos)-index-1         position=len(intervalos)-index-1
Línea 238: Línea 246:
 {{:clase:iabd:pia:2eval:comparacion_intervalos_confianza_lineas.png?direct|}} {{:clase:iabd:pia:2eval:comparacion_intervalos_confianza_lineas.png?direct|}}
  
-</note>+===== Comparación avanzada de métricas ===== 
 +En caso de que los intervalos se solapen, no significa exactamente que tengan la misma métrica. Para saber si realmente la tienen es necesario restar las distribuciones y ver si el cero (o algo cercano al cero) está en dicha resta. 
 + 
 +Para hacer los cálculos vamos a crear una serie de funciones en python. 
 + 
 +<sxh python> 
 +def get_hdi(sample, hdi_prob): 
 +    """ 
 +            Calculation of 100(1-a)% HDI for sample 
 +            Chen-Shao HPD Estimation algorithm 
 +            http://y-okamoto-psy1949.la.coocan.jp/Python/en/calc_map_est/ 
 +    """ 
 +    smpl = np.sort(sample) 
 +    n = len(smpl) 
 +    ckW = max(smpl) - min(smpl) 
 +    cki = 0 
 +    RB = int(n * (hdi_prob)) 
 +    L0 = 0 
 +    U0 = n-1 
 +    while (RB + cki < n): 
 +        if smpl[RB + cki] - smpl[cki] < ckW: 
 +            ckW = smpl[RB + cki] - smpl[cki] 
 +            L0 = cki 
 +            U0 = RB + cki 
 +        cki += 1 
 +    ckW = max(smpl) - min(smpl) 
 +    cki = 1 
 +    LB = n - int(n * (hdi_prob)) 
 +    L1 = 0 
 +    U1 = n-1 
 +    while (LB - cki >= 0): 
 +        if smpl[n - cki] - smpl[LB - cki] < ckW: 
 +            ckW = smpl[n - cki] - smpl[LB - cki] 
 +            U1 = n - cki 
 +            L1 = LB - cki 
 +        cki += 1 
 +    return [smpl[int((L1+L0)/2)], smpl[int((U1+U0)/2)]] 
 + 
 + 
 + 
 +def get_interval(success,total,confidence=0.95): 
 +    beta_a=0.5+success 
 +    beta_b=0.5+total-success 
 +    actual_beta=beta(beta_a,beta_b) 
 +    hdi=get_hdi(actual_beta.rvs(100000),confidence) 
 +    return hdi 
 + 
 + 
 + 
 + 
 + 
 +def get_hdi_compare(success1,total1,success2,total2,confidence=0.95): 
 +    beta_a1=0.5+success1 
 +    beta_b1=0.5+total1-success1 
 +    beta1=beta(beta_a1,beta_b1) 
 +    beta_a2=0.5+success2 
 +    beta_b2=0.5+total1-success2 
 +    beta2=beta(beta_a2,beta_b2) 
 + 
 +    n_samples = 100000 
 +    datos1=beta1.rvs(n_samples) 
 +    datos2=beta2.rvs(n_samples) 
 + 
 +    resultado=datos1-datos2 
 +     
 +    lower,upper=get_hdi(resultado,confidence) 
 + 
 +    return [lower,upper] 
 +</sxh> 
 + 
 +Lo primero es que hemos creado la función ''get_interval'' que nos retorna el [[https://easystats.github.io/bayestestR/articles/credible_interval.html|intervalo de credibilidad]] (en este caso el Highest Density Interval  o HDI ). Calculamos ambos intervalos y los mostramos: 
 + 
 +<sxh python> 
 +TP1=131 
 +FN1=16 
 + 
 +TP2=124 
 +FN2=23 
 + 
 + 
 +interval1=get_interval(TP1,TP1+FN1) 
 +interval2=get_interval(TP2,TP2+FN2) 
 + 
 + 
 +figure=plt.figure(figsize=(5.5, 3)) 
 +axes = figure.add_subplot() 
 + 
 +intervalos=[ 
 +    interval1, 
 +    interval2 
 +
 +ylabels=['Modelo 1', 'Modelo 2'] 
 +  
 +plot_intervals(axes,intervalos,"Comparación de modelos","Sensibilidad",ylabels) 
 +</sxh> 
 + 
 +La gráfica resultante es:  
 +{{:clase:iabd:pia:2eval:comparacion_2_metricas.png?direct|}} 
 + 
 + 
 +Y para saber si realmente tienen la misma métrica simplemente ejecutamos el siguiente código: 
 +<sxh python> 
 +print(get_hdi_compare(TP1,TP1+FN1,TP2,TP2+FN2)) 
 +</sxh> 
 +Y el resultado es: 
 +<sxh base> 
 +[-0.029769860656823077, 0.12498680076438595] 
 +</sxh> 
 + 
 +**Si el intervalo incluye al cero es que tienen la misma métrica.** Y en el ejemplo como el intervalo contiene el cero es que tienen la misma métrica. 
 + 
 +Veamos ahora otro ejemplo: 
 +<sxh python> 
 +TP1=131 
 +FN1=16 
 + 
 +TP2=116 
 +FN2=31 
 + 
 + 
 +interval1=get_interval(TP1,TP1+FN1) 
 +interval2=get_interval(TP2,TP2+FN2) 
 + 
 + 
 +figure=plt.figure(figsize=(5.5, 3)) 
 +axes = figure.add_subplot() 
 + 
 +intervalos=[ 
 +    interval1, 
 +    interval2 
 +
 +ylabels=['Modelo 1', 'Modelo 2'] 
 +  
 +plot_intervals_with_guides(axes,intervalos,"Comparación de modelos","Sensibilidad",ylabels) 
 +</sxh> 
 +{{:clase:iabd:pia:2eval:comparacion_2_metricas_b.png?direct|}} 
 + 
 +<sxh python> 
 +print(get_hdi_compare(TP1,TP1+FN1,TP2,TP2+FN2)) 
 +</sxh> 
 + 
 +<sxh base> 
 +[0.018992455698845223, 0.18505496723415582] 
 +</sxh> 
 + 
 +Por lo que en este caso se solapan pero no tiene la misma métrica.  
 + 
 +De todas en este caso, el intervalo está rozando el cero, hay un concepto llamado [[https://easystats.github.io/bayestestR/articles/region_of_practical_equivalence.html|Region of Practical Equivalence (ROPE)]] que dice que aunque no esté el cero en el intervalo, nos vale una región cercana al cero ya que de forma práctica es como si fuera el cero.
  
 ===== Ejercicios ===== ===== Ejercicios =====
Línea 249: Línea 404:
  
 ==== Ejercicio 3 ==== ==== Ejercicio 3 ====
-Crear modelos distintos para el problema del cancer y para cada uno de ellos:+Crear modelos distintos para el problema del cancer y para cada uno de ellos:
   * Calcula las métricas de sensibilidad y especificidad.   * Calcula las métricas de sensibilidad y especificidad.
   * Calcula el intervalo de confianza de las métricas de sensibilidad y especificidad. ¿Que método se va a usar?   * Calcula el intervalo de confianza de las métricas de sensibilidad y especificidad. ¿Que método se va a usar?
Línea 260: Línea 415:
   * Indica según la sensibilidad el orden de los bueno que es cada modelo (de mejor a peor).   * Indica según la sensibilidad el orden de los bueno que es cada modelo (de mejor a peor).
   * Indica según la especificidad el orden de los bueno que es cada modelo (de mejor a peor)   * Indica según la especificidad el orden de los bueno que es cada modelo (de mejor a peor)
 +  * ¿Que modelo elegirías?
 +
 +{{:clase:iabd:pia:2eval:comparacion_modelos_metricas_intervalo.png?direct|}}
 +
 +
 +==== Ejercicio 4 ====
 +Elige el mejor de los 5 modelos anteriores y muestra ahora una gráfica, en la que se mostrará:
 +
 +  * El valor de la sensibilidad y la especificidad según el valor del umbral. La gráfica tendrá un aspecto simular a la siguiente:
 +
 +{{:clase:iabd:pia:2eval:threshold-metricas.png?direct|}}
 +¿Que umbral elegirías?
 +
 +
 +
 +  * Repite ahora la gráfica, pero incluyendo los intervalos de credibilidad de cada métrica. La gráfica tendrá un aspecto simular a la siguiente:
 +
 +{{:clase:iabd:pia:2eval:threshold-metricas-intervalo-confianza.png?direct|}}
 +¿Que umbral elegirías?
 +
 +<note tip>Para ahcer este típo de gráficas usa el método:
 +
 +''axes.fill_between(rango_threshold, rango_sensibilidad_lower, rango_sensibilidad_upper, color=color, alpha=0.5)''</note>
  
clase/iabd/pia/2eval/tema08.intervalo_confianza.1715268123.txt.gz · Última modificación: 2024/05/09 17:22 por admin