{topicmodels}
Se rige por dos principios
Vamos a utilizar un corpus con cuentos de 57 autores en español creado por Karen Palacios
library(highcharter)
cuentos |>
count(author, sort= T)|>
arrange(n) |> # Para que coord_flip de ggplot se vea igual en highcharter
hchart(
type = "bar", # bar = horizontal; column = vertical
hcaes(x = author, y = n)
) |>
hc_chart(backgroundColor = "transparent") |>
hc_colors("#112446") |>
hc_xAxis(title = list(text = "")) |>
hc_yAxis(title = list(text = "Cantidad")) |>
hc_add_theme(hc_theme_flat()) # Similar a theme_minimal
Nos vamos a quedar solo con los cuentos de Borges
Convertimos a matriz
library(tidytext)
cuentos_anotados_limpios <- cuentos_anotados %>%
filter(upos=="ADJ"| upos=="VERB"| upos=="NOUN") %>%
select( doc_id, lemma ) %>%
filter(!lemma %in% stopwords::stopwords(language = "es"))%>%
count(doc_id, lemma, sort = TRUE) %>% # Armamos una freq por cada documento
cast_dtm(doc_id, lemma, n) # Convertimos a vector
Podemos utilizar la LDA() función del paquete topicmodels, configurando k = 5, para crear un modelo LDA de dos temas.
Podemos usar dplyr slice_max()
para encontrar los 10 términos más comunes en cada tema
library(tidyr)
beta_wide <- cuentos_lda_beta |>
mutate(topic = paste0("topic", topic)) |>
pivot_wider(names_from = topic, values_from = beta)
# Filtrar términos con beta > 0.001 en al menos un tema
beta_wide_filtrado <- beta_wide |>
filter(if_any(starts_with("topic"), ~ .x > 0.001))
cols_topics <- beta_wide_filtrado |>
select(starts_with("topic")) |>
colnames()
# Luego, hacer el mutate con max.col correctamente
beta_topico_max <- beta_wide_filtrado |>
mutate(topico_max = cols_topics[max.col(across(all_of(cols_topics)), ties.method = "first")])
beta_larga <- beta_topico_max |>
pivot_longer(cols = all_of(cols_topics), names_to = "topic", values_to = "beta")
beta_filtrada <- beta_larga |>
filter(topic == topico_max) |>
group_by(topic) |>
slice_max(order_by = beta, n = 20, with_ties = FALSE) |>
ungroup()
ggplot(beta_filtrada, aes(x = reorder(term, beta), y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
facet_wrap(~ topic, scales = "free_y") +
coord_flip() +
theme_minimal()
topicos_nombres <- rbind(
c(topico_max = "topic1" , nombre = "accion"),
c(topico_max = "topic2" , nombre = "suenio"),
c(topico_max = "topic3" , nombre = "onirico_horizonte"),
c(topico_max = "topic4" , nombre = "tragedia"),
c(topico_max = "topic5" , nombre = "existencialismo"),
c(topico_max = "topic6" , nombre = "ficcion_artistico")
) %>% as_tibble()
# Agregar nombres al gráfico
beta_filtrada <- beta_filtrada |>
left_join(topicos_nombres, by = "topico_max")|>
group_by(topic) |>
slice_max(order_by = beta, n = 20, with_ties = FALSE) |>
ungroup()
cuentos_clasificados <- gamma_dominante |>
select(document, topic_final = topic, nombre_topico = nombre, probabilidad = gamma) |>
mutate(document = as.numeric(document)) |>
left_join(borges |> select(id, author, text), by = c("document" = "id"))
head(cuentos_clasificados)
# A tibble: 6 × 6
# Groups: document [6]
document topic_final nombre_topico probabilidad author text
<dbl> <int> <chr> <dbl> <chr> <chr>
1 144 1 Acciones 0.542 Jorge Luis Borges Abel y Caín…
2 145 5 Reflexiones 0.994 Jorge Luis Borges Era muy lin…
3 146 3 Existencia 0.999 Jorge Luis Borges ¿Qué soñará…
4 147 3 Existencia 0.999 Jorge Luis Borges Los años le…
5 148 3 Existencia 0.998 Jorge Luis Borges Cierro los …
6 149 5 Reflexiones 1.00 Jorge Luis Borges El seis de …
Blei, David. 2012. “Probabilistic topic models.” Communications of the ACM 55 (4): 77. https://doi.org/10.1145/2133806.2133826.