library(igraph)
library(rgexf)
library(tidyverse)
library(visNetwork)Ходасевич
Подготовка данных
Установка библиотек
Подготовка данных
В данной работе используется датасет на основе «Камер-фурьерский журнала» Ходасевича. Мы будем использовать данные за 1932 год, потому что согласно данным из (Орехов Б. В. 2018), там содержится самое большое количество людей.
setwd('.\\months_data')
list_files <- list.files(pattern = '1932_.*\\.gexf', full.names = TRUE)
df <- tibble(from_name = character(), to_name = character(), weight = character())
for (f in list_files) {
d <- read.gexf(f) |>
gexf.to.igraph() |>
as_long_data_frame() |>
select(from_name, to_name, weight)
df <- merge(d, df, all=TRUE) # Объединяем в один датафрейм
df <- df |> # Суммируем повторяющиеся векторы
group_by(from_name, to_name) |>
summarize(weight = sum(weight))
}dfСоздаем граф
graph <- graph_from_data_frame(df)
graphIGRAPH 383877b DNW- 207 1909 --
+ attr: name (v/c), weight (e/n)
+ edges from 383877b (vertex names):
[1] Абрамова ->Зайцев_Б Абрамова ->Зайцева_В
[3] Авксентьев->Алданов Авксентьев->Вишняк
[5] Авксентьев->Вольфсон Авксентьев->Вольфсон_Э
[7] Авксентьев->Демидов Авксентьев->Керенский
[9] Авксентьев->Коварский Авксентьев->Маклаков
[11] Авксентьев->Маргулиес Авксентьев->Маргулиес_Марг
[13] Авксентьев->Пети Авксентьев->Руднев
[15] Аврех ->Азов Аврех ->Благов
+ ... omitted several edges
У нас получился направленный, именованный и взвешенный граф с 207 вершинами и 1909 связями.
Плотность
edge_density(graph)[1] 0.04476807
Компоненты
components(graph)$csize[1] 195 2 5 2 3
В этом графе 4 компоненты, в главной компоненте 195 узлов. Посмотрим, кто не попал в главную компоненту
which(components(graph)$membership !=1) Аитов Горчаков_МК Именитов Кугульский Ник_Алеев
7 52 75 93 125
Татищев жена_Шильтяна Алексинский Именитова Шильтян
161 173 180 198 199
Любимов Шишмарева
204 206
Самое длинное расстояние между узлами (оно же диаметр)
lgc <- largest_component(graph)
farthest_vertices(lgc)$vertices
+ 2/195 vertices, named, from 3887688:
[1] Полонская Полонский
$distance
[1] 22
Интересное наблюдение, так как из-за совпадения фамилий это скорее всего супруги.
Транзитивность
transitivity(graph)[1] 0.4954983
Взвешенная центральность
Рассчитаем взвешенную центральность
wDegree <- strength(graph)
sort(wDegree, decreasing = TRUE)[1:5] Алданов Нина Смоленский Мандельштам Оля
223 207 201 192 171
Визуализация графа
vis_g <- toVisNetworkData(graph)
g_3d <- visNetwork(nodes = vis_g$nodes,
edges = vis_g$edges,
width = "100%",
height = 600)
visOptions(g_3d,
highlightNearest = list(enabled = TRUE, degree = 1, hover = TRUE),
nodesIdSelection = FALSE) |>
visPhysics(maxVelocity = 20, stabilization = TRUE) |>
visInteraction(dragNodes = TRUE)Подграф
Сделаем подграф из узлов, у которых самая большая взыешенная центральность. Мы будем использовать метод к-ядер, так как к-ядро является “популярным определением социальной сплоченности”.
V(graph)$degree <- wDegree
degr_graph <- which(V(graph)$degree >= 100)
subgr <- induced_subgraph(graph, vids=degr_graph)
vis_sg <- toVisNetworkData(subgr)
vis_sub <- visNetwork(nodes = vis_sg$nodes,
edges = vis_sg$edges,
width = "100%",
height = 600)
visOptions(vis_sub,
highlightNearest = list(enabled = TRUE, degree = 1, hover = TRUE),
nodesIdSelection = FALSE) |>
visPhysics(maxVelocity = 20, stabilization = TRUE) |>
visInteraction(dragNodes = TRUE)Модулярность и анализ сообществ
Если все узлы принадлежат к одному классу, то модулярность равна нулю. Если разбиение на классы хорошее, то модулярность должна быть высокая. Сравним два алгоритма, чтобы понять, у какого модулярность больше. ### Алгоритм “случайного блуждания”
modularity(cluster_walktrap(graph))[1] 0.4182526
Главный собственный вектор
modularity(cluster_leading_eigen(graph))[1] 0.3895832
Алгоритм “случайного блуждания” более высокий, значит, лучше использовать его для разбиения на сообщества.
plot(cluster_walktrap(graph), graph)Видно, что результат получается не очень хороший (очень много делений на группы), но это может быть связано с особенностью данных (дневники одного человека и большое количество людей)
Точки сочленения
articulation_points(graph)+ 9/207 vertices, named, from 383877b:
[1] Каплун Крыжановская Костанов Женя Нина
[6] Муратов Оля Вишняк Именитов
Клики
clique_num(graph)[1] 25
Размер наибольшей клики равен 25, выведем ее узлы.
largest_cliques(graph)[[1]]
+ 25/207 vertices, named, from 383877b:
[1] Зайцев_Б Аминадо Шполянская Цетлина Цетлин
[6] Фондаминский Тумаркин Трахтерев Смоленский Руманов
[11] Ремизов Осоргина Нина Милочка Маршак
[16] Макеев Куприн Зайцева_В Жаботинский Гальперин
[21] Вольфсон_Э Вольфсон Вейдле Болотова_Шура Ася