# Resultados de Ajuste de Hiperparámetros EasyOCR

**Fecha de Ajuste:** 2026-01-19
**Plataforma:** NVIDIA RTX 3060 Laptop GPU
**Muestras:** 64
**Páginas de Prueba:** 5-10 (primer documento)

### ¿Por Qué Solo 5 Páginas?

Usamos solo 5 páginas (páginas 5-10) para el ajuste de hiperparámetros porque:

1. **Velocidad**: 64 pruebas × 5 páginas = 320 evaluaciones de página. Con 45 páginas, serían 2,880 evaluaciones (~9x más tiempo)
2. **Eficiencia de recursos**: Cada prueba toma ~10-20 segundos en GPU

**Riesgo de Sobreajuste**: El ajuste de hiperparámetros en un subconjunto pequeño PUEDE causar sobreajuste. Nuestros resultados confirman esto:
- Subconjunto de ajuste: **48% mejora** (5.83% CER)
- Dataset completo: **0.8% mejora** (11.14% CER)

La mejora mínima en el dataset completo indica que los hiperparámetros se sobreajustaron a las páginas 5-10. Los problemas de EasyOCR (detecciones espurias, pérdida de estructura) también pueden ser parcialmente a nivel de modelo.

## Evaluación del Dataset Completo (45 páginas)

| Métrica | Base | Ajustado | Mejora |
|---------|------|----------|--------|
| **CER** | 11.23% | 11.14% | **0.8%** |
| **WER** | 36.36% | 36.85% | **-1.3%** |
| Tiempo/Página | 1.84s | 1.94s | - |

> **Nota:** El ajuste mostró mejora mínima en el dataset completo. Los problemas de EasyOCR pueden ser a nivel de modelo.

## Resultados del Subconjunto de Ajuste (páginas 5-10)

| Métrica | Base | Ajustado | Mejora |
|---------|------|----------|--------|
| **CER** | 11.23% | **5.83%** | **48%** |
| **WER** | 36.36% | **26.33%** | **28%** |

> Nota: Las grandes mejoras en el subconjunto de ajuste no se transfirieron al dataset completo.

## Mejor Configuración Encontrada

```json
{
  "text_threshold": 0.6647,
  "low_text": 0.4247,
  "link_threshold": 0.2184,
  "slope_ths": 0.1629,
  "ycenter_ths": 0.7994,
  "height_ths": 0.6437,
  "width_ths": 0.6065,
  "add_margin": 0.1462,
  "contrast_ths": 0.1671,
  "adjust_contrast": 0.6416,
  "decoder": "greedy",
  "beamWidth": 7,
  "min_size": 10
}
```

## Hallazgos Clave

1. **decoder: greedy** - Consistentemente mejor que beamsearch para este dataset
2. **Mayor text_threshold (0.66)** - Reduce detecciones espurias
3. **min_size: 10** - Filtra artefactos de ruido pequeños
4. **Umbrales moderados** - Sensibilidad de detección balanceada

## Impacto de Parámetros

Parámetros que mejoraron la precisión:
- `decoder="greedy"` consistentemente superó a beamsearch
- Mayor `text_threshold` (0.6-0.8) redujo el ruido
- `min_size >= 5` ayudó a filtrar artefactos

Parámetros que perjudicaron la precisión:
- `decoder="beamsearch"` causó ~35-40% CER en muchas pruebas
- `text_threshold` muy bajo (<0.4) detectó demasiado ruido
- `min_size` alto (>15) omitió algo de texto

## Comparación con Problemas de Base

Problemas originales identificados en el debugset:
- Inserciones espurias de caracteres - **Mejorado** con umbrales más altos
- Pérdida de estructura - Todavía presente pero menos severa

## Evaluación del Dataset Completo

**Estado:** Completado

```bash
curl -X POST http://localhost:8002/evaluate_full \
  -H "Content-Type: application/json" \
  -d '{
    "pdf_folder": "/app/dataset",
    "text_threshold": 0.6647,
    "low_text": 0.4247,
    "link_threshold": 0.2184,
    "slope_ths": 0.1629,
    "ycenter_ths": 0.7994,
    "height_ths": 0.6437,
    "width_ths": 0.6065,
    "add_margin": 0.1462,
    "contrast_ths": 0.1671,
    "adjust_contrast": 0.6416,
    "decoder": "greedy",
    "beamWidth": 7,
    "min_size": 10,
    "save_output": true
  }'
```

**Resultado:** CER 11.14%, WER 36.85%, 1.94s/página (mejora mínima)

**Conclusión:** El ajuste de EasyOCR proporcionó mejora insignificante en el dataset completo.

## Configuración del Modelo

### Modelo Actual (Correcto para Español)

| Componente | Modelo | Estado |
|------------|--------|--------|
| Detección | CRAFT | Correcto |
| Reconocimiento | `latin_g2.pth` | Correcto para español |
| Idiomas | `es,en` | Correcto |

El modelo `latin_g2.pth` está optimizado para idiomas con escritura latina incluyendo español. **El modelo de reconocimiento es correcto** - los problemas observados (caracteres espurios `0`, `;`, `g`) son del **detector CRAFT**, no del modelo de reconocimiento.

### No Se Requiere Cambio de Modelo

A diferencia de DocTR, EasyOCR usa el modelo correcto para español. Los problemas son de detección (umbrales del CRAFT), no de reconocimiento.

## Análisis de Errores del Debugset

### Errores Observados

| Ground Truth | EasyOCR | Tipo de Error |
|--------------|---------|---------------|
| `o figura` | `0 figura` | Letra `o` → número `0` |
| `tabla o figura` | `tabla 0 figura` | Letra `o` → número `0` |
| `grupal,` | `grupal;` | Coma → punto y coma |
| `páginas,` | `páginas;` | Puntuación incorrecta |
| (ninguno) | `g`, `1`, `2` | **Caracteres espurios insertados** |
| Líneas separadas | Todo en una línea | **Estructura perdida** |

### Problemas Críticos

1. **Caracteres espurios**: El detector CRAFT inserta caracteres falsos (`g`, `1`, `2`, `;`) que no existen en el documento
2. **Confusión letra/número**: Consistentemente confunde `o` con `0`
3. **Puntuación incorrecta**: Reemplaza comas por punto y coma
4. **Pérdida de estructura**: Todo el texto se colapsa en una línea

### ¿Fine-tuning Recomendado?

**Sí.** EasyOCR tiene problemas significativos que podrían mejorarse con fine-tuning:

| Problema | ¿Fine-tuning ayuda? | Explicación |
|----------|---------------------|-------------|
| Caracteres espurios | **Sí** | El detector CRAFT puede entrenarse para reducir falsos positivos |
| Confusión `o`/`0` | **Sí** | El modelo de reconocimiento aprendería del contexto español |
| Puntuación | **Sí** | Corpus español enseñaría patrones de puntuación correctos |
| Estructura | **Parcial** | Depende de parámetros de agrupación de texto |

### Cómo Fine-Tunear EasyOCR

EasyOCR permite fine-tuning del modelo de reconocimiento:

```bash
# 1. Preparar dataset en formato EasyOCR
# Estructura: images/ + labels.txt (imagen<tab>texto)

# 2. Entrenar modelo de reconocimiento
python train.py \
  --train_data ./train_data \
  --valid_data ./valid_data \
  --lang_list es en \
  --saved_model ./custom_model
```

Documentación: https://github.com/JaidedAI/EasyOCR/blob/master/custom_model.md

### Alternativa Recomendada

Dado el CER de 11.14% y los problemas fundamentales de EasyOCR, se recomienda **usar PaddleOCR** (7.72% CER) en lugar de invertir esfuerzo en fine-tuning de EasyOCR
