R Academy · Lección

TF-IDF y análisis de frecuencia de términos

Calcule la importancia de los términos en varios documentos con bind_tf_idf().

Lección 2 de 413 pasos

TF-IDF y análisis de frecuencia de términos es una lección gratuita de R Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de R Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de R Academy incluye 4 lecciones en total.

¿Qué es TF-IDF?

TF-IDF (frecuencia de términos–frecuencia inversa de documentos) mide hasta qué punto una palabra es distintiva de un documento específico dentro de un corpus. Una puntuación TF-IDF alta significa que la palabra es frecuente en ese documento, pero poco frecuente en el conjunto de documentos: un buen indicador de los temas principales del documento.

# TF-IDF formula
# TF(w, d)  = count of w in document d / total words in d
# IDF(w)    = log(N / number of docs containing w)
# TF-IDF(w, d) = TF(w, d) * IDF(w)

# Manual example
N <- 4  # total documents
docs_with_word <- 1  # 'neural' appears in only 1 doc
tf <- 5 / 100  # word appears 5 times in 100-word doc
idf <- log(N / docs_with_word)
tfidf <- tf * idf

cat('TF:     ', round(tf, 4), '\n')
cat('IDF:    ', round(idf, 4), '\n')
cat('TF-IDF: ', round(tfidf, 4), '\n')

Preparar el recuento de tokens

Antes de calcular TF-IDF, necesita un marco de datos con las columnas document (identificador del documento), word (token) y n (recuento). Utilice unnest_tokens() seguido de count(document, word).

library(tidytext)
library(dplyr)

# Simulate a 4-document corpus on tech topics
docs <- tibble::tibble(
  document = c(rep('ML', 3), rep('Stats', 3), rep('DB', 3), rep('Web', 3)),
  text = c(
    'machine learning neural networks training',
    'deep learning models gradient descent',
    'reinforcement learning reward policy agent',
    'probability distributions hypothesis testing',
    'bayesian inference regression analysis variance',
    'statistics sampling confidence intervals normal',
    'database sql joins indexes queries transactions',
    'relational tables primary keys foreign constraints',
    'nosql document store mongodb redis cassandra',
    'html css javascript frontend react components',
    'dom events browser api fetch requests',
    'responsive design flexbox grid layout'
  )
)

word_counts <- docs |>
  unnest_tokens(word, text) |>
  count(document, word, sort = TRUE)

cat('Document-word pairs:', nrow(word_counts), '\n')
print(head(word_counts, 8))

bind_tf_idf: calcular TF-IDF

bind_tf_idf(word, document, n) toma un marco de datos tidy de recuentos y añade tres columnas: tf (frecuencia de términos), idf (frecuencia inversa de documentos) y tf_idf (su producto). Calcula el IDF a partir de los documentos presentes en el marco de datos.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c(rep('ML', 2), rep('Stats', 2), rep('DB', 2)),
  text = c(
    'machine learning neural gradient',
    'deep networks training epochs',
    'probability distributions variance covariance',
    'bayesian inference prior posterior',
    'sql database tables joins indexes',
    'queries transactions foreign primary'
  )
)

tfidf <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n)

cat('Columns added:', names(tfidf), '\n')
print(head(arrange(tfidf, desc(tf_idf)), 8))

arrange(desc(tf_idf)): términos principales

Ordene por tf_idf descendente para ver qué palabras caracterizan mejor cada documento. Las palabras con un IDF de cero (presentes en todos los documentos) tendrán un TF-IDF de cero independientemente de su frecuencia; no pueden distinguir entre documentos.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c(rep('Python', 3), rep('R', 3), rep('Julia', 3)),
  text = c(
    'python pandas numpy scipy programming',
    'machine learning scikit tensorflow keras',
    'jupyter notebooks scripts debugging modules',
    'ggplot2 dplyr tidyverse statistics vectors',
    'shiny rmarkdown knitr cran bioconductor',
    'linear models factors dataframes packages',
    'julia multiple dispatch type system macros',
    'package ecosystem flux diffeq parallel',
    'scientific computing performance benchmarks'
  )
)

top_terms <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n) |>
  arrange(desc(tf_idf))

cat('Top distinctive terms per language:\n')
print(head(top_terms[, c('document', 'word', 'tf_idf')], 9))

Términos TF-IDF principales por documento

Utilice group_by(document) |> slice_max(tf_idf, n = 5) para extraer los N términos más distintivos de cada documento. Este es un resumen muy útil de un corpus: el vocabulario distintivo de cada documento aparece con claridad.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c(rep('Cooking', 3), rep('Finance', 3), rep('Sports', 3)),
  text = c(
    'recipe ingredients oven bake flour butter',
    'cooking temperature boil simmer saute',
    'kitchen knife chopping herbs spices garnish',
    'investment portfolio returns dividends stocks bonds',
    'market equity risk hedge fund derivatives',
    'inflation interest rate treasury balance sheet',
    'goal tackle pass dribble goalkeeper penalty',
    'tournament league championship trophy season',
    'athlete training stamina sprint endurance'
  )
)

top5 <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n) |>
  group_by(document) |>
  slice_max(tf_idf, n = 3) |>
  ungroup()

print(top5[, c('document', 'word', 'tf_idf')])

Visualizar TF-IDF por documento

Los gráficos de barras de las puntuaciones TF-IDF, divididos por documento, revelan de un vistazo el vocabulario distintivo de cada documento. Utilice facet_wrap(~document, scales = 'free_y') para que cada panel muestre sus propios términos principales de forma independiente.

library(tidytext)
library(dplyr)
library(ggplot2)

docs <- tibble::tibble(
  document = c(rep('AI', 3), rep('DB', 3), rep('Web', 3)),
  text = c(
    'neural networks gradient backpropagation',
    'deep learning transformer attention bert',
    'reinforcement policy reward exploration',
    'sql database indexes joins transactions',
    'relational schema normalization queries',
    'nosql mongodb redis cassandra document',
    'html css javascript react dom',
    'frontend api fetch async components',
    'responsive flexbox grid webpack bundle'
  )
)

plot_data <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n) |>
  group_by(document) |>
  slice_max(tf_idf, n = 4) |>
  ungroup()

ggplot(plot_data, aes(reorder(word, tf_idf), tf_idf, fill = document)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~document, scales = 'free_y') +
  coord_flip() +
  labs(x = NULL, y = 'TF-IDF', title = 'Top TF-IDF Terms per Topic') +
  theme_minimal()

IDF: palabras que aparecen en todos los documentos

Las palabras que aparecen en todos los documentos obtienen IDF = log(N/N) = 0 y, por tanto, TF-IDF = 0. Esto reduce automáticamente el peso de las palabras comunes a todo el corpus sin necesidad de una lista de palabras vacías, aunque eliminar palabras vacías sigue siendo útil en corpus muy pequeños.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c('A', 'B', 'C'),
  text = c(
    'data analysis statistics regression probability',
    'data engineering pipelines etl transformation',
    'data visualisation ggplot2 charts dashboards'
  )
)

tfidf <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n)

# 'data' appears in all 3 docs: tf_idf should be 0
data_rows <- filter(tfidf, word == 'data')
cat('TF-IDF for "data" across documents:\n')
print(data_rows[, c('document', 'word', 'idf', 'tf_idf')])

Comparar dos documentos

TF-IDF facilita la comparación de documentos: busque términos con un TF-IDF alto en un documento, pero bajo o igual a cero en otro, para entender qué hace único a cada documento. Combine internamente las tablas TF-IDF por word y compare las puntuaciones.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c(rep('Doc1', 3), rep('Doc2', 3)),
  text = c(
    'bayesian statistics prior posterior mcmc',
    'markov chain monte carlo sampling',
    'probability distributions conjugate inference',
    'convolutional neural network image classification',
    'pooling activation relu softmax batch',
    'convolution filter feature map stride padding'
  )
)

tfidf <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n)

# Top 3 unique terms per document
tfidf |>
  group_by(document) |>
  slice_max(tf_idf, n = 3) |>
  select(document, word, tf_idf) |>
  print()

TF-IDF con novelas de Jane Austen

El paquete janeaustenr proporciona el texto completo de seis novelas de Austen. Este es un ejemplo clásico para TF-IDF: los lectores de Austen pueden identificar el vocabulario distintivo de cada novela; la palabra "wentworth" es casi exclusiva de Persuasion.

library(tidytext)
library(dplyr)

# Requires janeaustenr package
# library(janeaustenr)
# austen_books() returns: book, text

# Simulated mini-Austen corpus
mini_austen <- tibble::tibble(
  book = c(rep('Sense', 3), rep('Pride', 3), rep('Emma', 3)),
  text = c(
    'elinor marianne dashwood willoughby colonel',
    'edward ferrars barton cottage sister sense',
    'brandon feelings attachment sensibility heart',
    'darcy bennet bingley netherfield wickham',
    'jane lizzy lydia longbourn pemberley',
    'pride prejudice proposal marriage happiness',
    'emma woodhouse knightley harriet weston',
    'highbury match social governess niece',
    'frank jane fairfax box hill picnic'
  )
)

top <- mini_austen |>
  unnest_tokens(word, text) |>
  count(book, word) |>
  bind_tf_idf(word, book, n) |>
  group_by(book) |>
  slice_max(tf_idf, n = 3) |>
  select(book, word, tf_idf)

print(top)

TF-IDF para la ingeniería de características

Las puntuaciones TF-IDF se pueden utilizar como características en clasificadores de aprendizaje automático. Convierta el resultado tidy de TF-IDF en una matriz documento-término mediante cast_dtm() o cast_sparse() y páselo a glmnet, xgboost o cualquier otro clasificador.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  document = c(rep('Positive', 4), rep('Negative', 4)),
  text = c(
    'excellent product love recommend quality',
    'amazing fast delivery five star perfect',
    'great value money satisfied happy return',
    'wonderful experience purchase outstanding best',
    'terrible waste money broken arrived damaged',
    'horrible quality slow delivery disappointed awful',
    'poor value cheap plastic flimsy broken',
    'worst experience refund needed useless junk'
  )
)

# TF-IDF as features
tfidf_wide <- docs |>
  unnest_tokens(word, text) |>
  count(document, word) |>
  bind_tf_idf(word, document, n) |>
  cast_dtm(document, word, tf_idf)

cat('DTM dimensions:', dim(tfidf_wide), '\n')
cat('(rows=documents, cols=unique words)\n')

Limitaciones y alternativas

TF-IDF tiene algunas limitaciones: trata las palabras como independientes, ignora el orden y el contexto, y los errores ortográficos poco frecuentes pueden dominar el resultado. Entre las alternativas modernas se incluyen los embeddings de palabras (word2vec, GloVe) y los embeddings contextuales (BERT), pero TF-IDF sigue siendo excelente para la recuperación de documentos y como línea base de clasificación.

# TF-IDF strengths and weaknesses summary
criteria <- data.frame(
  Criterion = c('Speed', 'Interpretability', 'Context', 'Word order',
                'Rare words', 'Scalability'),
  TF_IDF    = c('Fast', 'High', 'None', 'Ignored',
                'High IDF (inflated)', 'Excellent'),
  BERT      = c('Slow', 'Low', 'Rich', 'Captured',
                'Handled', 'Moderate')
)

print(criteria, row.names = FALSE)

Comprobación rápida

Una palabra aparece en todos los documentos de su corpus. ¿Cuál será su puntuación TF-IDF?

Repaso: análisis TF-IDF

Conceptos clave:

  • TF-IDF = frecuencia de términos × frecuencia inversa de documentos; una puntuación alta indica una palabra distintiva
  • Flujo de trabajo: unnest_tokens() → count(document, word) → bind_tf_idf(word, document, n)
  • bind_tf_idf() añade las columnas tf, idf y tf_idf
  • arrange(desc(tf_idf)) / slice_max(tf_idf, n = 5) muestra los términos principales de cada documento
  • Las palabras presentes en todos los documentos obtienen automáticamente IDF = 0 y TF-IDF = 0
  • cast_dtm(document, word, tf_idf) convierte los datos en una matriz documento-término para aprendizaje automático
  • Los gráficos de barras divididos por facetas son la visualización estándar de los resultados TF-IDF
library(tidytext)
library(dplyr)

# Minimal TF-IDF pipeline
tibble::tibble(
  doc = c('A', 'A', 'B', 'B'),
  text = c('neural networks deep', 'learning training', 'sql database query', 'joins indexes')
) |>
  unnest_tokens(word, text) |>
  count(doc, word) |>
  bind_tf_idf(word, doc, n) |>
  arrange(desc(tf_idf)) |>
  print()
Gratis para empezar

Aprende R con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
43
Lecciones
159

Preguntas frecuentes

¿La lección «TF-IDF y análisis de frecuencia de términos» es gratis?

Sí — el texto completo de «TF-IDF y análisis de frecuencia de términos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de R Academy, actualiza a CoddyKit PRO. El curso de R Academy incluye 4 lecciones en total.

¿Qué aprenderé en «TF-IDF y análisis de frecuencia de términos»?

Calcule la importancia de los términos en varios documentos con bind_tf_idf(). Practicas R Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar R Academy?

No se requiere experiencia previa. R Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «TF-IDF y análisis de frecuencia de términos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de R Academy?

Sí. Cada lección de R Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Tokenización y eliminación de palabras vacías
  2. TF-IDF y análisis de frecuencia de términos
  3. Análisis de sentimientos en R
  4. Modelado de temas con LDA
← Volver a R Academy