Data Cleaning en RAG

En cualquier sistema de RAG, la calidad del resultado final depende directamente de la calidad del dato de entrada. Antes de aplicar técnicas de segmentación, generación de embeddings o recuperación de información, es imprescindible garantizar que el contenido extraído esté correctamente estructurado y libre de ruido.

En la práctica, los datos rara vez llegan en un formato listo para ser utilizados. Ya provengan de documentos PDF, páginas web u otras fuentes, el contenido suele presentar problemas como fragmentación del texto, elementos irrelevantes o estructuras inconsistentes. Estos problemas no son visibles a simple vista en todos los casos, pero tienen un impacto directo en el rendimiento del sistema.

Esto significa que, aunque el loader funcione correctamente, el resultado puede ser un texto difícil de utilizar en un sistema RAG como en este ejemplo:

print(document[6].page_content[:300]) 
zonas  premium:  cada  metro  valía  (y  vale)  mucho  más  en  Madrid,  Baleares  y  País  
Vasco
 
que
 
en
 
cualquier
 
otra
 
región.
 

Por tanto, antes de avanzar hacia fases más avanzadas del sistema, es necesario validar y procesar adecuadamente el contenido extraído. Un pipeline sólido no comienza con el modelo, sino con datos bien preparados.

Antes de generar embeddings, es fundamental aplicar una fase de limpieza del texto. El objetivo es reconstruir, en la medida de lo posible, una estructura natural del lenguaje.

  • Una estrategia básica de limpieza incluye:
  • Eliminación de saltos de línea innecesarios
  • Normalización de espacios
  • Unificación del texto en una secuencia continua

Este enfoque elimina múltiples espacios, saltos de línea y fragmentaciones simples, devolviendo un texto más coherente. Para casos más complejos, se pueden aplicar reglas adicionales, como la eliminación de patrones repetitivos o la reconstrucción de párrafos.

Métodos de limpieza de datos tras la carga (post-load)

Una vez cargados los documentos mediante un loader, el siguiente paso crítico es aplicar técnicas de limpieza que permitan transformar el texto en una forma coherente y útil para el sistema RAG.

No existe un único método universal. La limpieza debe adaptarse al tipo de fuente (PDF, web, datos estructurados), pero sí existen patrones comunes que se aplican en la mayoría de los casos:

Normalización básica de espacios

Eliminar espacios duplicados, saltos de línea y fragmentación simple. Se debe hacer siempre. Es el primer paso obligatorio.

text = document.page_content

clean_text = " ".join(text.split())

Soluciona:

  • Saltos de línea (\n)
  • Espacios múltiples
  • Texto fragmentado

Eliminación explícita de saltos de línea

Reconstruir frases que han sido cortadas artificialmente. Se utiliza en PDFs con líneas rotas y texto extraído por coordenadas

text = document.page_content

clean_text = text.replace("\n", " ")
clean_text = " ".join(clean_text.split())

Eliminación de patrones repetitivos (headers/footers)

Eliminar contenido repetido en todas las páginas. Como: “Página 1”, “Confidencial”, nombres de empresa, etc. Mejora la calidad del embedding.

import re

text = document.page_content

clean_text = re.sub(r'Página \d+', '', text)
clean_text = re.sub(r'Confidencial', '', clean_text)

Filtrado de líneas irrelevantes

Eliminar líneas demasiado cortas o sin valor semántico como títulos sueltos, fragmentos incompletos y ruido.

lines = document.page_content.split("\n")

clean_lines = [line for line in lines if len(line.strip()) > 30]

clean_text = " ".join(clean_lines)

Reconstrucción de párrafos

Unir líneas que pertenecen al mismo párrafo. Esta acción mejora coherencia y contexto para embeddings

lines = document.page_content.split("\n")

paragraph = ""

for line in lines:
    if line.strip():
        paragraph += line.strip() + " "
    else:
        paragraph += "\n"

clean_text = paragraph

Limpieza con expresiones regulares (regex)

Eliminar patrones complejos o caracteres no deseados. Usalo en PDFs sucios, OCR y datos con simbolos.

import re

text = document.page_content

# eliminar espacios múltiples
text = re.sub(r'\s+', ' ', text)

# eliminar caracteres raros
text = re.sub(r'[^\w\s.,€%-]', '', text)

Eliminación de contenido irrelevante por secciones

Eliminar partes completas del documento (ej. índice). Uso en informes largos y documentos estructurados.

text = document.page_content

if "Índice" in text:
    text = text.split("Introducción")[-1]

Limpieza específica para web (HTML)

Eliminar etiquetas HTML y contenido no útil. Elimina etiquetas, scripts y navegacion.

from bs4 import BeautifulSoup

html = document.page_content
soup = BeautifulSoup(html, "html.parser")

text = soup.get_text()

clean_text = " ".join(text.split())

Pipeline de limpieza básico recomendado

text = document.page_content
text = text.replace("\n", " ")
text = " ".join(text.split())

Versión más robusta

import re

text = document.page_content

text = text.replace("\n", " ")
text = re.sub(r'\s+', ' ', text)
text = re.sub(r'Página \d+', '', text)

La limpieza de datos no es un paso opcional dentro de un sistema RAG, sino una fase crítica que determina la calidad del resto del pipeline.

Aplicar técnicas básicas como la normalización de espacios o la eliminación de ruido puede mejorar significativamente la coherencia del texto y, por tanto, la precisión del sistema.

En entornos reales, la combinación de varios métodos de limpieza es la práctica habitual, adaptándose siempre al tipo de documento y a la calidad del contenido extraído.