Подключаем библиотеки для работы с данными, NLP и графами

library(tidyverse)
library(udpipe)
library(igraph)
library(ggraph)

Загружаем аннотированный текст Цезаря

caesar <- udpipe_read_conllu(
  "https://github.com/locusclassicus/text_analysis_2024/raw/main/files/bg_latinpipe.conllu"
)

Оставляем только существительные

caesar_subset <- caesar |> 
  filter(upos == "NOUN")

Создаем таблицу со-употреблений лемм в пределах предложения

cooc <- cooccurrence(
  caesar_subset,
  term = "lemma",
  group = c("doc_id", "sentence_id")
) |> 
  as_tibble() |> 
  filter(cooc > 25)  # Сохраняем только частые пары

Преобразуем таблицу в граф и считаем степень вершин

g <- graph_from_data_frame(cooc, directed = FALSE)
V(g)$degree <- degree(g)

Визуализация графа с настройкой стиля и подписи узлов

set.seed(123)
ggraph(g, layout = "fr") +
  geom_edge_arc(aes(width = cooc), color = "grey70", alpha = 0.5, strength = 0.2) +
  geom_node_point(aes(size = degree), shape = 21, fill = "#3A86FF", color = "black", stroke = 0.4) +
  geom_node_text(aes(label = name), repel = TRUE, size = 3.5, color = "black") +
  scale_edge_width(range = c(0.3, 2)) +
  scale_size(range = c(3, 10), guide = "none") +
  theme_graph(base_family = "sans") +
  labs(
    title =  "Записки Цезаря",
    subtitle = "Слова, встречающиеся в одном предложении"
  )