Skip to content

bvergara-hacienda/RCAs-CNEP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Pipeline de Extracción de Obligaciones Ambientales desde RCAs

Este repositorio contiene el código utilizado para extraer, estructurar y clasificar las obligaciones ambientales contenidas en Resoluciones de Calificación Ambiental (RCA) del Sistema de Evaluación de Impacto Ambiental (SEIA) de Chile.

Fue desarrollado como parte del estudio "Uso de inteligencia artificial para la caracterización de la carga regulatoria ambiental de proyectos en desarrollo", de la Comisión Nacional de Evaluación y Productividad (CNEP) del Ministerio de Hacienda de Chile. El análisis de las 1.336 RCAs procesadas habría requerido aproximadamente un año de trabajo manual; este pipeline lo realiza de forma sistemática, escalable y reproducible.


Descripción del problema

Las RCAs son actos administrativos que aprueban proyectos de inversión, fijando las condiciones ambientales bajo las cuales deben ejecutarse. Cada RCA contiene cientos de obligaciones distribuidas en tablas y secciones de texto no estructurado. El objetivo de este pipeline es convertir ese texto en un dataset estructurado y analizable.


Resultados

Los resultados finales se encuentran disponibles en Drive:
📂 Acceder a los resultados


Estructura del repositorio

/
├── archivos/               # RCAs en formato PDF (entrada del pipeline)
├── auxiliares/
│   ├── pas.xlsx            # Listado de Permisos Ambientales Sectoriales
│   └── normativa*.xlsx     # Normativa sectorial de referencia
├── resultados/
│   ├── doctr/              # Textos OCR (Parquet) — output etapa 1
│   ├── marcaje/            # Chunks marcados — output etapa 2
│   ├── gemini_ocr/         # Textos OCR vía Gemini — output etapa 3
│   ├── subconsiderandos/   # Tablas estructuradas — output etapa 4
│   ├── obligaciones/       # Obligaciones extraídas — output etapa 5
│   ├── intermedio/         # Archivos intermedios del postprocesamiento
│   └── postprocessing/     # Dataset final limpio — output etapa 6
├── seia.xlsx               # Listado maestro de RCAs con metadatos
│
└── codigos/                # ← Este repositorio
    ├── 1_Doctr.ipynb
    ├── 2_Marcar.ipynb
    ├── 3_OCR_Pagado.ipynb
    ├── 4_subconsiderandos.ipynb
    ├── 4_aux/
    │   ├── 4.1_Instrucciones.ipynb   # Prompts para etapa 4
    │   └── 4.2_Modelo_Datos.ipynb    # Modelos Pydantic para etapa 4
    ├── 5_obligaciones.ipynb
    ├── 5_aux/
    │   ├── 5.1_Instrucciones.ipynb   # Prompts para etapa 5
    │   └── 5.2_Modelo_Datos.ipynb    # Modelos Pydantic para etapa 5
    ├── 6_postprocessing.ipynb
    └── 6_aux/
        ├── 6.1_decretos_pas.ipynb    # Separación por decretos y PAS
        ├── 6.2_duplicados_semanticos.ipynb
        ├── 6.3_contingencias_emergencias.ipynb
        ├── 6.4_fuentes.ipynb
        ├── 6.5_manuales.ipynb
        └── 6.6_comprimir.ipynb

Flujo del pipeline

archivos/*.pdf
      │
      ▼
[Etapa 1]  1_Doctr.ipynb
           OCR dual: pdfplumber (texto nativo) → doctr (escaneados)
           Output: resultados/doctr/Resultado_Consolidado.parquet
      │
      ▼
[Etapa 2]  2_Marcar.ipynb
           Identifica y marca las secciones relevantes del texto (mitigación,
           PAS, seguimiento, contingencias, etc.)
           Output: resultados/marcaje/chunk_*.parquet
      │
      ▼
[Etapa 3]  3_OCR_Pagado.ipynb
           OCR con Gemini para PDFs escaneados de baja calidad
           Output: resultados/gemini_ocr/*.txt
      │
      ▼
[Etapa 4]  4_subconsiderandos.ipynb
           Extrae subconsiderandos estructurados usando GPT con structured output
           Output: resultados/subconsiderandos/subconsiderandos_validos.xlsx
      │
      ▼
[Etapa 5]  5_obligaciones.ipynb
           Extrae obligaciones individuales de cada subconsiderando usando GPT
           Output: resultados/obligaciones/gpt-4o-mini/obligaciones.xlsx
      │
      ▼
[Etapa 6]  6_postprocessing.ipynb
           Limpieza, deduplicación exacta y semántica, clasificación de
           contingencias, normalización de fuentes normativas y compresión
           Output: resultados/postprocessing/obligaciones_combinadas_corregidas.xlsx

Cada etapa lee el output de la anterior. Los notebooks *_aux/ contienen los prompts del sistema e instrucciones y los modelos Pydantic que estructuran las respuestas de los LLMs.


Configuración

Requisitos

  • Python 3.9+
  • Clave de API de OpenAI (etapas 4, 5 y 6)
  • Clave de API de Google (solo etapa 3, para OCR con Gemini)

Instalación de dependencias

pip install pandas numpy openpyxl openai python-dotenv pydantic transformers \
            pdfplumber doctr-tf fuzzywuzzy python-Levenshtein tqdm docx2txt

Variables de entorno

Crea un archivo .env en la raíz del proyecto con tus claves de API:

OPENAI_API_KEY=sk-...
GOOGLE_API_KEY=...    # solo para etapa 3

Directorio raíz

Por defecto, cada notebook resuelve la raíz del proyecto como el directorio padre (..) asumiendo que se ejecuta desde la carpeta codigos/. Si lo ejecutas desde otro lugar, define la variable de entorno RCA_BASE_DIR:

# Linux / macOS
export RCA_BASE_DIR=/ruta/al/proyecto

# Windows (PowerShell)
$env:RCA_BASE_DIR = "C:\ruta\al\proyecto"

Descripción de etapas

Etapa 1 — OCR (1_Doctr.ipynb)

Lee los PDFs de archivos/ aplicando una estrategia dual: primero intenta extraer el texto nativo con pdfplumber; si el documento es escaneado o el texto extraído es muy escaso, lo procesa con doctr (modelo CRNN/FAST). El resultado es un archivo Parquet con el texto por página de cada RCA.

Etapa 2 — Marcaje de secciones (2_Marcar.ipynb)

Detecta las secciones canónicas de cada RCA (mitigación, plan de seguimiento, PAS, contingencias y emergencias, compromisos voluntarios, condiciones y exigencias) mediante fuzzy matching. El output son chunks de texto etiquetados por sección.

Etapa 3 — OCR avanzado (3_OCR_Pagado.ipynb)

Para las páginas que no pudieron procesarse correctamente con doctr, utiliza la API de Gemini para realizar un OCR de mayor calidad. Complementa el output de la etapa 1.

Etapa 4 — Subconsiderandos (4_subconsiderandos.ipynb)

Llama a GPT con structured output (modelos Pydantic en 4_aux/) para extraer las filas estructuradas que componen los subconsiderandos de cada sección, incluyendo campos como forma de cumplimiento, indicadores, normas, componente ambiental, fase del proyecto, entre otros.

Etapa 5 — Obligaciones (5_obligaciones.ipynb)

Sobre los subconsiderandos estructurados, llama nuevamente a GPT para extraer y desglosar las obligaciones individuales. Maneja el proceso de forma incremental (checkpoint automático), dividiendo el texto en chunks según límites de tokens y deduplicando duplicados por numero_tabla.

Etapa 6 — Postprocesamiento (6_postprocessing.ipynb)

Cadena de transformaciones aplicadas al dataset de obligaciones:

  1. Corrección de campos: mueve titulo a resumen donde corresponde.
  2. Eliminación de errores: descarta filas vacías o con valores genéricos (fuzzy matching).
  3. Deduplicación exacta: elimina duplicados por combinación de campos clave.
  4. Deduplicación semántica (6_aux/6.2): usa embeddings de OpenAI para detectar obligaciones equivalentes expresadas de forma distinta.
  5. Clasificación de contingencias (6_aux/6.3): clasifica las obligaciones de la sección de contingencias y emergencias en tipologías y subtipologías (Riesgos Operacionales, Naturales, etc.) usando GPT con structured output.
  6. Normalización de fuentes (6_aux/6.4, 6_aux/6.5): expande, estandariza y corrige las referencias normativas (decretos supremos, resoluciones, PAS), asociando cada obligación a su fuente de derecho.
  7. Compresión final (6_aux/6.6): agrupa todas las filas de una misma obligación en una única fila con columnas fuente_1, fuente_2, etc.

Contexto

Este trabajo es parte de un esfuerzo más amplio de la CNEP por caracterizar la carga regulatoria ambiental en Chile. El dataset resultante permite medir la distribución de obligaciones por sección, tipo de medida, componente ambiental y fuente normativa, tanto para proyectos mineros como energéticos.

Para más información sobre el estudio y sus resultados, consulta el informe disponible en www.cnep.cl.


Licencia

Este repositorio es publicado con fines de transparencia y reproducibilidad académica. El código puede reutilizarse libremente con atribución a la CNEP.

About

Códigos utilizados en la extracción de información de RCAs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors