diff --git a/apply_content.py b/apply_content.py index 0f28fcf..24c79d3 100644 --- a/apply_content.py +++ b/apply_content.py @@ -4,6 +4,7 @@ import re import os from bs4 import BeautifulSoup, NavigableString +from latex2mathml.converter import convert as latex_to_mathml BASE_DIR = os.path.dirname(os.path.abspath(__file__)) TEMPLATE_INPUT = os.path.join(BASE_DIR, 'instructions/plantilla_individual.htm') @@ -38,6 +39,30 @@ def md_to_html_para(text): text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'\1', text) return text +def convert_latex_formulas(text): + """Convert LaTeX formulas to MathML for Word compatibility.""" + # Block formulas $$...$$ + def convert_block(match): + latex = match.group(1) + try: + mathml = latex_to_mathml(latex, display="block") + return f'

{mathml}

' + except: + return match.group(0) # Keep original if conversion fails + + text = re.sub(r'\$\$([^$]+)\$\$', convert_block, text) + + # Inline formulas $...$ + def convert_inline(match): + latex = match.group(1) + try: + return latex_to_mathml(latex, display="inline") + except: + return match.group(0) + + text = re.sub(r'\$([^$]+)\$', convert_inline, text) + return text + def extract_table_title(lines, current_index): """Look for table title in preceding lines (e.g., **Tabla 1.** *Title*).""" # Check previous non-empty lines for table title @@ -251,6 +276,7 @@ def parse_md_to_html_blocks(md_content): if re.match(r'^[\-\*\+]\s', line): while i < len(lines) and re.match(r'^[\-\*\+]\s', lines[i]): item_text = lines[i][2:].strip() + item_text = convert_latex_formulas(item_text) html_blocks.append(f'

·     {md_to_html_para(item_text)}

') i += 1 continue @@ -260,6 +286,7 @@ def parse_md_to_html_blocks(md_content): num = 1 while i < len(lines) and re.match(r'^\d+\.\s', lines[i]): item_text = re.sub(r'^\d+\.\s*', '', lines[i]).strip() + item_text = convert_latex_formulas(item_text) html_blocks.append(f'

{num}.   {md_to_html_para(item_text)}

') num += 1 i += 1 @@ -284,7 +311,12 @@ def parse_md_to_html_blocks(md_content): i += 1 para_text = ' '.join(para_lines) - html_blocks.append(f'

{md_to_html_para(para_text)}

') + para_text = convert_latex_formulas(para_text) + # Check if paragraph contains MathML (already wrapped) + if '{md_to_html_para(para_text)}

') return '\n\n'.join(html_blocks) diff --git a/thesis_output/plantilla_individual.htm b/thesis_output/plantilla_individual.htm index 00ae5b9..4b121c9 100644 --- a/thesis_output/plantilla_individual.htm +++ b/thesis_output/plantilla_individual.htm @@ -4678,11 +4678,11 @@ _Toc14106979">La evaluación rigurosa de sistemas OCR requiere métricas estandarizadas que permitan comparaciones objetivas. Las métricas fundamentales se basan en la distancia de edición de Levenshtein.

Distancia de Levenshtein

La distancia de Levenshtein (Levenshtein, 1966) entre dos cadenas es el número mínimo de operaciones de edición (inserción, eliminación, sustitución) necesarias para transformar una cadena en otra. Formalmente, para dos cadenas a y b:

-

$$d(a,b) = \min(\text{inserciones} + \text{eliminaciones} + \text{sustituciones})$$

+

d(a,b)=min(inserciones+eliminaciones+sustituciones)

Esta métrica es fundamental para calcular tanto CER como WER.

Character Error Rate (CER)

El CER mide el error a nivel de carácter y se calcula como:

-

$$CER = \frac{S + D + I}{N}$$

+

CER=S+D+IN

Donde:

·     S = número de sustituciones de caracteres

·     D = número de eliminaciones de caracteres

@@ -4695,7 +4695,7 @@ _Toc14106979">·     Búsqueda y archivo: CER < 5% puede ser suficiente

Word Error Rate (WER)

El WER mide el error a nivel de palabra, utilizando la misma fórmula pero considerando palabras como unidades:

-

$$WER = \frac{S_w + D_w + I_w}{N_w}$$

+

WER=Sw+Dw+IwNw

El WER es generalmente mayor que el CER, ya que un solo error de carácter puede invalidar una palabra completa. La relación típica es WER ≈ 2-3 × CER para texto en español.

Otras Métricas Complementarias

Precision y Recall a nivel de palabra: Útiles cuando se evalúa la capacidad del sistema para detectar palabras específicas.

@@ -4808,16 +4808,18 @@ _Toc14106979">·     Parámetros de regularización (dropout, weight decay)

·     Umbrales de decisión en tiempo de inferencia (relevante para este trabajo)

El problema de HPO puede formalizarse como:

-

$$\lambda^* = \arg\min_{\lambda \in \Lambda} \mathcal{L}(M_\lambda, D_{val})$$

+

λ*=\argminλΛ(Mλ,Dval)

Donde:

-

·     $\lambda$ es un vector de hiperparámetros

-

·     $\Lambda$ es el espacio de búsqueda

-

·     $M_\lambda$ es el modelo configurado con $\lambda$

-

·     $\mathcal{L}$ es la función de pérdida

-

·     $D_{val}$ es el conjunto de validación

+

·     λ es un vector de hiperparámetros

+

·     Λ es el espacio de búsqueda

+

·     Mλ es el modelo configurado con λ

+

·      es la función de pérdida

+

·     Dval es el conjunto de validación

Métodos de Optimización

Grid Search (Búsqueda en rejilla):

-

El método más simple consiste en evaluar todas las combinaciones posibles de valores discretizados de los hiperparámetros. Para $k$ hiperparámetros con $n$ valores cada uno, requiere $n^k$ evaluaciones.

+ +El método más simple consiste en evaluar todas las combinaciones posibles de valores discretizados de los hiperparámetros. Para k hiperparámetros con n valores cada uno, requiere nk evaluaciones. +

Ventajas:

·     Exhaustivo y reproducible

·     Fácil de paralelizar

@@ -4841,12 +4843,18 @@ _Toc14106979">·     Random Forests: Manejan bien espacios de alta dimensión y variables categóricas

·     Tree-structured Parzen Estimator (TPE): Modela densidades en lugar de la función objetivo

Tree-structured Parzen Estimator (TPE)

-

TPE, propuesto por Bergstra et al. (2011) e implementado en Optuna, es particularmente efectivo para HPO. En lugar de modelar $p(y|\lambda)$ directamente, TPE modela:

-

$$p(\lambda|y) = \begin{cases} l(\lambda) & \text{si } y < y^ \\ g(\lambda) & \text{si } y \geq y^ \end{cases}$$

-

Donde $y^*$ es un umbral (típicamente el percentil 15-25 de las observaciones), $l(\lambda)$ es la densidad de hiperparámetros con buen rendimiento, y $g(\lambda)$ es la densidad de hiperparámetros con mal rendimiento.

+ +TPE, propuesto por Bergstra et al. (2011) e implementado en Optuna, es particularmente efectivo para HPO. En lugar de modelar p(y|λ) directamente, TPE modela: + +

p(λ|y)={l(λ)si y<y*g(λ)si yy*

+ +Donde y* es un umbral (típicamente el percentil 15-25 de las observaciones), l(λ) es la densidad de hiperparámetros con buen rendimiento, y g(λ) es la densidad de hiperparámetros con mal rendimiento. +

La función de adquisición Expected Improvement se aproxima como:

-

$$EI(\lambda) \propto \frac{l(\lambda)}{g(\lambda)}$$

-

Configuraciones con alta probabilidad bajo $l$ y baja probabilidad bajo $g$ tienen mayor Expected Improvement.

+

EI(λ)l(λ)g(λ)

+ +Configuraciones con alta probabilidad bajo l y baja probabilidad bajo g tienen mayor Expected Improvement. +

Ventajas de TPE:

·     Maneja naturalmente espacios condicionales (hiperparámetros que dependen de otros)

·     Eficiente para espacios de alta dimensión