Proyecto final e IA responsable

Tema 30 · Fase 6, Ver, oír y crear · Toda la ruta

En esta ficha · 5 secciones
  1. Antes de empezar
  2. Ejercicios
  3. Mini-proyecto: tu proyecto final
  4. Errores comunes
  5. ¿Lo lograste?

Antes de empezar

Varios ejercicios usan las variables y funciones de la teoría: datos, X, X_ent, y_ent, X_pru, y_pru, s_ent, s_pru, crear_pipeline, metricas, intervalos, auditoria, por_sexo, HistGradientBoostingClassifier y roc_auc_score. Abre un cuaderno nuevo en Colab, pega y ejecuta en orden los bloques de la ficha Código y después trabaja debajo. Intenta cada ejercicio antes de abrir la respuesta.

Ejercicios

1. Métricas de equidad a mano

Un modelo decide sobre 100 personas del grupo A y 100 del grupo B. En el grupo A, 40 personas son positivas: el modelo aprueba a 30 de ellas y a 10 de las 60 negativas. En el grupo B, 20 personas son positivas: el modelo aprueba a 10 de ellas y a 5 de las 80 negativas.

a) Calcula para cada grupo la tasa de aprobación, la TVP, la TFP y la precisión. Compruébalo con la función metricas.

b) ¿Cumple el modelo la paridad demográfica? ¿Y la igualdad de oportunidades?

c) Si en el grupo B se aprobara a 15 de los 20 positivos (y a los mismos 5 negativos), ¿qué criterio se cumpliría? ¿Se cumplirían los dos?

Respuesta

a) Grupo A: aprobación (30 + 10) / 100 = 0,40; TVP 30 / 40 = 0,75; TFP 10 / 60 ≈ 0,167; precisión 30 / 40 = 0,75. Grupo B: aprobación 15 / 100 = 0,15; TVP 10 / 20 = 0,50; TFP 5 / 80 ≈ 0,062; precisión 10 / 15 ≈ 0,667.

tabla = pd.DataFrame({
    "grupo": ["A"] * 100 + ["B"] * 100,
    "y":    [1] * 40 + [0] * 60 + [1] * 20 + [0] * 80,
    "pred": [1] * 30 + [0] * 10 + [1] * 10 + [0] * 50
          + [1] * 10 + [0] * 10 + [1] * 5 + [0] * 75,
})
resumen = tabla.groupby("grupo")[["y", "pred"]].apply(metricas)
print(resumen[["aprobacion", "tvp", "tfp", "precision"]].round(3))
       aprobacion   tvp    tfp  precision
grupo                                    
A            0.40  0.75  0.167      0.750
B            0.15  0.50  0.062      0.667

b) Ninguno de los dos: la aprobación es 0,40 contra 0,15 y la TVP, 0,75 contra 0,50.

c) La TVP de B sería 15 / 20 = 0,75, igual a la de A: se cumpliría la igualdad de oportunidades. La aprobación de B sería (15 + 5) / 100 = 0,20, todavía lejos de 0,40: la paridad no se cumpliría. ¿Se pueden cumplir los dos? Sí: aprobando a 25 negativos de B (en vez de 5), la aprobación de B sube a (15 + 25) / 100 = 0,40 y la TVP sigue en 0,75. Pero la TFP de B pasaría de 5 / 80 ≈ 0,06 a 25 / 80 ≈ 0,31, casi el doble de la de A (0,167), y B tendría 20 errores más: se cumplen los dos criterios a costa de muchos más errores. Si además pides la misma TFP (igualdad de probabilidades), ya no se puede: con TVP 0,75 y TFP 0,167, B aprobaría a 0,75 · 20 + 0,167 · 80 ≈ 28 personas, no a 40. Es el mismo choque que viste en la actividad.

2. Auditar por origen

La columna raza de Adult (el «origen», como lo llamamos en este tema) tiene las cinco categorías que usaba el censo de los Estados Unidos en 1994. Esas categorías no corresponden a cómo se pregunta la identidad en Bolivia: en el Censo 2024, la pregunta es de autoidentificación con una nación o pueblo indígena originario campesino o afroboliviano. Audita el modelo de la teoría por esa columna: tamaño de cada grupo, tasa base, aprobación y TVP, con el intervalo de bootstrap de la TVP. ¿En qué grupos puedes afirmar algo y en cuáles no?

Respuesta
# Las categorías del censo de 1994, traducidas
nombres = {"White": "blanca", "Black": "negra",
           "Asian-Pac-Islander": "asiática o del Pacífico",
           "Amer-Indian-Eskimo": "indígena americana", "Other": "otra"}
raza = datos.loc[X_pru.index, "raza"].astype(str).map(nombres)
auditoria["raza"] = raza.to_numpy()
por_raza = auditoria.groupby("raza")[["y", "pred"]].apply(metricas)
por_raza["n"] = por_raza["n"].astype(int)
print(por_raza[["n", "tasa_base", "aprobacion", "tvp"]].round(3))

print("Intervalo del 95 % de la TVP:")
for r, t in auditoria.groupby("raza"):
    iv = intervalos(t[["y", "pred"]], repeticiones=500)
    print(f"  {r:23s} {iv.loc[0.025, 'tvp']:.2f}–"
          f"{iv.loc[0.975, 'tvp']:.2f}")
                            n  tasa_base  aprobacion    tvp
raza                                                       
asiática o del Pacífico   306      0.265       0.258  0.704
blanca                   8329      0.255       0.213  0.661
indígena americana         95      0.095       0.116  0.778
negra                     950      0.118       0.082  0.518
otra                       89      0.112       0.079  0.400
Intervalo del 95 % de la TVP:
  asiática o del Pacífico 0.61–0.80
  blanca                  0.64–0.68
  indígena americana      0.50–1.00
  negra                   0.42–0.62
  otra                    0.03–0.67
  • Los grupos son muy desiguales en tamaño: 8329 personas en «blanca» y menos de 100 en «indígena americana» y en «otra».
  • En «negra», la TVP es 0,518, con un intervalo de 0,42 a 0,62 que no se toca con el de «blanca» (0,64 a 0,68): de las personas de ese grupo que sí ganaban más de 50 000, el modelo reconoce bastante menos. Es una diferencia que vale la pena reportar y estudiar.
  • En «indígena americana» y en «otra», los intervalos van de 0,50 a 1,00 y de 0,03 a 0,67: con tan pocas personas positivas (unas 10 en cada grupo), no se puede afirmar nada. Que la TVP de «indígena americana» sea 0,778 no quiere decir que el modelo las trate mejor.
  • La lección para tu proyecto: reporta siempre el tamaño de cada grupo junto a sus métricas, y si un grupo es demasiado pequeño, dilo como una limitación en la ficha, en lugar de sacar conclusiones. La solución de fondo es conseguir más datos de ese grupo.

3. Las columnas delatan el sexo

El modelo de la teoría no usa la columna sexo. Entrena un clasificador que intente adivinar el sexo con las mismas diez columnas que usa el modelo, y mide su AUC en prueba. ¿Qué dice el resultado sobre la idea de «quitar la columna y listo»?

Respuesta
# El objetivo ahora es el sexo, con las mismas columnas de antes
es_mujer = (s_ent == "mujer").astype(int)
detector = crear_pipeline(HistGradientBoostingClassifier(random_state=0))
detector.fit(X_ent, es_mujer)
prob_mujer = detector.predict_proba(X_pru)[:, 1]
print(f"AUC para adivinar el sexo: "
      f"{roc_auc_score(s_pru == 'mujer', prob_mujer):.3f}")
AUC para adivinar el sexo: 0.932

Un AUC de 0,932 quiere decir que, con las columnas que «no son el sexo», un modelo ordena casi perfectamente a las personas según su sexo. La información sigue ahí, sobre todo en parentesco y estado_civil. Quitar el atributo sensible (la llamada equidad por desconocimiento) no garantiza que el modelo no lo use indirectamente. Además, sin la columna ya no se puede auditar: por eso en la teoría la guardamos aparte.

4. ¿Y si quitamos el estado civil y el parentesco?

Entrena el mismo boosting sin estado_civil ni parentesco, las dos columnas que delatan el sexo. Compara la exactitud y las tasas de aprobación y TVP por grupo con las del modelo original. ¿Se volvió más justo? ¿A qué costo?

Respuesta
# Las mismas columnas, menos estado_civil y parentesco
otras = ["empleador", "ocupacion", "pais"]
sin_familia = crear_pipeline(
    HistGradientBoostingClassifier(random_state=0), categoricas=otras)
sin_familia.fit(X_ent, y_ent)
pred_sin = sin_familia.predict(X_pru)

tabla_sin = pd.DataFrame({"y": y_pru.to_numpy(), "pred": pred_sin,
                          "sexo": s_pru.to_numpy()})
sin = tabla_sin.groupby("sexo")[["y", "pred"]].apply(metricas)
print(f"Exactitud sin esas columnas: {(pred_sin == y_pru).mean():.3f}")
comparar = pd.DataFrame({
    "aprob_con": por_sexo["aprobacion"], "aprob_sin": sin["aprobacion"],
    "tvp_con": por_sexo["tvp"], "tvp_sin": sin["tvp"]})
print(comparar.round(3))
Exactitud sin esas columnas: 0.848
        aprob_con  aprob_sin  tvp_con  tvp_sin
sexo                                          
hombre      0.255      0.178    0.664    0.494
mujer       0.087      0.078    0.605    0.446
  • La diferencia de aprobación entre hombres y mujeres baja de 0,168 (0,255 − 0,087) a 0,100 (0,178 − 0,078), y la de TVP, de 0,059 a 0,048.
  • Pero la exactitud cae de 0,875 a 0,848, y la TVP baja para los dos grupos: el modelo reconoce a muchas menos personas que sí cumplen, mujeres incluidas (de 0,605 a 0,446).
  • Las brechas se achicaron más porque el modelo empeoró para todos que porque tratara mejor a las mujeres. Este es un caso típico: una intervención que mejora una métrica de equidad puede empeorar lo que le pasa a cada persona. Por eso se reportan las tasas de cada grupo, no solo la diferencia entre ellas.

5. ¿Qué criterio de equidad?

Para cada situación, di si te parece más defendible pedir paridad demográfica, igualdad de oportunidades o ninguna de las dos (y por qué). No hay una única respuesta correcta, pero sí respuestas mejor y peor justificadas.

  1. Un modelo que elige a quién ofrecerle una beca de estudio: predice si un estudiante tendrá buen rendimiento en la universidad, y se entrenó con los promedios de colegio de exalumnos que vienen de colegios con recursos muy distintos (fiscales, de convenio y particulares).
  2. Un detector de una enfermedad que afecta mucho más a las personas mayores que a las jóvenes.
  3. Un filtro que decide qué currículums lee una persona de recursos humanos, entrenado con quién fue contratado en los últimos diez años en una empresa con casi solo hombres en los puestos técnicos.
  4. Un modelo que recomienda canciones.
Respuesta
  1. Las notas miden el mérito, pero también los recursos del colegio: la etiqueta trae sesgo. Hay buenos argumentos para alguna forma de paridad entre colegios, o mejor, para medir el mérito dentro de cada contexto. Igualar las oportunidades medidas con esas mismas notas heredaría la desigualdad.
  2. Igualdad de oportunidades (o igualdad de probabilidades): lo que importa es detectar igual de bien a los enfermos de cada edad. La paridad sería absurda, porque la enfermedad de verdad es más frecuente en un grupo.
  3. Las etiquetas («fue contratado») registran una historia de exclusión, así que la igualdad de oportunidades medida con ellas no basta. Aquí se justifica mirar la paridad al menos en la etapa de preselección, y sobre todo revisar si hay que automatizar esa decisión.
  4. Probablemente ninguna de las dos en el sentido de este tema: el daño de un error es pequeño. Aun así, vale preguntarse si el sistema les recomienda a todos solo la música de siempre y deja sin oyentes a los artistas menos conocidos.

6. ¿Anónimo?

Una tabla sin nombres no es anónima si una combinación de columnas comunes deja a una persona sola. Cuenta cuántas personas de Adult son únicas en la combinación de edad, sexo, raza, país y ocupación, y cuántas están en grupos de menos de 5 personas.

Respuesta
cuasi = ["edad", "sexo", "raza", "pais", "ocupacion"]
tamanios = datos.groupby(cuasi, observed=True).size()
print(f"Combinaciones distintas: {len(tamanios)}")
print(f"Personas únicas en su combinación: {(tamanios == 1).sum()}")
print(f"Personas en grupos de menos de 5: "
      f"{tamanios[tamanios < 5].sum()} de {len(datos)}")
Combinaciones distintas: 6427
Personas únicas en su combinación: 3810
Personas en grupos de menos de 5: 6944 de 48842

3810 personas son las únicas de su combinación, y 6944 de 48 842 (cerca del 14 %) están en grupos de menos de 5. Quien conozca esas cinco cosas de un vecino podría encontrarlo en la tabla y conocer su ingreso, su estado civil y sus horas de trabajo. Una forma de medirlo es la k-anonimidad: una tabla es k-anónima si cada combinación de esas columnas aparece al menos k veces. Para lograrlo se generalizan los valores (edad en rangos de 10 años, país en región) o se eliminan filas. Adult se publicó sin nombres y con datos de 1994, pero si armas tu propio dataset con datos de tus compañeros, haz esta cuenta antes de compartirlo.

7. La ficha de un modelo de la ruta

Escribe la ficha del mejor modelo que entrenaste en el mini-proyecto del tema 11 (el Titanic), con las secciones de la ficha de la teoría: qué es, uso previsto, usos fuera de alcance, datos, métricas globales, métricas por grupo, consideraciones éticas y limitaciones. Usa los números de tu propio cuaderno.

Respuesta

Una ficha razonable dice algo así (los números salen de tu cuaderno):

  • Qué es. El modelo que elegiste en el tema 11 (por ejemplo, un bosque aleatorio) dentro del pipeline del tema 10, con sus hiperparámetros.
  • Uso previsto. Practicar el ciclo de un proyecto tabular. Fuera de alcance: cualquier conclusión sobre personas reales o sobre la seguridad de un barco actual.
  • Datos. Los pasajeros del dataset titanic de seaborn, una lista histórica de 1912 con faltantes en la edad y el puerto; la división y la semilla que usaste.
  • Métricas. La exactitud en prueba y la de la línea base, porque solo así se ve cuánto aporta el modelo.
  • Por grupo. Exactitud y TVP por sexo y por clase del pasaje, con intervalos de bootstrap. Con tan pocos pasajeros en prueba, los intervalos son anchos: dilo.
  • Consideraciones éticas. En el tema 11, la variable más importante fue el sexo. Eso refleja una regla de 1912 («mujeres y niños primero») y las diferencias entre clases sociales. El modelo describe lo que pasó, no lo que debería pasar.
  • Limitaciones. Pocos datos, una sola fuente histórica y variables faltantes que se imputaron.

8. Asistentes: ¿honesto o no?

Para cada caso, di si el uso de un modelo de lenguaje te parece honesto en un proyecto de estudio y qué cambiarías.

  1. Le pides que te explique por qué tu código da KeyError y, con eso, lo corriges tú.
  2. Le pides el proyecto completo y lo entregas con tu nombre.
  3. Pegas en el chat la tabla con los nombres y las notas de tus compañeros para que te haga gráficos.
  4. Te genera la función de bootstrap; la ejecutas, compruebas que da lo mismo que la de la teoría y lo anotas en tu informe.
Respuesta
  1. Honesto: lo usaste como tutor y el trabajo es tuyo. Puedes mencionarlo en una línea.
  2. Deshonesto: es copiar, y además no aprendiste nada que puedas explicar en la presentación.
  3. Problema de privacidad: compartiste datos personales de otras personas sin su permiso con un servicio externo. Quita los nombres (y mira el ejercicio 6) o pide permiso antes.
  4. Honesto, siempre que entiendas cada línea: comprobaste el código contra una referencia y lo declaraste.

Mini-proyecto: tu proyecto final

Este es el cierre de la ruta: un sistema de IA completo, sobre un problema que elijas, medido con honestidad. Se entregan tres cosas: un cuaderno con las ocho secciones de la plantilla de la teoría, una ficha del modelo y una presentación de 5 minutos.

Elige un tema. Algunas ideas, con el tema de la ruta del que parten:

  • El clima de tu ciudad: predecir la temperatura o la lluvia de mañana con datos meteorológicos abiertos, con ventanas y una línea base de «mañana igual que hoy» (tema 13, «Datos en el tiempo: series temporales y ventanas»).
  • Texto en español: clasificar opiniones, noticias o mensajes, primero con una bolsa de palabras y después con un modelo preentrenado (temas 21, «Texto como datos: tokens, vocabulario y clasificación», y 25, «Reutilizar modelos: BERT, codificador-decodificador y ajuste fino»), o un buscador por significado con embeddings (tema 22).
  • Tus propias fotos: reconocer plantas, platos o lugares de tu entorno con un modelo de visión preentrenado (tema 26, «Visión moderna: modelos preentrenados, autoaprendizaje y CLIP»), o ubicarlos en la imagen (tema 27).
  • Audio: distinguir sonidos o palabras grabados por ti y tus compañeros (tema 28, «Audio: del sonido a los números»).
  • Una tabla de datos abiertos sobre algo que te importe, con el pipeline y los árboles de los temas 10 y 11.

Pasos.

  1. La pregunta, antes de tocar los datos. Escribe qué predices, quién usaría el resultado, qué error cuesta más y qué métrica vas a usar.
  2. Los datos. Anota el origen y la licencia. Si recoges fotos o audios de personas, pídeles permiso y diles para qué. Haz la cuenta del ejercicio 6 si tu tabla tiene datos de personas.
  3. La línea base y el modelo. Sigue la plantilla: línea base, iteraciones anotadas en la bitácora y evaluación final en prueba una sola vez.
  4. Los subgrupos. Elige al menos una forma de dividir tus datos que tenga sentido para tu problema (estación del año, ciudad, iluminación de la foto, hablante, tipo de texto) y reporta las métricas de cada grupo con intervalos de bootstrap. Si no hay personas en tus datos, la pregunta sigue siendo útil: ¿en qué casos falla más el modelo?
  5. La ficha. Con todas sus secciones, incluidos los usos fuera de alcance y el tiempo de cómputo aproximado.
  6. La presentación de 5 minutos. Una diapositiva por idea: la pregunta (30 segundos), los datos (1 minuto), la línea base contra tu modelo (1 minuto), dónde falla (1 minuto y medio), qué harías con más tiempo y qué aprendiste (1 minuto).

Antes de entregar, revisa:

  • ¿Le gana tu modelo a la línea base, en prueba?
  • ¿Usaste la prueba una sola vez?
  • ¿Cualquier persona puede ejecutar tu cuaderno de arriba abajo y obtener los mismos números (semillas fijas)?
  • ¿Dice tu ficha para qué no sirve tu modelo?
  • ¿Declaraste si usaste un asistente y para qué?

Errores comunes

  • Medir solo la exactitud global. Un grupo pequeño puede tener métricas mucho peores sin que el número global se mueva.
  • Comparar la exactitud entre grupos con tasas base distintas. Al grupo con menos positivos le va «mejor» solo porque decir «no» acierta más. Compara la TVP y la TFP.
  • Creer que quitar el atributo sensible arregla el sesgo. Otras columnas lo delatan (ejercicio 3), y sin él ya no puedes auditar.
  • Sacar conclusiones de un grupo con 9 positivos. Sin intervalos, una diferencia puede ser puro azar (ejercicio 2).
  • Elegir los umbrales por grupo mirando la prueba. Los umbrales son una decisión del modelo: se eligen en validación, como los hiperparámetros.
  • Hablar de «justo» sin decir qué métrica. La paridad y la igualdad de oportunidades piden cosas distintas; nombra la que elegiste y por qué.
  • Llamar anónima a una tabla sin nombres. Revisa cuántas personas son únicas en sus columnas comunes (ejercicio 6).
  • Usar datos sin mirar la licencia ni pedir permiso a las personas que aparecen en ellos.
  • Entregar código que no entiendes, venga de un asistente o de internet.
  • Una ficha sin limitaciones. Si tu ficha no dice dónde falla el modelo, está incompleta.

¿Lo lograste?

Al terminar este tema deberías poder hacer lo siguiente. Al lado, dónde lo practicaste.

  • Formular un problema real como tarea de aprendizaje, con datos, métrica y línea base (pasos 1 a 3 del mini-proyecto).
  • Llevar un problema de los datos crudos a un modelo evaluado en un conjunto de prueba bien separado (paso 3 del mini-proyecto).
  • Auditar un modelo por subgrupos y detectar sesgos (ejercicios 1, 2, 3 y 4, y paso 4 del mini-proyecto).
  • Elegir y justificar un criterio de equidad (ejercicios 1 y 5).
  • Documentar un modelo con una ficha y comunicar sus límites (ejercicio 7 y paso 5 del mini-proyecto).
  • Argumentar de forma concreta los riesgos de privacidad, mal uso e impacto ambiental de un sistema de IA (ejercicios 6 y 8, y la ficha del mini-proyecto).