library(udpipe)
library(igraph)
library(ggraph)
library(ggplot2)
library(visNetwork)
library(dplyr)Сеть совместной встречаемости в «Записках о Галльской войне» Цезаря
Импорт библиотек и загрузка корпуса.
Загружаем необходимые библиотеки.
Загружаем размеченный корпус. Оставим только существительные.
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(
x = caesar_subset,
term = "lemma",
group = c("doc_id", "sentence_id")
) |>
as_tibble() |>
filter(cooc > 20)
DT::datatable(cooc[1:10,])Построение статической сети
Преобразуем результат в граф.
caesar_g <- graph_from_data_frame(cooc)
deg <- degree(caesar_g)
V(caesar_g)$Узлы <- ifelse(deg >= 6, "Ключевые", "Прочие")
cols <- c(Ключевые = "#C266FF", Прочие = "#aed7a0")
set.seed(2026)
ggraph(caesar_g, layout = "fr") +
geom_edge_link(color = "grey50", edge_width = 1, edge_alpha = 0.7) +
geom_node_label(aes(label = name, fill = Узлы), color = "white", size = 3) +
scale_fill_manual(values = cols) +
theme_graph(base_family = "Arial") +
labs(title = "Сеть соупотреблений существительных",
subtitle = "Ключевые и прочие узлы") На графике видим наиболее центральные слова, связанные с другими множеством ребер.
Интерактивная визуализация
library(visNetwork)
nodes <- data.frame(id = unique(c(cooc$term1, cooc$term2)))
nodes$label <- nodes$id
nodes$group <- ifelse(nodes$id %in% V(caesar_g)$name[deg >= 6], "Ключевые", "Прочие")
edges <- data.frame(from = cooc$term1, to = cooc$term2, value = cooc$cooc)
visNetwork(nodes, edges, width = "100%") %>%
visIgraphLayout(layout = "layout_with_fr") %>%
visGroups(groupname = "Прочие", color = list(background = "#aed7a0", border = "#aed7a0")) %>%
visGroups(groupname = "Ключевые", color = list(background = "#C266FF", border = "#C266FF")) %>%
visLegend() %>%
visNodes(shape = "dot", size = 10, shadow = TRUE,
color = list(highlight = "#FC8D62")) %>%
visEdges(color = list(color = "#A0A0A0", highlight = "#D95F02"),
smooth = FALSE) %>%
visOptions(highlightNearest = list(enabled = TRUE, degree = 1, hover = TRUE),
nodesIdSelection = TRUE) %>%
visLayout(randomSeed = 123)