Применение сетевого подхода к “Камер-фурьерскому журналу” В.Ф. Ходасевича

Автор

Анастасия Орлова

Дата публикации

21.03.2025

Данные представляют собой записи “Камер-фурьерского журнала” (КФЖ) Владислава Фелициановича Ходасевича. КФЖ — это рукописный текст, в котором Ходасевич фиксировал историю встреч с приятелями, знакомыми и друзьями в период эмиграции. Первая запись датирована 30 июня 1922 г. (приезд Ходасевича и Н. Н. Берберовой в Берлин). Обращение к архаичной форме камер-фурьерского журнала, с одной стороны, демонстрирует верность традициям Российской империи, а с другой – создаёт иллюзию оседлости. Ходасевич соблюдает канон «жанра» по основным параметрам: ежедневность записей, выдержанность стиля, разграничение публичного и приватного, внимание к парадной стороне жизни.

В качестве анализируемого периода выбран 1932 год — год расставания Ходасевича со своей первой женой Ниной Берберовой, которая стала появляться в записях Ходасевича только после разрыва супругов.

1 Импорт данных

library(rgexf)
library(igraph)
library(tidyverse)
library(igraph)

В предоставленных данных каждый год “разбит” по месяцам. Импортируем данные за каждый месяц 1932 года в отдельности, а затем объединяем их и извлекаем необходимую информацию о встречах.

gexf_files <- list.files("./months_data", pattern = "1932.*\\.gexf", full.names = TRUE)

gexf_data <- lapply(gexf_files, read.gexf)
all_edges <- data.frame()

for (i in 1:length(gexf_data)) {
  edges_table <- gexf_data[[i]]$edges
  all_edges <- rbind(all_edges, edges_table)
}

all_edges
all_edges <- all_edges |>
  select(-id)

2 Создание объекта графа

На основе подготовленных данных создаем объект графа (igraph). Тип связи в данных ненаправленный, так как Ходасевич фиксирует свои наблюдения о его встречах с различными людьми. Тип связи задаю вручную.

khodasevich_circle <- graph_from_data_frame(
  d = all_edges,  
  directed = FALSE    
)
khodasevich_circle
IGRAPH 85d9c6f UNW- 207 2778 -- 
+ attr: name (v/c), weight (e/n)
+ edges from 85d9c6f (vertex names):
 [1] Именитов     --Шильтян       Именитов     --жена_Шильтяна
 [3] Именитов     --Горчаков_МК   Архангельский--Костанов     
 [5] Нина         --Осоргина      Нина         --Макеев       
 [7] Нина         --Фельзен       Нина         --Бахрах       
 [9] Нина         --Смоленский    Нина         --Браславский  
[11] Нина         --Софроницкая   Нина         --Полонский    
[13] Нина         --Гончарова     Марголин     --Оля          
[15] Зайцева_В    --Абрамова      Зайцева_В    --Зайцев_Б     
+ ... omitted several edges

Таким образом, граф является ненаправленным (undirected), именованным (named), то есть узлы имеют имена, а также взвешенным (weighted), то есть рёбра имеют вес. Граф не имеет других специальных атрибутов, например, временных меток. Количество узлов (вершин): 207. Количество рёбер: 2778.

3 Атрибуты рёбер

Теперь внимательнее посмотрим на атрибуты рёбер.

E(khodasevich_circle)
+ 2778/2778 edges from 85d9c6f (vertex names):
 [1] Именитов     --Шильтян       Именитов     --жена_Шильтяна
 [3] Именитов     --Горчаков_МК   Архангельский--Костанов     
 [5] Нина         --Осоргина      Нина         --Макеев       
 [7] Нина         --Фельзен       Нина         --Бахрах       
 [9] Нина         --Смоленский    Нина         --Браславский  
[11] Нина         --Софроницкая   Нина         --Полонский    
[13] Нина         --Гончарова     Марголин     --Оля          
[15] Зайцева_В    --Абрамова      Зайцева_В    --Зайцев_Б     
[17] Полонский    --Осоргина      Полонский    --Оля          
[19] Полонский    --Алданов       Полонский    --Марианна     
+ ... omitted several edges

Проверяем количество ребер.

ecount(khodasevich_circle)
[1] 2778

Веса ребер хранят информацию о том, как часто упоминаемые личности встречаются с Ходасевичем, т. е. отражают силу связи.

edge_attr(khodasevich_circle, "weight")

Выведем ребра, вес которых больше 1.

E(khodasevich_circle)[weight > 1] 
+ 451/2778 edges from 85d9c6f (vertex names):
 [1] Ал_Минор    --Тумаркин      Тумаркин    --Болотова_Шура
 [3] Марианна    --Оля           Осоргина    --Макеев       
 [5] Левинсонша  --Мандельштам   Алданов     --Вольфсон     
 [7] Вольфсон    --Зензинов      Зайцева_В   --Вольфсон     
 [9] Вольфсон    --Керенский     Вольфсон    --Руднева      
[11] Вольфсон    --Цетлина       Макеев      --Вольфсон     
[13] Вольфсон    --Вольфсон_Э    Вольфсон    --Вишняк       
[15] Вольфсон    --Вишнячка      Вольфсон    --Зайцев_Б     
[17] Вольфсон    --Алданова      Вольфсон    --Цетлин       
[19] Вольфсон    --Бунина        Мережковский--Гиппиус      
+ ... omitted several edges

Другая характеристика сети – это ее плотность. Граф имеет относительно мало связей по сравнению с максимально возможным числом. Такие сети часто встречаются в настоящих данных, например, в социальных сетях, где каждый человек связан только с небольшой частью всех возможных контактов. Вспомним число Данбара, которое означает, что человек не может поддерживать больше 150 постоянных социальных связей.

edge_density(khodasevich_circle)
[1] 0.1302941

4 Атрибуты узлов

еще одна важная характеристика сети – это ее размер. Размер – это количество участников (members), которые называются вершинами (vertices), узлами или акторами. Рассмотрим вершины графа.

V(khodasevich_circle)
+ 207/207 vertices, named, from 85d9c6f:
  [1] Именитов          Архангельский     Нина              Марголин         
  [5] Зайцева_В         Полонский         Ник_Алеев         Нюша             
  [9] Ал_Минор          Вейдле            Фельзен           Шишмарева        
 [13] Бахрах            Тумаркин          Шильтян           Браславский      
 [17] Каплун            Абрамова          Марианна          Гончарова        
 [21] Осоргина          Оля               Терапиано         Алданов          
 [25] Левинсон          Макеев            Левинсонша        жена_Г_Лунца     
 [29] Вольфсон          Мережковский      Цетлина           Кнут             
 [33] Голенищев-Кутузов Шполянская        Керенский         Руднева          
 [37] Городецкая        Азов              Вольфсон_Э        Мандельштам      
+ ... omitted several vertices
vcount(khodasevich_circle)
[1] 207

Определяем степень узлов.

d <- as.numeric(degree(khodasevich_circle))
V(khodasevich_circle)$degree <- d
khodasevich_circle
IGRAPH 85d9c6f UNW- 207 2778 -- 
+ attr: name (v/c), degree (v/n), weight (e/n)
+ edges from 85d9c6f (vertex names):
 [1] Именитов     --Шильтян       Именитов     --жена_Шильтяна
 [3] Именитов     --Горчаков_МК   Архангельский--Костанов     
 [5] Нина         --Осоргина      Нина         --Макеев       
 [7] Нина         --Фельзен       Нина         --Бахрах       
 [9] Нина         --Смоленский    Нина         --Браславский  
[11] Нина         --Софроницкая   Нина         --Полонский    
[13] Нина         --Гончарова     Марголин     --Оля          
[15] Зайцева_В    --Абрамова      Зайцева_В    --Зайцев_Б     
+ ... omitted several edges

Теперь в графе отражается также степень вершин (узлов).

Важность (prominence) участника (актора, вершины, узла) определяется его положением внутри сети. Применительно к ненаправленным сетям говорят о центральности (центральный актор вовлечен в наибольшее количество связей, прямых или косвенных).

Выводим самые “влиятельные” вершины (те, у которых больше всего связей).

degrees <- degree(khodasevich_circle)
sort(degrees, decreasing = T)[1:10]
    Алданов        Нина  Смоленский Мандельштам      Вейдле     Милочка 
        168         164         154         134         131         128 
     Вишняк    Зайцев_Б      Макеев   Зайцева_В 
        125         120         119         117 

Видно, что в 1932 году Нина занимает второе в сети место по центральности. Предположительно, это связано с тем, что Ходасевич искал встреч с бывшей женой (например, посещал те же места, что и она).

5 Визуализация графа

Визуализируем полный граф.

set.seed(210325)  
plot(khodasevich_circle,
     vertex.label = V(khodasevich_circle)$name,
     vertex.size = 5, 
     vertex.label.cex = 0.8,  
     vertex.color = "black", 
     edge.color = "black",
     vertex.label.color = "black",
     edge.width = E(khodasevich_circle)$weight * 0.5, 
     layout = layout_with_kk(khodasevich_circle))

К сожалению, прочитать его в таком виде невозможно. Отираем связи по весу и отбрасываем наименее значимые, что позволит наглядно визуализировать граф.

filtered_edges <- E(khodasevich_circle)[weight > 2]
filtered_graph <- subgraph.edges(khodasevich_circle, filtered_edges)
set.seed(210325)  
plot(filtered_graph,
     vertex.size = 5, 
     vertex.label = V(filtered_graph)$name,  
     vertex.label.cex = 0.8,  
     edge.color = "#A5A684", 
     vertex.color = "#C37A89",
     vertex.label.color = "black",
     vertex.frame.color = "transparent",
     edge.width = E(filtered_graph)$weight * 0.5,  
     layout = layout_with_fr(filtered_graph))

Граф распадается на два крупных кластера (в более мелкий входит Нина) и на один кластер, состоящий всего из двух персон - Клемм и Жуковский.

6 Подграф

Теперь выведем эго-граф для Нины Берберовой, чтобы отразить ее социальную сеть. Мы создаем (под)графы из всех соседей заданных вершин, т. е. таким образом мы находит дурзей и друзей друзей Нины Берберовой.

p <- make_ego_graph(
  khodasevich_circle,
  order = 2,
  nodes = "Нина",
  mode = "all"
)[[1]]

p
IGRAPH 151d1dd UNW- 189 2755 -- 
+ attr: name (v/c), degree (v/n), weight (e/n)
+ edges from 151d1dd (vertex names):
 [1] Нина     --Осоргина      Нина     --Макеев        Нина     --Фельзен      
 [4] Нина     --Бахрах        Нина     --Смоленский    Нина     --Браславский  
 [7] Нина     --Софроницкая   Нина     --Полонский     Нина     --Гончарова    
[10] Марголин --Оля           Зайцева_В--Абрамова      Зайцева_В--Зайцев_Б     
[13] Полонский--Осоргина      Полонский--Оля           Полонский--Алданов      
[16] Полонский--Марианна      Полонский--Полонская     Полонский--Макеев       
[19] Нюша     --Каплун        Ал_Минор --Тумаркин      Ал_Минор --Болотова_Шура
[22] Вейдле   --Терапиано     Вейдле   --Мандельштам   Фельзен  --Браславский  
+ ... omitted several edges

Для визуализации оставляем более значимые свзяи, т. е. отбираем рёбра с весом больше 3.

p_filtered <- subgraph_from_edges(
  p,
  eids = which(E(p)$weight > 3)
)

p_filtered
IGRAPH a6dba24 UNW- 22 53 -- 
+ attr: name (v/c), degree (v/n), weight (e/n)
+ edges from a6dba24 (vertex names):
 [1] Марианна --Оля         Вольфсон --Вольфсон_Э  Зайцева_В--Зайцев_Б   
 [4] Зайцева_В--Алданов     Алданов  --Керенский   Макеев   --Керенский  
 [7] Керенский--Вишняк      Керенский--Вишнячка    Керенский--Алданова   
[10] Алданов  --Зайцев_Б    Марианна --Оля         Макеев   --Алданова   
[13] Алданов  --Алданова    Алданов  --Макеев      Алданов  --Вишняк     
[16] Алданов  --Вишнячка    Вишнячка --Вишняк      Марианна --Оля        
[19] Марианна --Оля         Полонский--Полонская   Зайцева_В--Зайцев_Б   
[22] Марианна --Оля         Нина     --Терапиано   Нина     --Мандельштам
+ ... omitted several edges

7 Визуализация подграфа

Визуализируем отфильтрованные данные.

par(mar = rep(0,4), cex = 0.7)
layout_p <- layout_with_kk(p_filtered)

set.seed(210325)
plot(p_filtered, 
     vertex.size = 6, 
     edge.arrow.size = 0.5, 
     vertex.label.dist = 0.5,
     edge.curved = 0.2,
     edge.color = "#A5A684", 
     vertex.color = "#C37A89",
     vertex.label.cex = 1.2,
     vertex.label.color = "black",
     vertex.label = V(p_filtered)$name,  
     layout = layout_p,
     vertex.frame.color = "transparent")

Теперь граф рассыпался на два условно крпуных кластера и три более мелких. Исходя из свидетельств, Берберова действительно была дружна с Мандельштамом. Примечательно, что во второй кластер входит Макеев - будущий супруг Берберовой (1936 г.). Отдельно отмечу, что если оставить связи со значением больше 5, в сети Нины останется всего один человек — Оля.

8 Анализ сообществ

Используем алгоритм “случайного блуждания” для определения сообществ.

cw <- cluster_walktrap(khodasevich_circle)
membership(cw) |> head()
     Именитов Архангельский          Нина      Марголин     Зайцева_В 
           18            19             7             6             4 
    Полонский 
            6 
par(mar = rep(0, 4))
set.seed(2103)
plot(cw, khodasevich_circle)

Согласно результатам, сообщества скорее распадаются преимущественно на мелкие или средние группы, а также на совсем отдельные, состоящие всего из нескольких человек.

9 Модулярность

Проверить удачность используемого для определения сообществ алгоритма можно при помощи подсчета модулярности.

modularity(khodasevich_circle, membership(cw))
[1] 0.3627279

Пробуем сопаставить полученные результаты с другим алгоритмом обнаржуения сообществ.

test_infomap <- cluster_infomap(khodasevich_circle)
modularity(khodasevich_circle, membership(test_infomap))
[1] 0.07201374

Так как при выделении сообществ в большинстве случаев наша задача – максимизировать модулярность, алгоритм infomap оказывается менее продуктивным для наших данных. Хотя визуально он является более интерпретируемым.

par(mar = rep(0, 4))
set.seed(21.03)
plot(test_infomap, khodasevich_circle)

10 Точки сочленения и клики

Точка сочленения – это узел, при удалении которого увеличивается число компонент связности. Таким образом, они соединяют разные части сети. При их удалении акторы (узлы, вершины) не могут взаимодействовать друг с другом.

articulation_points(khodasevich_circle)
+ 9/207 vertices, named, from 85d9c6f:
[1] Именитов     Каплун       Крыжановская Муратов      Вишняк      
[6] Женя         Оля          Нина         Костанов    

Мы видим, что Нина является точкой сочленения, а значит её удаление приведет к тому, что некоторые акторы (узлы) больше не смогут взаимодействовать друг с другом. В целом точки сочленения, как правило, это люди, которые связывают разные группы (например, общие друзья в разных компаниях).

Клика – один из самых простых типов сплоченных подгрупп; это максимально полный подграф, т.е. подмножество узлов со всеми возможными связями между ними.

clique_num(khodasevich_circle)
[1] 25
cliques(khodasevich_circle, min=25)
[[1]]
+ 25/207 vertices, named, from 85d9c6f:
 [1] Нина          Зайцева_В     Вейдле        Тумаркин      Осоргина     
 [6] Макеев        Вольфсон      Цетлина       Шполянская    Вольфсон_Э   
[11] Зайцев_Б      Цетлин        Милочка       Ася           Аминадо      
[16] Смоленский    Болотова_Шура Трахтерев     Маршак        Гальперин    
[21] Фондаминский  Куприн        Жаботинский   Ремизов       Руманов      
largest_cliques(khodasevich_circle)
[[1]]
+ 25/207 vertices, named, from 85d9c6f:
 [1] Маршак        Нина          Руманов       Ремизов       Жаботинский  
 [6] Куприн        Фондаминский  Гальперин     Трахтерев     Болотова_Шура
[11] Смоленский    Аминадо       Ася           Милочка       Цетлин       
[16] Зайцев_Б      Вольфсон_Э    Шполянская    Цетлина       Вольфсон     
[21] Макеев        Осоргина      Тумаркин      Вейдле        Зайцева_В    

Клика из 25 узлов указывает на тесную группу, где все участники напрямую связаны друг с другом. Такие группы часто играют важную роль в распространении информации или влияния внутри сети.

Результаты проведенного сетевого анализа 1932 года подтверждают результаты исследования, опубликованного в статье “Цифровые подходы к «Камер-фурьерскому журналу» В. Ф. Ходасевича”. Нина Берберова стала появляться в записях Ходасевича только после разрыва. К этому времени она приобрела литературную известность; нет сомнения, что и раньше ее круг знакомств был широк, но до расставания Ходасевич фиксировал ее в журнале лишь изредка (когда она уезжала или возвращалась). На мой взгляд, такой характер записей говорит о слиянии Ходасевича и Берборовой в сознании Ходасевича, т.е. о восприятии жены как части себя. Ходасевич действительно фокусировал свое внимание на жизни Нины Берберовой, кроме у них очевидно был общий круг знакомых (что неудивительно), но удивительно как раз то, что он сохранился. Ходасевич не стал “затирать” ее из КФЖ, как он делал с другими людьми, c которыми у него было некоторое несовпадение (Адамович, например), а наоборот поместил ее в центр событий 1932 года.