Capítulo 3: Manejo de diferentes tipos de archivo
Introducción
Los documentos del mundo real vienen en muchos formatos, cada uno con desafíos únicos. Este capítulo cubre estrategias para manejar PDFs, imágenes, tablas y datos estructurados.
Desafíos de los PDF
Los PDFs son el formato de documento más común, pero también el más desafiante:
Áreas problemáticas
| Desafío | Descripción | Solución |
|---|---|---|
| PDFs escaneados | Imágenes, no texto | Procesamiento OCR |
| Tablas | Se pierde la estructura | Extractores especializados |
| Multicolumna | Orden de lectura incorrecto | Análisis de diseño |
| Encabezados/Pies de página | Ruido repetido | Filtrado |
Opciones de extracción de PDF
# Opción 1: Básica (PyPDF2/PyPDFLoader)
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("document.pdf")
# Pros: Rápido, simple
# Contras: Deficiente con diseños complejos
# Opción 2: Mejores tablas (PDFPlumber)
from langchain.document_loaders import PDFPlumberLoader
loader = PDFPlumberLoader("document.pdf")
# Pros: Mejor extracción de tablas
# Contras: Más lento
# Opción 3: Mejor calidad (Unstructured)
from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader(
"document.pdf",
mode="elements", # Conserva la estructura
strategy="hi_res" # Mejor calidad
)
# Pros: Mejor calidad general
# Contras: Requiere dependencias adicionales
OCR para documentos escaneados
Para PDFs escaneados e imágenes:
# Usando Tesseract OCR
from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader(
"scanned_document.pdf",
strategy="ocr_only",
ocr_languages="eng"
)
documents = loader.load()
# Usando Amazon Textract
from langchain.document_loaders import AmazonTextractPDFLoader
loader = AmazonTextractPDFLoader(
"scanned.pdf",
client=textract_client
)
Buenas prácticas de OCR
- Preprocesar imágenes - Corregir inclinación, mejorar contraste
- Especificar idioma - Mejora la precisión
- Posprocesar texto - Corregir errores comunes de OCR
- Puntajes de confianza - Marcar extracciones de baja confianza
Manejo de tablas
Las tablas requieren un manejo especial para preservar la estructura:
# Método 1: Convertir a Markdown
from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader(
"report.pdf",
mode="elements"
)
docs = loader.load()
# Las tablas vienen como elementos estructurados
for doc in docs:
if doc.metadata.get("category") == "Table":
# Procesar la tabla de forma especial
table_markdown = convert_table_to_markdown(doc)
# Método 2: Usando Camelot para PDFs
import camelot
tables = camelot.read_pdf("document.pdf", pages="all")
for table in tables:
df = table.df
markdown = df.to_markdown()
Estrategia de fragmentación de tablas
def chunk_with_tables(documents):
chunks = []
for doc in documents:
if is_table(doc):
# Mantener las tablas como fragmentos individuales
chunks.append(doc)
else:
# Fragmentación normal para texto
text_chunks = splitter.split_documents([doc])
chunks.extend(text_chunks)
return chunks
Imágenes en documentos
Extraer y procesar imágenes:
# Extraer imágenes de PDF
import fitz # PyMuPDF
doc = fitz.open("document.pdf")
for page_num, page in enumerate(doc):
images = page.get_images()
for img_index, img in enumerate(images):
# Extraer imagen
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
# Procesar con modelo de visión
description = vision_model.describe(image_bytes)
# Agregar descripción al documento
Integración con modelo de visión
from langchain.chat_models import ChatOpenAI
# Usar GPT-4 Vision para comprensión de imágenes
vision_llm = ChatOpenAI(model="gpt-4-vision-preview")
def describe_image(image_path):
response = vision_llm.invoke([
{
"type": "image_url",
"image_url": f"data:image/jpeg;base64,{base64_image}"
},
{
"type": "text",
"text": "Describa esta imagen en detalle para búsqueda documental."
}
])
return response.content
Datos estructurados
JSON/JSONL
from langchain.document_loaders import JSONLoader
loader = JSONLoader(
file_path="data.json",
jq_schema=".data[].content",
text_content=False
)
CSV
from langchain.document_loaders import CSVLoader
loader = CSVLoader(
file_path="data.csv",
csv_args={"delimiter": ","},
source_column="source"
)
# Para CSV grandes, procesar por lotes
import pandas as pd
def load_csv_in_batches(file_path, batch_size=1000):
for chunk in pd.read_csv(file_path, chunksize=batch_size):
yield from chunk.to_dict('records')
Bases de datos SQL
from langchain.document_loaders import SQLDatabaseLoader
from langchain.utilities import SQLDatabase
db = SQLDatabase.from_uri("postgresql://user:pass@localhost/db")
loader = SQLDatabaseLoader(
db=db,
query="SELECT id, content, metadata FROM documents WHERE active = true"
)
Pipeline de procesamiento completo
from pathlib import Path
def process_document(file_path: str):
"""Procesador universal de documentos"""
path = Path(file_path)
extension = path.suffix.lower()
loaders = {
".pdf": lambda p: UnstructuredPDFLoader(p, strategy="hi_res"),
".docx": lambda p: Docx2txtLoader(p),
".txt": lambda p: TextLoader(p, encoding="utf-8"),
".html": lambda p: UnstructuredHTMLLoader(p),
".md": lambda p: UnstructuredMarkdownLoader(p),
".csv": lambda p: CSVLoader(p),
".json": lambda p: JSONLoader(p, jq_schema=".[]")
}
if extension not in loaders:
raise ValueError(f"Unsupported file type: {extension}")
loader = loaders[extension](str(path))
documents = loader.load()
# Agregar metadatos del archivo
for doc in documents:
doc.metadata["file_name"] = path.name
doc.metadata["file_type"] = extension
doc.metadata["file_size"] = path.stat().st_size
return documents
Resumen
| Tipo de archivo | Mejor loader | Notas |
|---|---|---|
| PDF (texto) | PDFPlumberLoader | Buen soporte de tablas |
| PDF (escaneado) | UnstructuredPDFLoader + OCR | Use estrategia hi_res |
| Word | Docx2txtLoader | Rápido y confiable |
| HTML | UnstructuredHTMLLoader | Elimina etiquetas |
| CSV | CSVLoader | Lote para archivos grandes |
| Imágenes | Modelos de visión | Para imágenes incrustadas |
Puntos clave
- Los PDFs son complejos - Use el loader adecuado según sus necesidades
- OCR para documentos escaneados - Esencial para PDFs basados en imágenes
- Las tablas requieren manejo especial - No fragmente entre filas
- Las imágenes requieren descripción - Use modelos de visión
- Pruebe su pipeline - Con muestras representativas
Próximos pasos
¡Ponga a prueba sus conocimientos con el Cuestionario del Módulo 2!