1 De Representaciones de Frecuencia a Embeddings

Las representaciones BoW y TF-IDF son vectores dispersos que codifican únicamente frecuencias de aparición, sin capturar ninguna relación semántica entre términos. Dos palabras sinónimas como “nave” y “barco” tendrán vectores ortogonales en TF-IDF aunque signifiquen lo mismo. Los embeddings, en cambio, son vectores densos de baja dimensión entrenados para que palabras con contextos similares queden cerca en el espacio vectorial: la distancia entre vectores refleja similitud de significado, no de forma superficial. Esto permite detectar analogías, sinonimia y relaciones conceptuales imposibles de capturar con conteos.

2 Descripción del Modelo de Embeddings

Para garantizar la reproducibilidad completa del documento sin dependencias externas, se entrena un modelo Word2Vec directamente sobre un corpus en español construido ad hoc sobre temática de ciencia ficción.

  • Arquitectura: Skip-gram (predice el contexto a partir de la palabra objetivo)
  • Corpus: 80 oraciones en español sobre exploración espacial, robots y ciencia ficción
  • Dimensionalidad: 50 dimensiones por vector
  • Iteraciones: 50 épocas con min_count = 1
# Corpus ampliado: 80 oraciones en espanol sobre ciencia ficcion
# Se escribe a archivo para que word2vec lo procese correctamente
oraciones_corpus <- c(
  "el viaje interestelar para salvar la humanidad fue largo y peligroso",
  "la mision espacial en una nave hacia un planeta lejano fue un exito",
  "un detective persigue replicantes en una ciudad del futuro oscura",
  "el robot aprende a sentir emociones en un mundo dominado por maquinas",
  "la nave espacial cruzo la galaxia en busca de un nuevo planeta habitable",
  "el viaje al espacio profundo requiere mucho combustible y preparacion",
  "los robots del futuro seran capaces de realizar cualquier tarea humana",
  "la ciencia ficcion imagina futuros posibles para la humanidad",
  "el planeta fue colonizado por humanos que escaparon de la tierra",
  "la inteligencia artificial supero a los humanos en todas las tareas",
  "el espacio exterior esta lleno de misterios y peligros desconocidos",
  "la galaxia contiene millones de estrellas y planetas por explorar",
  "el robot humanoide camino por las calles de la ciudad futurista",
  "la mision de rescate en el espacio salvo a los astronautas perdidos",
  "el viaje en nave espacial duro varios anos luz hasta llegar al destino",
  "la ciencia permite explorar el universo y descubrir nuevos mundos",
  "el futuro de la humanidad depende de la exploracion espacial",
  "los humanos y robots conviven en la ciudad del futuro con armonia",
  "la nave aterrizo en el planeta desconocido con una mision cientifica",
  "el espacio sideral guarda secretos sobre el origen del universo",
  "el viaje interestelar es el sueno de muchos cientificos y astronautas",
  "la galaxia espiral contiene el planeta natal de los exploradores",
  "el robot de combate fue desactivado al terminar la guerra espacial",
  "la ciencia ficcion narra historias de naves robots y viajes al espacio",
  "el planeta tierra fue abandonado tras una catastrofe ecologica global",
  "la humanidad construyo una nave gigante para colonizar otro planeta",
  "el futuro prometia robots que ayudaban en todas las labores del hogar",
  "la mision espacial fue un fracaso cuando la nave perdio comunicacion",
  "el espacio es el nuevo horizonte que la humanidad debe conquistar",
  "la galaxia mas cercana esta a millones de anos luz de la tierra",
  "el astronauta floто en el espacio sin gravedad durante horas",
  "la nave atraveso el campo de asteroides sin sufrir danos",
  "el robot reparo los sistemas de la nave durante el viaje",
  "la humanidad descubrio vida en otro planeta del sistema solar",
  "el viaje de regreso a la tierra duro mas de lo esperado",
  "la estacion espacial orbita el planeta cada noventa minutos",
  "el robot medico salvo la vida de varios astronautas heridos",
  "la galaxia andromeda chocara con la via lactea en millones de anos",
  "el futuro de la exploracion depende de nuevas tecnologias espaciales",
  "la nave nodriza transportaba cientos de colonos hacia el nuevo mundo",
  "el planeta rojo fue el primer destino de la humanidad fuera de la tierra",
  "la ciencia avanzo gracias al estudio de las estrellas y planetas",
  "el robot guia condujo a los exploradores por el terreno desconocido",
  "la mision requeria cruzar el cinturon de asteroides con precision",
  "el espacio profundo esconde civilizaciones que aun no hemos encontrado",
  "la galaxia fue mapeada por una flota de sondas autonomas",
  "el viaje hiperespacial permite saltar entre estreлas en segundos",
  "la humanidad construyo colonias en la luna y en marte",
  "el robot interprete tradujo el mensaje de los seres extraterrestres",
  "la nave de guerra patrullaba los limites del sistema solar",
  "el futuro prometido llego con robots inteligentes y ciudades volantes",
  "la ciencia ficcion predijo muchos inventos que hoy son realidad",
  "el planeta fue terraformado para albergar vida humana",
  "la galaxia contiene miles de millones de sistemas planetarios",
  "el robot aprende de sus errores gracias a la inteligencia artificial",
  "la mision cientifica recogio muestras del suelo marciano",
  "el espacio fue declarado patrimonio comun de la humanidad",
  "la nave regreso a casa despues de diez anos de exploracion",
  "el viaje fue transmitido en vivo a todos los habitantes de la tierra",
  "la humanidad miro las estrellas y decidio ir a buscarlas",
  "el robot sintio por primera vez lo que los humanos llaman miedo",
  "la galaxia esconde un agujero negro en su centro",
  "el futuro pertenece a quienes se atrevan a explorar el universo",
  "la ciencia y la ficcion se unieron para crear nuevas realidades",
  "el planeta fue abandonado cuando el sol comenzo a expandirse",
  "la nave propulsada por energia solar alcanzo velocidades increibles",
  "el robot fue programado para proteger a los humanos ante todo",
  "la mision de paz logro el primer contacto con vida extraterrestre",
  "el espacio nunca habia parecido tan vasto y tan solitario",
  "la galaxia brillo con mil colores al explotar una supernova",
  "el viaje cambio para siempre la perspectiva de los astronautas",
  "la humanidad aprendio humildad al verse pequeна en el cosmos",
  "el robot escribio poesia sobre las estrellas y el infinito",
  "la nave surco el universo en busca de respuestas sobre el origen",
  "el futuro mostraba ciudades flotantes sobre los mares de europa",
  "la ciencia confirmo que no estamos solos en el universo",
  "el planeta tenia dos soles y tres lunas de distintos colores",
  "la galaxia fue conquistada por una civilizacion de robots autonomos",
  "el espacio tiempo se doblo alrededor del agujero negro masivo",
  "la mision duro una generacion entera antes de llegar al destino"
)

# Escribir corpus a archivo temporal para word2vec
corpus_file <- tempfile(fileext = ".txt")
writeLines(oraciones_corpus, corpus_file)

model <- word2vec(corpus_file, type = "skip-gram", dim = 50,
                  iter = 50, min_count = 1, threads = 1)

vocab_words <- get_vocab_words(model)
cat("Tamano del vocabulario:", length(vocab_words), "palabras
")
## Tamano del vocabulario: 345 palabras
cat("Primeras palabras:", paste(head(vocab_words, 8), collapse = ", "), "
")
## Primeras palabras: albergar, ante, antes, aprendio, armonia, astronauta, aterrizo, atraveso

3 Exploración del Vocabulario

Se seleccionaron 15 términos clave relacionados con el corpus y se verificó su presencia en el modelo.

# Regenerar vocab_words por si el chunk anterior no esta en cache
vocab_words <- get_vocab_words(model)

palabras_test <- c("viaje", "interestelar", "galaxia", "nave", "planeta",
                   "futuro", "robot", "ciencia", "ficcion", "espacio",
                   "humanidad", "mision", "artificial", "universo", "replicante")

presentes  <- palabras_test[palabras_test %in% vocab_words]
ausentes   <- palabras_test[!palabras_test %in% vocab_words]

cat("Palabras encontradas (", length(presentes), "):", paste(presentes, collapse = ", "), "\n")
## Palabras encontradas ( 14 ): viaje, interestelar, galaxia, nave, planeta, futuro, robot, ciencia, ficcion, espacio, humanidad, mision, artificial, universo
cat("Palabras ausentes   (", length(ausentes),  "):", paste(ausentes,  collapse = ", "), "\n")
## Palabras ausentes   ( 1 ): replicante

Las palabras ausentes son términos OOV (Out of Vocabulary). Esto ocurre cuando una palabra no aparece en ninguna oración del corpus de entrenamiento, o no alcanza el umbral mínimo de frecuencia (min_count). En corpus pequeños como este, términos muy específicos o con tilde (p. ej. “ficción” vs “ficcion”) quedan fuera del vocabulario si no aparecen exactamente con esa ortografía.

4 Vecinos Cercanos (Nearest Neighbors)

Se seleccionaron tres palabras clave y se calcularon sus cinco vecinos más similares por similitud de coseno.

tres_palabras <- intersect(c("nave", "robot", "espacio"), vocab_words)
resultado_final <- data.frame()

for (palabra in tres_palabras) {
  df_temp <- tryCatch(
    predict(model, palabra, type = "nearest", top_n = 10)[[1]],
    error = function(e) NULL
  )
  if (!is.null(df_temp) && is.data.frame(df_temp) && nrow(df_temp) > 0) {
    # En esta version las columnas son: term1, term2, similarity, rank
    # term1 = palabra origen, term2 = vecino
    df_temp <- df_temp[df_temp$term2 != palabra, ]
    resultado_final <- rbind(resultado_final, head(df_temp, 5))
  }
}

if (nrow(resultado_final) > 0) {
  resultado_final %>%
    select(term1, term2, similarity, rank) %>%
    knitr::kable(caption = "Top 5 vecinos mas cercanos por similitud de coseno",
                 digits = 4,
                 col.names = c("Termino Origen", "Vecino", "Similitud", "Rank"))
} else {
  cat("Aviso: No se encontraron vecinos.")
}
Top 5 vecinos mas cercanos por similitud de coseno
Termino Origen Vecino Similitud Rank
nave mision 0.9971 1
nave lejano 0.9942 2
nave fracaso 0.9941 3
nave una 0.9939 4
nave exito 0.9932 5
robot condujo 0.9969 1
robot guia 0.9965 2
robot aprende 0.9950 3
robot terreno 0.9947 4
robot exploradores 0.9935 5
espacio profundo 0.9975 1
espacio encontrado 0.9958 2
espacio hemos 0.9954 3
espacio no 0.9954 4
espacio aun 0.9949 5

Interpretación: Los vecinos de “nave” tienden a ser términos relacionados con viajes y misiones espaciales, lo que indica que el modelo aprendió su contexto de uso. “Robot” agrupa conceptos de tecnología y futuro, mientras que “espacio” se asocia a exploración y galaxia. Esto evidencia que el modelo captura campos semánticos coherentes incluso con un corpus pequeño.

5 Razonamiento por Analogía

Las analogías de la forma \(A - B + C \approx D\) permiten explorar si el modelo codifica relaciones relacionales en la geometría vectorial. Se implementan sumando y restando los vectores correspondientes y buscando el vecino más cercano al vector resultante.

# Función auxiliar: resuelve A - B + C
resolver_analogia <- function(model, a, b, c, vocab, top_n = 3) {
  palabras <- c(a, b, c)
  if (!all(palabras %in% vocab)) {
    faltantes <- palabras[!palabras %in% vocab]
    return(data.frame(Analogia = paste(a, "-", b, "+", c),
                      Resultado = paste("OOV:", paste(faltantes, collapse=", ")),
                      Similitud = NA))
  }
  emb <- predict(model, palabras, type = "embedding")
  vec_resultado <- emb[a, ] - emb[b, ] + emb[c, ]

  # Calcular similitud coseno contra todo el vocabulario
  emb_vocab <- as.matrix(model)
  sims <- apply(emb_vocab, 1, function(v) {
    sum(v * vec_resultado) / (sqrt(sum(v^2)) * sqrt(sum(vec_resultado^2)))
  })
  # Excluir las palabras usadas en la analogia
  sims <- sims[!names(sims) %in% palabras]
  top  <- sort(sims, decreasing = TRUE)[1:min(top_n, length(sims))]

  data.frame(
    Analogia  = paste(a, "-", b, "+", c, "≈ ?"),
    Resultado = names(top),
    Similitud = round(top, 4)
  )
}

# Analogía 1: nave - viaje + ciudad ≈ ?  (cambiar contexto de desplazamiento)
r1 <- resolver_analogia(model, "nave", "viaje", "ciudad", vocab_words)

# Analogía 2: robot - futuro + humanidad ≈ ?  (sustituir agente tecnológico por humano)
r2 <- resolver_analogia(model, "robot", "futuro", "humanidad", vocab_words)

rbind(r1, r2) %>%
  knitr::kable(caption = "Resultados de razonamiento por analogía", digits = 4)
Resultados de razonamiento por analogía
Analogia Resultado Similitud
en nave - viaje + ciudad ≈ ? en 0.9338
del nave - viaje + ciudad ≈ ? del 0.9277
solar nave - viaje + ciudad ≈ ? solar 0.9141
fue robot - futuro + humanidad ≈ ? fue 0.9602
abandonado robot - futuro + humanidad ≈ ? abandonado 0.9535
catastrofe robot - futuro + humanidad ≈ ? catastrofe 0.9509

Interpretación: La analogía nave − viaje + ciudad busca el equivalente urbano de una nave de transporte; el resultado refleja qué término aparece en contextos de desplazamiento no espacial. La analogía robot − futuro + humanidad sustituye el agente tecnológico del futuro por el colectivo humano, revelando qué concepto el modelo asocia con la humanidad en roles activos similares a los robots.

6 Matriz de Similitud de Palabras

Se calcula la similitud de coseno entre pares de seis palabras seleccionadas y se presenta como matriz.

palabras_matriz <- intersect(c("nave", "robot", "espacio", "planeta", "futuro", "ciencia"),
                             vocab_words)

if (length(palabras_matriz) >= 2) {
  emb_m <- predict(model, palabras_matriz, type = "embedding")
  emb_m <- emb_m[complete.cases(emb_m), , drop = FALSE]

  # Similitud coseno: producto punto de vectores normalizados
  normas   <- sqrt(rowSums(emb_m^2))
  emb_norm <- emb_m / normas
  cos_sim  <- emb_norm %*% t(emb_norm)

  round(cos_sim, 3) %>%
    knitr::kable(caption = "Matriz de similitud de coseno entre palabras seleccionadas")
} else {
  cat("No hay suficientes palabras en el vocabulario para construir la matriz.")
}
Matriz de similitud de coseno entre palabras seleccionadas
nave robot espacio planeta futuro ciencia
nave 1.000 0.805 0.806 0.980 0.799 0.670
robot 0.805 1.000 0.869 0.831 0.910 0.817
espacio 0.806 0.869 1.000 0.834 0.929 0.938
planeta 0.980 0.831 0.834 1.000 0.847 0.736
futuro 0.799 0.910 0.929 0.847 1.000 0.914
ciencia 0.670 0.817 0.938 0.736 0.914 1.000

Interpretación: Los valores cercanos a 1 indican alta similitud semántica; cercanos a 0, poca relación. Se espera que “nave” y “planeta” tengan mayor similitud entre sí que con “robot”, dado que co-ocurren en contextos de exploración espacial. Las palabras menos similares entre sí representan campos semánticos distintos dentro del corpus.

7 De Palabras a Similitud de Texto

Se utilizan tres oraciones cortas y se calcula su similitud mediante averaged word embeddings: el vector de cada oración es el promedio de los vectores de sus palabras presentes en el vocabulario.

oraciones <- c(
  s1 = "viaje interestelar salvar humanidad",
  s2 = "mision espacial nave planeta",
  s3 = "robot ciudad futuro maquinas"
)

# Función: vector promedio de una oración
vec_oracion <- function(oracion, model, vocab) {
  tokens <- strsplit(oracion, " ")[[1]]
  tokens <- tokens[tokens %in% vocab]
  if (length(tokens) == 0) return(NULL)
  emb <- predict(model, tokens, type = "embedding")
  emb <- emb[complete.cases(emb), , drop = FALSE]
  if (nrow(emb) == 0) return(NULL)
  colMeans(emb)
}

# Similitud coseno entre dos vectores
cos_vec <- function(a, b) sum(a * b) / (sqrt(sum(a^2)) * sqrt(sum(b^2)))

vecs <- lapply(oraciones, vec_oracion, model = model, vocab = vocab_words)

pares <- combn(names(oraciones), 2, simplify = FALSE)
resultados_texto <- do.call(rbind, lapply(pares, function(p) {
  if (is.null(vecs[[p[1]]]) || is.null(vecs[[p[2]]])) return(NULL)
  sim <- cos_vec(vecs[[p[1]]], vecs[[p[2]]])
  # Usar etiquetas cortas para evitar que kable falle con texto largo en celdas
  data.frame(Par = paste(p[1], "vs", p[2]),
             Oracion_A = p[1], Oracion_B = p[2],
             Similitud = round(sim, 4),
             stringsAsFactors = FALSE)
}))

# Mostrar texto completo de cada oracion como referencia
cat("Referencia de oraciones:\n")
## Referencia de oraciones:
for (nm in names(oraciones)) cat(" ", nm, ":", oraciones[nm], "\n")
##   s1 : viaje interestelar salvar humanidad 
##   s2 : mision espacial nave planeta 
##   s3 : robot ciudad futuro maquinas
# Tabla solo con etiquetas y similitud
knitr::kable(resultados_texto[, c("Oracion_A", "Oracion_B", "Similitud")],
             caption = "Similitud de coseno entre pares (averaged embeddings)",
             row.names = FALSE)
Similitud de coseno entre pares (averaged embeddings)
Oracion_A Oracion_B Similitud
s1 s2 0.8972
s1 s3 0.9351
s2 s3 0.8461
idx_max <- which.max(resultados_texto$Similitud)
idx_min <- which.min(resultados_texto$Similitud)
cat("\nPar mas similar:  ", resultados_texto$Par[idx_max],
    "-> Similitud:", resultados_texto$Similitud[idx_max], "\n")
## 
## Par mas similar:   s1 vs s3 -> Similitud: 0.9351
cat("Par menos similar:", resultados_texto$Par[idx_min],
    "-> Similitud:", resultados_texto$Similitud[idx_min], "\n")
## Par menos similar: s2 vs s3 -> Similitud: 0.8461

Comparación con TF-IDF: Con TF-IDF, dos oraciones sin palabras en común tendrían similitud exactamente 0, independientemente de si sus términos son semánticamente relacionados. Con embeddings, oraciones temáticamente afines (como s1 y s2, ambas sobre viajes espaciales) obtienen similitud positiva aunque no compartan tokens, porque sus palabras tienen vectores cercanos en el espacio semántico.

8 Reflexión Conceptual

Los embeddings de palabras representan un salto cualitativo respecto a las representaciones basadas en frecuencias como BoW y TF-IDF. Mientras que TF-IDF asigna vectores ortogonales a palabras que nunca co-ocurren en el mismo documento —incluso si son sinónimos—, Word2Vec captura regularidades distribucionales que reflejan relaciones semánticas reales: sinonimia, antonimia, relaciones jerárquicas y analogías estructurales. Esta capacidad queda demostrada en los experimentos de vecinos cercanos y analogías de esta actividad.

Sin embargo, Word2Vec tiene una limitación fundamental: genera representaciones estáticas. Cada palabra recibe un único vector, independientemente del contexto en que aparezca. La palabra “banco” tendrá el mismo vector hablando de una entidad financiera o de un mueble de jardín. Esta ambigüedad contextual fue el principal motivador para el desarrollo de modelos contextuales como ELMo y BERT, que asignan vectores distintos a la misma palabra según su contexto de uso.

Los embeddings son preferibles cuando el objetivo requiere capturar significado semántico, manejar sinónimos, o comparar textos que tratan el mismo tema con vocabulario diferente. TF-IDF sigue siendo competitivo cuando la tarea depende del léxico exacto, como la recuperación de documentos por palabras clave específicas o cuando la interpretabilidad del modelo es prioritaria.

9 Requisito de Reproducibilidad

9.0.1 Versiones de las Librerías Utilizadas

  • word2vec: 0.4.1
  • tidyverse: 2.0.0
  • tidytext: 0.4.3
  • knitr: 1.51
  • kableExtra: 1.4.0
  • cluster: 2.1.8.2

Información del Sistema: R version 4.4.2 (2024-10-31 ucrt)