10 · TF-IDF: intuición y matemáticas
Entiende por qué los conteos crudos engañan — y cómo TF-IDF pondera alto las palabras raras y específicas del documento mientras silencia los tokens de ruido comunes.
TF-IDF pondera los conteos crudos de palabras por la frecuencia inversa de documentos — las palabras raras y específicas del documento puntúan alto; las palabras 'ruido' comunes puntúan bajo.
Sin esto:
BOW trata 'the' igual que 'antibiotic' — tu vector está dominado por tokens sin información.
La bolsa de palabras cuenta cuántas veces aparece cada palabra en un documento. Eso suena razonable — hasta que te das cuenta de que las palabras extremadamente comunes como "the", "is" y "a" acumulan conteos enormes en todos los documentos sin decirte nada útil sobre de qué trata el documento.
BOW sobre-cuenta las palabras comunes. Un documento con 500 ocurrencias de "the" no contiene más información sobre "the" que uno con 50. Esos conteos crudos solo añaden ruido.
TF-IDF (Term Frequency–Inverse Document Frequency) corrige esto multiplicando dos factores:
- TF(t, d) — con qué frecuencia aparece el término t en el documento d (o una versión normalizada).
- IDF(t) — cuánta información lleva el término en todo el corpus. Las palabras que aparecen en casi todos los documentos tienen muy poco poder discriminativo — su IDF es cercano a cero.
El resultado: una palabra que aparece muchas veces en un documento pero raramente en otros obtiene un puntaje TF-IDF alto. Una palabra que aparece en todas partes obtiene un puntaje cercano a cero — suprimida automáticamente, sin necesidad de lista de stopwords.
La fórmula:
TF(t, d) = count(t, d) / total_tokens(d) # frecuencia de término normalizada
IDF(t) = log( N / DF(t) ) # N = total docs, DF = docs que contienen t
TF-IDF = TF(t, d) * IDF(t)
El TfidfVectorizer de sklearn usa una variante suavizada para evitar la división por cero (+1 dentro del logaritmo y en el denominador) y normaliza L2 cada fila de documento para que la longitud del documento no sesgue las comparaciones.
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Cuatro razones por las que TF-IDF supera a BOW para búsqueda y recuperación
Si una palabra aparece en TODOS los documentos del corpus, ¿cuál es su puntaje IDF?
- TF-IDF = TF(t,d) × IDF(t), donde IDF = log(N/DF(t)). Las palabras que aparecen en todos los documentos obtienen IDF ≈ 0 y se suprimen automáticamente — no se necesita lista manual de stopwords.
- El TfidfVectorizer de sklearn usa suavizado (+1 en numerador y denominador del logaritmo) y normalización L2 por fila — los valores difieren ligeramente del TF-IDF crudo pero el orden de ranking se preserva.
- La similitud coseno sobre vectores TF-IDF es la columna vertebral de la recuperación clásica de documentos — los documentos semánticamente similares comparten términos raros y específicos del documento, que el coseno premia.
- TF-IDF es BOW con pesos inteligentes — la forma de la matriz es idéntica (n_docs × vocab_size) y todos los trucos de matrices dispersas siguen aplicando; solo cambian los valores.
Todo motor de búsqueda y sistema de recuperación de documentos usa TF-IDF como línea base. BM25 de Lucene/Elasticsearch es un refinamiento moderno de TF-IDF que añade normalización de longitud y saturación de términos. Los sistemas modernos de búsqueda por vectores densos (FAISS, bases de datos vectoriales) típicamente usan dual TF-IDF para recuperación dispersa y embeddings para recuperación densa, combinando ambos mediante fusión de rango recíproco.
Si lo quitas: Sin la intuición de TF-IDF, BM25 y la recuperación híbrida densa-dispersa parecen arbitrarios. TF-IDF es el peldaño conceptual entre BOW crudo y las arquitecturas de recuperación modernas.