Evalúa campos extraídos por IA con precisión y recall de coincidencia exacta
En esta página
Un asistente de IA convierte solicitudes de mantenimiento en identificadores de activos y fechas límite. El JSON se puede analizar, pero un identificador es incorrecto, una fecha es inventada y otra solicitud queda sin respuesta. ¿Qué parte de la extracción es realmente correcta?
Construye un evaluador local que separe las predicciones incorrectas de los datos omitidos y cuente los registros completamente correctos. Usa la biblioteca estándar de Python, ejemplos sintéticos y ninguna cuenta de modelos. Si recibes JSON sin procesar del modelo, primero rechaza el JSON ambiguo; una sintaxis válida no demuestra que la extracción sea precisa.
1. Fija la referencia y las reglas de coincidencia
Empieza con tres mensajes de origen, conservados sin cambios como datos de prueba:
r1: “Inspect pump A7 by 2026-11-10.”r2: “Inspect fan B2; no due date provided.”r3: “Inspect valve C9 by 2026-11-12.”
Pide al extractor exactamente dos campos por registro: asset, con solo el identificador del activo, y due, con una fecha en formato ISO o el valor JSON null si no existe. En Python, representa null con None. Una persona revisa las fuentes y escribe GOLD independientemente de las predicciones. No permitas que el modelo modifique su propia clave de respuestas.
Usa coincidencias exactas de cadenas, distinguiendo mayúsculas y minúsculas. Los espacios y el formato de fecha importan; los valores repetidos en registros distintos siguen siendo datos diferentes. Este ejemplo admite un valor por campo, no partidas repetidas de facturas ni entidades anidadas. Conserva los identificadores incluso cuando falle la extracción, con ambos campos en None.
2. Cuenta datos, no celdas vacías
Representa cada dato no vacío como (record_id, field, value):
- Verdadero positivo (TP): un dato predicho coincide con la referencia.
- Falso positivo (FP): un dato predicho no tiene coincidencia en la referencia.
- Falso negativo (FN): un dato de referencia no tiene una predicción coincidente.
Un valor incorrecto genera tanto un FP como un FN. Predecir una fecha inexistente genera solo un FP. Estas distinciones siguen las definiciones de evaluación de extracción de Google Document AI; nuestro evaluador es una implementación pequeña de coincidencia exacta, no una reproducción de ese servicio.
La precisión es TP / (TP + FP); la exhaustividad, o recall, es TP / (TP + FN). F1 es 2*TP / (2*TP + FP + FN). Son las definiciones estándar de precisión, recall y puntuación F. Para entender mejor la diferencia, consulta recall frente a precisión.
3. Ejecuta el evaluador local
Guarda esto como evaluate_extraction.py y usa Python 3.10 o posterior. CANDIDATE contiene predicciones escritas a mano con errores deliberados, no resultados medidos de un modelo. El comprobador rechaza identificadores ausentes, campos inesperados y tipos de valores inválidos en lugar de excluirlos silenciosamente.
FIELDS = ("asset", "due")
GOLD = {
"r1": {"asset": "A7", "due": "2026-11-10"},
"r2": {"asset": "B2", "due": None},
"r3": {"asset": "C9", "due": "2026-11-12"},
}
CANDIDATE = {
"r1": {"asset": "A7", "due": "2026-11-10"},
"r2": {"asset": "B3", "due": "2026-11-11"},
"r3": {"asset": None, "due": None},
}
def facts(rows):
if not isinstance(rows, dict) or set(rows) != set(GOLD):
raise ValueError("record IDs must match gold")
result = set()
for record_id, row in rows.items():
if not isinstance(row, dict) or set(row) != set(FIELDS):
raise ValueError("each record needs asset and due")
for field, value in row.items():
if value is not None:
if not isinstance(value, str) or not value.strip():
raise ValueError("values must be nonempty strings or None")
result.add((record_id, field, value))
return result
def score(rows):
expected, actual = facts(GOLD), facts(rows)
tp = len(expected & actual)
fp, fn = len(actual - expected), len(expected - actual)
precision = tp / (tp + fp) if tp + fp else None
recall = tp / (tp + fn) if tp + fn else None
denominator = 2 * tp + fp + fn
f1 = 2 * tp / denominator if denominator else None
whole = sum(rows[key] == GOLD[key] for key in GOLD)
return tp, fp, fn, precision, recall, f1, whole
def report(name, rows):
tp, fp, fn, precision, recall, f1, whole = score(rows)
fmt = lambda value: "n/a" if value is None else f"{value:.3f}"
print(f"{name}: tp={tp} fp={fp} fn={fn}")
print(f"precision={fmt(precision)} recall={fmt(recall)} f1={fmt(f1)}")
print(f"whole_records={whole}/{len(GOLD)}")
if __name__ == "__main__":
report("candidate", CANDIDATE)
report("perfect control", GOLD)
empty = {key: dict.fromkeys(FIELDS) for key in GOLD}
report("empty control", empty)
python3 evaluate_extraction.py
Salida esperada:
candidate: tp=2 fp=2 fn=3
precision=0.500 recall=0.400 f1=0.444
whole_records=1/3
perfect control: tp=5 fp=0 fn=0
precision=1.000 recall=1.000 f1=1.000
whole_records=3/3
empty control: tp=0 fp=0 fn=5
precision=n/a recall=0.000 f1=0.000
whole_records=0/3
4. Valida los cálculos e inspecciona los fallos
El candidato devuelve cuatro datos, pero solo dos coinciden. El B3 incorrecto aporta un FP y deja B2 como un FN. Su fecha inventada aporta otro FP. Faltan ambos datos de r3, lo que añade dos FN. Solo r1 es completamente correcto.
El control perfecto debe alcanzar 1.000 en las tres métricas. El control vacío debe tener recall cero; su precisión no está definida y se muestra como n/a, porque no predice nada. Las ausencias coincidentes no cuentan como TP, aunque la comparación de registros completos incluye todos los campos.
Estos controles prueban el evaluador, no la calidad de producción de un modelo. El comando termina correctamente incluso con predicciones deficientes; informa de mediciones en lugar de imponer un bloqueo de despliegue.
5. Resuelve problemas antes de comparar modelos
- Omisiones inesperadas: inspecciona
facts(GOLD) - facts(CANDIDATE). Comprueba la fuente antes de cambiar las etiquetas. - Errores solo de formato: acuerda la normalización antes de evaluar. Aplica la misma regla documentada a ambos lados; no borres diferencias significativas entre identificadores.
- F1 global alto, fechas incorrectas: evalúa cada campo por separado e informa de su cantidad de datos de referencia. Los campos frecuentes pueden ocultar fallos en los menos habituales.
- Resultados sorprendentemente perfectos: busca filtraciones de respuestas. Separa los ejemplos de desarrollo de un conjunto de prueba reservado.
Para ensayos reales, usa solicitudes autorizadas y anonimizadas que incluyan fechas ausentes, identificadores inusuales y entradas ilegibles. Registra las versiones del modelo y del prompt. Corrige un patrón de fallo con datos de desarrollo y usa después el mismo conjunto de prueba fijo para la comparación final. Nuestro tutorial de regresión de prompts muestra cómo seguir los cambios entre versiones.
Conclusión práctica
Comprueba los datos exactos y los registros completos antes de automatizar una extracción. Una respuesta que se puede analizar aún puede contener valores inventados; una media alta aún puede ocultar registros inutilizables.
Artículos relacionados
Evalúa la clasificación de incidencias con una matriz de confusión
Compara versiones de prompts de IA con una prueba de regresión en Python
Evalúa transcripciones de IA con la tasa de error por palabra
Comprueba las cifras de resúmenes de IA con una tabla de referencia
Detecta texto repetido entre entrenamiento y prueba antes de evaluar una IA
Revisa planes de renombrado de IA sin cambiar archivos
Evalúa probabilidades de IA con la puntuación de Brier en Python
Comprueba las dependencias de tareas de IA antes de programarlas con Python
Comprueba las horas de calendario de IA antes de crear eventos
Comprueba los marcadores de traducciones de IA con Python
Elige umbrales de revisión de IA con cobertura y tasas de error
Comprueba las rutas propuestas por IA antes de escribir con Python
Últimos artículos
Comprueba las rutas propuestas por IA antes de escribir con Python
Evita actualizaciones de IA obsoletas con un control de versión en SQLite
Comprueba las dependencias de tareas de IA antes de programarlas con Python
Revisa los cambios JSON de la IA con una lista de campos permitidos
Combina resultados RAG con fusión de rangos recíprocos
Comprueba las horas de calendario de IA antes de crear eventos
Comprueba citas textuales de IA con fuentes locales y Python
Comprueba las cifras de resúmenes de IA con una tabla de referencia
Elige umbrales de revisión de IA con cobertura y tasas de error
Comprueba los marcadores de traducciones de IA con Python
Compara versiones de prompts de IA con una prueba de regresión en Python