Сетевой анализ романа «Война и мир» Л. Н. Толстого

Автор

Авдеева Полина

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

12.03.2026

«Над ним не было ничего уже, кроме неба, — высокого неба, не ясного, но все-таки неизмеримо высокого, с тихо ползущими по нему серыми облаками. “Как тихо, спокойно и торжественно, совсем не так, как я бежал, — подумал князь Андрей, — не так, как мы бежали, кричали и дрались; совсем не так, как с озлобленными и испуганными лицами тащили друг у друга банник француз и артиллерист, — совсем не так ползут облака по этому высокому бесконечному небу. Как же я не видал прежде этого высокого неба? И как я счастлив, что узнал его наконец. Да! все пустое, все обман, кроме этого бесконечного неба. Ничего, ничего нет, кроме его. Но и того даже нет, ничего нет, кроме тишины, успокоения. И слава богу!..”»

Л. Н. Толстой, «Война и мир»

1 Введение

В настоящей работе объектом исследования является «Война и мир» Л. Н. Толстого (1863—1869). Это сложное произведение, объединяющее в себе черты романа-эпопеи, военной повести и романа-воспитания.

Толстой в «Войне и мире» отказывается от идеи сюжета, выстроенного вокруг одного главного героя, так как каждый человек включен в историю и интересен с точки зрения своего восприятия времени.

В записной книжке 1868 года Толстой (Толстой 1952, p. 89) пишет следующее:

«Человек, личность, есть атом. Он необходим, как необходим атом для теории физики, но определение его может довести только до абсурда».

«Герои-атомы» в результате формируют сложную систему, влияющую на движение романа. Вот как это осмысляет литературовед, историк и исследователь творчества Толстого И. И. Бендерский (Бендерский 2021, p. 165):

«…Речь о том, что в многочисленных семьях “Войны и мира” — Болконских, Ростовых, Безуховых, Курагиных — мы видим расстановку тех сил, которые и движут историю. Персонаж романа, даже самый незначительный, и есть определенным образом заряженный атом. Это художественное переложение идеи Толстого важно и для его опыта писателя-историка: он дает голос каждому своему персонажу, испытывая на прочность его мировоззрение самой жизнью».

Такая структура произведения, состоящая из множества взаимодействий персонажей, делает роман подходящим объектом для анализа с использованием методов сетевого анализа.

Рисунки Л. Н. Толстого в Записной книжке №1. 1859 г.

2 Цель работы

Именно «герои-атомы» и их взаимодействия становятся основной областью анализа в данном исследовании. При этом в настоящей работе для анализа будут применяться не традиционные литературоведческие или исторические методы, а цифровые.

Данный подход позволяет анализировать аспекты текста, которые в произведениях подобного масштаба трудно исследовать вручную:

  • Какие персонажи занимают центральное положение в романе (в нашем случае — в сети взаимодействий);
  • Какие герои выступают связующими звеньями между остальными;
  • Какие группы персонажей формируют те или иные сообщества.

Таким образом, цель работы — построить и проанализировать сеть взаимодействий персонажей, используя методы анализа графов и цифровые инструменты.

Для достижения данной цели необходимо выполнить ряд задач:

  1. Извлечь текст произведения и выделить из него данные о персонажах и их взаимодействиях;
  2. Построить граф взаимодействий персонажей на основе полученных данных, где персонажи представлены узлами, а взаимоотношения между ними — через ребра;
  3. Определить вес связей;
  4. Рассчитать показатели важности персонажей;
  5. Выявить сообщества персонажей;
  6. Определить ключевые структурные элементы сети.

3 Данные

В качестве материала исследования используется датасет «Персонажи “Войны и мира” Л. Н. Толстого: вхождения в тексте, прямая речь и семантические роли», размеченный в формате XML Д. А. Скоринкиным (2022), который содержит информацию о персонажах и их взаимодействиях.

Для анализа данных и построения графов будут использоваться библиотеки igraph, ggraph, visNetwork.

4 Основная работа

4.1 Установка необходимых ресурсов

Перед началом работы необходимо установить нужные пакеты:

library(xml2)
library(tidyverse)
library(igraph)
library(ggraph)
library(ggimage)
library(visNetwork)
library(networkD3)
library(paletteer)

4.2 Сбор данных

После загрузки необходимых библиотек можно приступить к работе с тектом.

Далее необходимо загрузить необходимый датасет по роману из «Репозитория открытых данных по русской литературе и фольклору».

Поскольку данные представлены в формате XML-файла, важно предварительно ознакомитьмся с их структурой, чтобы определить, какие элементы необходимо извлекать.

На изображении ниже представлен скриншот, иллюстрирующий то, как структурно описаны герои романа с помощью тега <person xml:id ="...".

Скриншот из программы Visual Studio Code №1: пример XML-разметки персонажей романа с уникальными идентификаторами

На данном этапе персонажам присваиваются уникальные идентификаторы, которые позволяют избежать путаницы между ними.

Так как взаимодействия персонажей выражаются через диалоги, можно отметить, что каждый идентификатор персонажа становится спикером в конкретном отрывке текста. Для иллюстрации предоставлен скриншот №2:

Скриншот из программы Visual Studio Code № 2: пример диалога с атрибутами и , иллюстрирующий установление взаимодействий.

Здесь видно, что участникам диалога присваивается тег участника связи: <said corresp="..." ...> и спикера <... who="...">. Именно атрибуты используются для построения ориентированного графа: SourceTarget.

В книге «Введение в TEI Lite» Лу Бернарда и С. М. Шперберг-Мак-Куина (Лу и Шперберг-Мак-Куин 1995) данные атрибуты описываются следующим образом:

«Атрибут corresp (соответствие) обеспечивает простой способ представления некоторых форм соответствия между двумя элементами в тексте».

Вот что известно о тэге <sp> (в наше случае — <said>):

«Содержит прямую речь персонажа в тексте пьесы (сценария) или отрывок, представляющий таковую в тексте прозаического или стихотвореного произведения. Включает следующие атрибуты: who указывает (с помощью идентификатора), кто произносит данный текст».

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

xml_file <- "War_and_Peace.xml" 
doc <- read_xml(xml_file) # Читаю файл

# Определяю пространство имен
ns <- xml_ns(doc)
ns
d1 <-> http://www.tei-c.org/ns/1.0
# Переименовываю пространство имен
ns <- xml_ns_rename(xml_ns(doc), d1 = "tei")
ns
tei <-> http://www.tei-c.org/ns/1.0

Теперь извлечем необходимые атрибуты из XML-файла с помощью функции, так как это требование прописано в условии задания:

# Хочется проанализировать первый и четвертый том романа, так что попробую извлечь еще и тома
speakers_by_volume <- function(xml_file) {
  doc <- read_xml(xml_file)
  ns <- xml_ns(doc)
  ns <- xml_ns_rename(xml_ns(doc), d1 = "tei")
  # Нахожу все тома внутри TEI. Они имеют структуру типа: <div n="1" type="volume" xml:id="Volume1">
  volumes <- xml_find_all(doc, ".//tei:text//tei:div[@type='volume']", ns)
  map_dfr(volumes, function(volume) { # Теперь перехожу к поиску взаимодействий. 
    vol_name <- xml_attr(volume, "n") 
    said_attributes <- xml_find_all(volume, ".//tei:said", ns)
    # Тиббл для удобства дальнейшей работы
    map_dfr(said_attributes, ~ tibble(
      Volume = vol_name,
      Source = xml_attr(.x, "who"),
      Target = xml_attr(.x, "corresp"), # Указывает на связь
    ))
  })
}


# Было решено почистить данные, чтобы не попадались склейки
clean_names <- function(x) {
  x <- gsub("[^[:alnum:]_]", "_", x) 
  x <- gsub("_+", "_", x)              
  x <- gsub("^_|_$", "", x)            
  x
}


# Финальная версия
war_and_peace_data <- speakers_by_volume("War_and_Peace.xml") |> 
  na.omit() |> # Убираю NA, чтобы они не ломали структуру
  mutate(
    Source = clean_names(Source),           
    Target = clean_names(Target)) |> 
  separate_rows(Target, sep = ";") |>           
  mutate(Target = trimws(Target)) |>            
  filter(Target != "") |>                        
  count(Volume, Source, Target, name = "Weight", sort = T) # Подсчет веса ребер

Выводим таблицу, чтобы убедиться, что данные собраны корректно:

DT::datatable(war_and_peace_data[1:50,], options = list(), style = "auto")

Итак, мы получили таблицу, содержащую следующие столбцы:

  • Volume — номер тома романа;
  • Source — ID узла, от которого исходит ребро, то есть тот, кто говорит;
  • Target — ID узла, к которому ведет ребро, то есть тот, кто получает реплику;
  • Weight — вес связи с учетом тома.

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

На данном этапе создается граф по всему роману без разделения на главы:

war_and_peace_igraph <- war_and_peace_data |> 
              select(-Volume) |> 
              graph_from_data_frame(directed = T)

war_and_peace_igraph
IGRAPH aa31d2e DN-- 435 1265 -- 
+ attr: name (v/c), Weight (e/n)
+ edges from aa31d2e (vertex names):
 [1] NatashaRostova  ->Nikolai_Rostov          
 [2] Nikolai_Rostov  ->NatashaRostova          
 [3] Telyanin        ->Nikolai_Rostov          
 [4] NatashaRostova  ->Countess_Natalya_Rostova
 [5] NatashaRostova  ->Sonya_Rostova           
 [6] AndreyBolkonsky ->Pierre_Bezukhov         
 [7] Boris_Drubetskoy->Nikolai_Rostov          
 [8] Pierre_Bezukhov ->AndreyBolkonsky         
+ ... omitted several edges

Анализ полученного графа показывает, что:

  • Граф является направленным (D);
  • Узлы графа имеют имена (N);
  • Всего в графе 435 вершин и 1265 ребер.

Таким образом, размре сети (= количеству вершин) составляет 435.

Дополнительно рассчитываются следующие характеристики графа:

  • Плотность сети (density);
  • Компоненты сети (components);
  • Диаметр сети (diameter);
  • Коэффициент кластеризации, или транзитивность (transitivity).

4.3.1 Плотность графа

Плотность графа — это доля имеющихся связей по отношению к максимально возможному количеству связей. Таким образом, плотность является отношением, которое может колебаться от 0 до 1. Чем ближе плотность к 1, тем выше взаимосвязанность сети (Дуглас 2017, p.25).

Плотность графа по «Войне и миру» составляет:

stringr::str_glue("Плотность графа: {edge_density(war_and_peace_igraph)}")
Плотность графа: 0.00670056676730759

Итак, показатель оказался относительно низким: в разреженных сетях плотность невелика даже при наличии интенсивных связей между ключевыми персонажами.

4.3.2 Компоненты сети

Компонента графа — это одна из базовых структрных единиц сети, представляющая собой множество узлов, в котором любые два узла связаны друг с другом прямо или косвенно (Дуглас 2017, p.26).

Для данного графа определено число связанных компонент:

stringr::str_glue("Количество компонент: {components(war_and_peace_igraph)$no}")
Количество компонент: 11

Размеры компонент (количество вершин в каждой) представлены ниже:

components(war_and_peace_igraph)$csize
 [1] 413   2   2   2   2   2   2   2   2   2   4

Построенный граф состоит из одиннадцати компонент. Основная компонента включает в себя 413 вершин, остальные девять компонент, кроме последней, являются диодами — каждая состоит из двух связанных между собой вершин. Последняя компонента включает в себя четыре вершины.

Также определены вершины, не входящие в главную компоненту:

which(components(war_and_peace_igraph)$membership !=1)
                    Бицкий                   ефрейтор 
                       136                        189 
            молодой_солдат               худой_солдат 
                       191                        207 
          Данило_Терентьич                       Ефим 
                       256                        257 
                     Игнат                      Мишка 
                       258                        259 
                    задний                      малый 
                       267                        270 
                  форейтор            денщик_Ермолова 
                       283                        297 
            казачий_офицер            штабный_товарищ 
                       299                        308 
AndreyBolkonsky_Сперанский                      Зикин 
                       324                        366 
                  дяденька               артиллеристы 
                       368                        372 
                   мальчик             передний_мужик 
                       414                        419 
               целовальник     кавалергардский_офицер 
                       421                        432 

Вершины, не входящие в главную компоненту, не относятся к числу ключевых персонажей.

4.3.3 Диаметр сети

Диаметр графа определяется как наибольшая длина (количество ребер) среди всех кратчайших путей между двумя узлами сети. Этот показатель отражает компактность структуры: чем меньше диаметр, тем быстрее информация может распространяться между самими удаленными узлами (Дуглас 2017, p.26).

Для анализа взят наибольший связаный компонент исходного графа:

lgc <- largest_component(war_and_peace_igraph)

Диаметр этой компоненты составил:

stringr::str_glue("Максимальное геодезическое расстояние между двумя вершинами: {diameter(lgc, directed = T)
}")
Максимальное геодезическое расстояние между двумя вершинами: 7

Диаметр равен 7: это самый длинный по количеству шагов путь от одной вершины к другой.

Определим, какие именно вершины образуют этот путь:

get_diameter(lgc)
+ 8/413 vertices, named, from cd4318d:
[1] берейтор                                         
[2] Тит                                              
[3] шутник                                           
[4] Pierre_Bezukhov                                  
[5] NatashaRostova                                   
[6] Vasily_Vasska_Denisov                            
[7] Tikhon_Shtcherbatov                              
[8] Vasily_Vasska_Denisov_esaul_Lovaysky_Petya_Rostov

То есть путь от вершины берейтора и заканчивается вершиной Денисова, эсаула Ловайского и Пети Ростова (в исходных файлах эти три персонажа объединены в одну дважды: <...corresp="Vasily__Vasska__Denisov;esaul Lovaysky;Petya_Rostov"..>) составляет 7 шагов или 8 узлов.

Пару вершин, находящихся на максимальном расстоянии друг от друга, также можно получить с помощью фукнции farthest_verticles():

farthest_vertices(lgc)
$vertices
+ 2/413 vertices, named, from cd4318d:
[1] берейтор                                         
[2] Vasily_Vasska_Denisov_esaul_Lovaysky_Petya_Rostov

$distance
[1] 7

Полученная пара потверждает, что диаметр соединяет берейтора с указанной составной вершиной.

Столь большое расстояние (7 шагов) может объясняться следующим образом: объединение трех разных персонажей в один узел искажает реальную структуру связей, создавая «гибридную» вершину.

4.3.4 Коэффицент кластеризации

В работе Дугласа Люка (Дуглас 2017, p.27) коэффицент кластеризации описывается следующим образом:

«Одной из фундаментальных характеристик социальных сетей (по сравнению со случайными сетями) является наличие кластеризации (clustering), или тенденции к созданию закрытых треугольников (closed triangles). Процесс замыкания происходит в социальной сети, когда два человека, у которых есть общий друг, сами становятся друзьями. В социальной сети это можно измерить путем исследования ее транзитивности (transitivity). Транзитивность определяется как доля закрытых треугольников (триад, где наблюдаются все три связи) по отношению к общему количеству открытых и закрытых треугольников (триад, где наблюдаются либо две, либо все три связи). Таким образом, как и плотность, транзитивность является отношением, которое может колебаться от 0 до 1».

stringr::str_glue("Транзитивность сети: {transitivity(war_and_peace_igraph)}")
Транзитивность сети: 0.101020607163752

Результат: 0.1010206. Это означает, что лишь около 10% потенциальных треугольников в сети являются замкнутыми, что свидетельствует о сравнительно низком уровне кластеризации данной сети.

4.4 Осмысление атрибутов ребер

Рассмотрим атрибуты ребер в графе, построенном на основе романа «Войны и мира»:

edge_attr(war_and_peace_igraph)$Weight[1:30] # Так как результат очень длинный, выведу только первые 30 результатов
 [1] 122  90  89  73  70  68  52  51  43  40  39  37  36  34  33  31  30  30  29
[20]  28  28  28  26  26  25  25  23  23  23  22

Приведенный фрагмент демонстрирует, что интенсивность взаимодействий между персонажами (вес ребра) распределена неравномерно. Данный факт кажется закономерным, так как сюжетная близость персонажей варьируется: одни герои взаимодействуют часто и образуют более устойчивые связи, другие контактируют редко.

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

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

Для идентификации вершин используется атрибут $name, содержащий имена персонажей. Извлечение данного атрибута позволяет сопоставить структурные характеристики сети с конкретными персонажами «Войны и мира».

Ниже приведены первые 25 значений указанного атрибута:

names <- vertex_attr(war_and_peace_igraph)$name
names[1:25]
 [1] "NatashaRostova"                       
 [2] "Nikolai_Rostov"                       
 [3] "Telyanin"                             
 [4] "AndreyBolkonsky"                      
 [5] "Boris_Drubetskoy"                     
 [6] "Pierre_Bezukhov"                      
 [7] "Sonya_Rostova"                        
 [8] "Platon_Karataev"                      
 [9] "Bilibin"                              
[10] "Countess_Natalya_Rostova"             
[11] "Captain_Ramballe"                     
[12] "Fedor_Ivanovich_Dolokhov"             
[13] "Napoleon_Bonaparte"                   
[14] "Prince_Nikolay_Bolkonsky"             
[15] "Vasily_Vasska_Denisov"                
[16] "Joseph_Alexeevich_Bazdeev"            
[17] "Timohin"                              
[18] "Princess_Mariya_Bolkonskaya"          
[19] "Princess_Anna_Mikhaylovna_Drubetskaya"
[20] "Catiche_eldest_princess"              
[21] "Vasili_Kuragin"                       
[22] "Anatole_Kuragin"                      
[23] "Смольянинов_ритор"                    
[24] "Anna_Pavlovna_Scherer"                
[25] "доктор"                               

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

4.5.1 Центральность по степени

Для анализа структурной значимости персонажей в сети романа «Война и мир» вычислим показатели центральности по степени (degree centrality). Эта мера отражает количество непосредственных связей вершины с другими вершинами графа:

degrees <- degree(war_and_peace_igraph)

Результат выполнения:

sort(degrees, decreasing = T) |> 
  head()
            Pierre_Bezukhov              Nikolai_Rostov 
                        182                         143 
            AndreyBolkonsky              NatashaRostova 
                        132                         116 
Princess_Mariya_Bolkonskaya           Count_Ilya_Rostov 
                         76                          64 

Представленный результат демонстрирует: чем выше degrees, тем чаще персонаж встречается в произведении и взаимодействует с другими. Наибольшее количество связей в сети принадлежит Пьеру Безухову, Николаю Ростову, Андрею Болконскому, Наташе Ростовой и княжне Марье Болконской. Данные персонажи являются главными героями романа.

Поскольку ребра графа имеют веса, отражающие интенсивность взаимодействий между персонажами, можно рассмотреть также взвешенную центральность по степени (weighted degree centrality). Данная мера учитывает суммарный вес инцидентных вершине ребер:

wDegree <- strength(
  war_and_peace_igraph,
  weights = E(war_and_peace_igraph)$Weight
)

Результат выполнения:

sort(wDegree, decreasing = T) |> 
       head()
            Pierre_Bezukhov              Nikolai_Rostov 
                       1055                        1006 
             NatashaRostova             AndreyBolkonsky 
                       1003                         854 
Princess_Mariya_Bolkonskaya    Countess_Natalya_Rostova 
                        438                         302 

Значения взвешенной центральности существенно превышают показатели обычной степени, что обусловлено учетом интенсивности связей, а не только их наличия. Примечательно, что здесь Наташа Ростова находится на третьем, а не на четвертом месте, как это было при подсчете degree, что может свидетельствовать о более высокой совокупной интенсивности взаимодействий героини с другими персонажами по сравнению с Андреем Болконским, несмотря на меньшее количество связей.

4.5.2 Центральность по близости

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

closeness_centrality <- closeness(war_and_peace_igraph, 
                     mode = "all",
                     normalized = T)

Результат выполнения:

closeness_centrality |> 
  sort() |> 
  tail()
              дяденька           артиллеристы                мальчик 
                     1                      1                      1 
        передний_мужик            целовальник кавалергардский_офицер 
                     1                      1                      1 

Полученные значения оказались равны единице для всех вершин, а список персонажей в хвосте сортировки не соответствует ожидаемому распределению близости. Таким образом, результат в данном случае не дает важную нам информацию.

4.5.3 Центральность по посредничеству

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

betweenness_centrality <- betweenness(war_and_peace_igraph, 
                               directed = F,
                               normalized = T)

Результат выполнения:

betweenness_centrality |> 
  sort(decreasing = T) |> 
  head()
             Pierre_Bezukhov              AndreyBolkonsky 
                  0.32826505                   0.25119764 
              Nikolai_Rostov               NatashaRostova 
                  0.21990705                   0.12545702 
Mikhail_Ilarionovich_Kutuzov        Vasily_Vasska_Denisov 
                  0.10095430                   0.07640731 

Как и в случае с центральностью по степени, Пьер Безухов демонстрирует наивысший показатель посредничества. Это свидетельствует о том, что через данного персонажа проходят многочисленные пути между другими героями романа.


На данном этапе можно также рассчитать точки сочленения (cutpoint) — узлы, соединяющие различные части сети. Удаление данных точек приводит к нарушению связанности графа иа увеличению числа компонент. Анализ точек сочленения позволяет идентифицировать критически важных персонажей, обеспечивающих целостность социальной сети романа.

Для корректного вычисления точек сочленения граф должен быть неориентированным. Приведем исходный граф к такому виду:

# Убираю ориентированность графа
ug <- as.undirected(war_and_peace_igraph, mode = "each") 
Warning: `as.undirected()` was deprecated in igraph 2.1.0.
ℹ Please use `as_undirected()` instead.

Проведем анализ на наибольшей компоненте графа:

lgc_undirected <- as.undirected(lgc, mode = "each")
aps <- articulation_points(lgc_undirected)

V(lgc_undirected)$name[aps]
 [1] "Wolzogen"                                    
 [2] "Prince_Kozlovsky"                            
 [3] "Ferapontov"                                  
 [4] "Yakov_Alpatych"                              
 [5] "Ilagin"                                      
 [6] "Uncle"                                       
 [7] "HeleneKuragin"                               
 [8] "viscount"                                    
 [9] "l_homme_à_l_esprit_profond"                  
[10] "Princess_Elisabeta_Lisa_Karlovna_Bolkonskaya"
[11] "Aline_Kuragina"                              
[12] "Anna_Pavlovna_Scherer"                       
[13] "Bilibin"                                     
[14] "доктор"                                      
[15] "камердинер"                                  
[16] "Staff_Captain_Tushin"                        
[17] "старый_солдат"                               
[18] "фельдфебель"                                 
[19] "один_солдат"                                 
[20] "плясун"                                      
[21] "казак"                                       
[22] "солдат"                                      
[23] "Тит"                                         
[24] "шутник"                                      
[25] "Макеев"                                      
[26] "regimental_commander"                        
[27] "Count_Vasily_Orlov_Denisov"                  
[28] "унтер_офицер"                                
[29] "француз"                                     
[30] "солдаты"                                     
[31] "офицер"                                      
[32] "Julie_Karagina"                              
[33] "Zherkov"                                     
[34] "Богданыч"                                    
[35] "Lieutenant_Alphonse_Karlovich_Berg"          
[36] "Vera_Rostova"                                
[37] "Petya_Rostov"                                
[38] "Tikhon_Shtcherbatov"                         
[39] "гусар"                                       
[40] "Marya_Lvovna_Karagina"                       
[41] "Chekmar"                                     
[42] "Count_Ilya_Rostov"                           
[43] "Prince_Nesvitsky"                            
[44] "генерал"                                     
[45] "Miloradovich"                                
[46] "Tsar_Alexander_I_of_Russia"                  
[47] "Balashev"                                    
[48] "Napoleon_Bonaparte"                          
[49] "Count_Rostopchin"                            
[50] "полковник"                                   
[51] "адъютант"                                    
[52] "Capt_von_Toll"                               
[53] "Weyrother"                                   
[54] "Mikhail_Ilarionovich_Kutuzov"                
[55] "Timohin"                                     
[56] "Балага"                                      
[57] "Fedor_Ivanovich_Dolokhov"                    
[58] "Anatole_Kuragin"                             
[59] "Vasili_Kuragin"                              
[60] "Prince_Nikolay_Bolkonsky"                    
[61] "Princess_Mariya_Bolkonskaya"                 
[62] "девушка"                                     
[63] "Диммлер"                                     
[64] "Countess_Natalya_Rostova"                    
[65] "Sonya_Rostova"                               
[66] "Pierre_Bezukhov"                             
[67] "женщина"                                     
[68] "Boris_Drubetskoy"                            
[69] "AndreyBolkonsky"                             
[70] "Pfuel"                                       
[71] "Kirsten"                                     
[72] "Vasily_Vasska_Denisov"                       
[73] "Nikolai_Rostov"                              
[74] "NatashaRostova"                              

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

Таким образом, анализ центральности по посредничеству и точек сочленения позволяет выявить не только явно центральных персонажей (Пьер Безухов, Андрей Болконский, Наташа Ростова), но и тех, кто выполняет важные связующие функции в структуре социальных отношений романа.

4.5.4 Центральность по собственному вектору

Дополнительно расcчитаем степень влиятельности (eigenvector centrality), оценивающую важность узла с учетом значимсоти его соседей. В контексте социальной сети персонажей данная мера позволяет выявить не просто активно взаимодействующих с другими героев, а тех, кто связан с другими влиятельными узлами, усиливая свою позицию за счет «престижа» окружения.

eigen <- eigen_centrality(war_and_peace_igraph)$vector

Результат выполнения:

eigen |> 
  sort(decreasing = T) |> 
  head()
            Pierre_Bezukhov              NatashaRostova 
                  1.0000000                   0.9306427 
            AndreyBolkonsky Princess_Mariya_Bolkonskaya 
                  0.7858427                   0.6864069 
             Nikolai_Rostov    Countess_Natalya_Rostova 
                  0.6422440                   0.5041753 

Вновь Пьер Безухов занимает лидирующую позицию, демонстрируя максимальное нормированное значение (1.0000000). Это подтверждает его центральную роль в социальной структуре романа.

Также важен высокий показатель Наташи Ростовой (0.9306427), что свидетельствует о том, что ее окружение включает особенно значимых фигур, что повышает ее собственный статус в сети. Далее по показателю идет Андрей Болконский (0.7858427), который также взаимодействует с престижными персонажами.

4.5.5 Промежуточные выводы

Применение различных метрик центральности к графу персонажей романа «Война и мир» позволяет выделить наиболее значимых действующих лиц. Ключевыми фигурами, неизменно попадающими в число лидеров по всем метрикам, являются:

  • Пьер Безухов (Pierre_Bezukhov);
  • Наташа Ростова (NatashaRostova);
  • Андрей Болконский (AndreyBolkonsky);
  • Княжна Марья Болконская (Princess_Mariya_Bolkonskaya);
  • Николай Ростов (Nikolai_Rostov).

При этом Пьер Безухов неизменно занимает наивысшие позиции во всех расчетах, что позволяет идентифицировать его как наиболее центрального персонажа романа с точки зрения сетевого анализа.

4.6 Граф

Для наглядного представления социальных позиций персонажей построен интерактивный граф с помощью пакета visNetwork. Он основан на метрике центральности. Размер узлов пропорционален собственной центральности (eigenvector centrality), что позволяет выделить наиболее влиятельных персонажей. Благодаря цветовой дифференциации (лиственно-зеленый для топ-5 персонажей и песочно-желтый для остальных) облегчается идентификация ключевых узлов.

eigen_wap <- eigen_centrality(war_and_peace_igraph)$vector  # Вновь обращаюсь к собственной центральности 
size <- 10 + 40 * (eigen_wap - min(eigen_wap)) / (max(eigen_wap) - min(eigen_wap)) # Нормирование

is_top5 <- rank(-eigen_wap) <= 5

# Таблица узлов
nodes <- data.frame(
  id = V(war_and_peace_igraph)$name,
  size = size,
  label = V(war_and_peace_igraph)$name,
  color = ifelse(is_top5, "#276235", "#D2B773"),
  group = ifelse(is_top5, "Значимые персонажи", "Другие")
)


# Связи между узлами
edges <- as_data_frame(war_and_peace_igraph)[, 1:2]
colnames(edges) <- c("from", "to")

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

# Трансформация igraph в объект visNetwork
war_and_peace_3d <- visNetwork(nodes, edges, 
                             width = "100%", 
                             height = 600)

# Настройка графика
visOptions(war_and_peace_3d, 
           highlightNearest = list(enabled = T, degree = 1, hover = T),
           nodesIdSelection = F)  |> 
  visNodes(font = list(color = "black", size = 14)) |> 
  visGroups(groupname = "Значимые персонажи", color = "#276235") |>
  visGroups(groupname = "Другие", color = "#D2B773")  |>  
  visLegend(width = 0.2, position = "right", main = "Группы") |> #  Добавляю легенду
  visPhysics(maxVelocity = 20, stabilization = F)  |>  
  visInteraction(dragNodes = T) |> # Добавляю возможность интерактива
  visInteraction(hideEdgesOnDrag = T) |> 
  visLayout(randomSeed = 123) 
# Попытка добавить визуализации физики привела к тому, что граф стал слишком переполненный и тяжелый :(

4.7 Подграф

На данном этапе можно построить подграф.

Для выявления наиболее плотно связанных подгрупп персонажей применим метод k-ядер (k-cores). Согласно определению, предложенному Дугласом Люком (Дуглас 2017, p.120):

«k-ядро — это максимальный подграф, в котором каждая вершина связана минимум с k другими вершинами этого же подграфа. k-ядра имеют массу преимуществ: они вложены (каждый участник 4-ядра является также участником 3-ядра и т.д.), они не перекрываются, и их легко определить».

Вычислим значения k-ядер для всех вершин графа с помощью функции coreness:

cores_war_and_peace <- coreness(war_and_peace_igraph) # Определение k-ядерной структуры

Результат выполнения:

sort(cores_war_and_peace, decreasing = T) |> 
  head()
             NatashaRostova             AndreyBolkonsky 
                         24                          24 
            Pierre_Bezukhov Princess_Mariya_Bolkonskaya 
                         24                          24 
             Nikolai_Rostov               Sonya_Rostova 
                         22                          22 

Максимальное значение ядра имеют Наташа Ростова (24), Андрей Болконский (24), Пьер Безухов (24), а также княжна Марья Болконская (24).

Для наглядной интерпретации k-ядерной структуры добавим полученные значения в граф в качестве атрибута вершин, а также построим визуализацию, ограничившись подграфом из 25 наиболее значимых персонажей по взвешенной степени (strengh). Такой подход позволяет избежать перегруженности визуализации и сфокусироваться на центральных узлах.

V(war_and_peace_igraph)$core <- cores_war_and_peace

# Убедимся, что добавился новый атрибут
names(vertex_attr(war_and_peace_igraph))
[1] "name" "core"

Непосредственно визуализация:

V(war_and_peace_igraph)$wDegree <- strength(
  war_and_peace_igraph,
  weights = E(war_and_peace_igraph)$Weight
) # Взвешенные степени

top_nodes <- V(war_and_peace_igraph)$name[
  order(V(war_and_peace_igraph)$wDegree, decreasing = T)[1:25]
]  # Нахожу топ-15 персонажей по весу связей

new_degrees <- induced_subgraph(war_and_peace_igraph, vids = top_nodes)  # Подграф

V(war_and_peace_igraph)$core <- cores_war_and_peace # Вычисляю k-core каждой вершины в подграфе. Необходимый пункт для подстроения подобного подграфа



set.seed(201)
ggraph(new_degrees, layout = "stress") + 
  geom_edge_link(aes(width = Weight), # Ширина ребер зависит от показателя столбца Weight
                 color = "grey65",
                 alpha = 0.2) +
  scale_edge_width(range = c(0.2, 2)) + # Делаю ребра аккуратнее, так как до этого они выглядели... внушительно
  geom_node_point(aes(color = as.factor(core), # Цвет узла зависит от k-ядра
                      size = wDegree)) +
  geom_node_text(
    aes(label = name,
        filter = name %in% top_nodes), # Только топ-25 персонажей, чтобы не перегружать подграф
    repel = T,
    color = "#1D1F2A", 
    size = 2
  ) +
  scale_color_viridis_d(option = "mako", name = "k-ядра") + # Устанавливаю палитру, в которой достаточно цветов
  scale_size(range = c(2,10)) +
  theme_void() +
  theme(legend.position = "right",
        legend.direction = "horizontal",
        legend.text = element_text(size = 7),
        legend.title = element_text(size = 9),
        legend.key.size = unit(0.6, "cm"),
        legend.spacing.y = unit(0.2, "cm")
  )

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

В центре подграфа располагаются Пьер Безухов, Наташа Ростова, Андрей Болконский, а также княжна Марья Болконская. Чуть более низкое значение ядра (22) у Николая Ростова объясняется, вероятно, его несколько обособленными сюжетными линиями (военные эпизоды), однако в целом все главные герои входят в ядро с высокими значениями k, что подтверждает их принадлежность к плотно связанной группе основных действующих лиц романа.

Таким образом, анализ k-ядерной структуры дополняет картину, полученную с помощью мер центральности, и позволяет выделить наиболее сплочённое ядро персонажей, обеспечивающих связность всей социальной сети.

4.8 Анализ сообществ, модулярность

Так как мы имеем направленную взвешенную сеть, для выделения сообществ целесообразно применить алгоритмы, поддерживающие данные характеристики:

  • Edge-betweenness (Посредничество ребер);
  • InfoMAP

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

Перед применением методов кластеризации следует уточнить понятие модулярности. Д. Люк характеризует её следующим образом (Дуглас 2017, p.125):

«Модулярность характеризует структуру сети, в частности степень кластеризации узлов, когда внутри кластера наблюдается много узлов (высокая плотность), а между кластерами мало узлов (низкая плотность) (Newman 2006). <…> Показатель модулярности определяется как разница между долей связей внутри группы и ожидаемой долей связей, если бы связи были размещены случайно. Показатель модулярности может принимать значения в диапазоне от -1/2 до +1. Чем выше показатель, тем больше уровень кластеризации сети в соответствии с данной группировкой узлов».


Так как до этого был учтен показатель Volume, на данном этапе можно разделить весь роман на два тома, первый и четвертый, чтобы провести сравнительный анализ сообществ.

data_vol1 <- war_and_peace_data |> 
  filter(Volume == "1") |> 
  select(Source, Target, Weight)

# Фильтруем данные для четвёртого тома
data_vol4 <- war_and_peace_data |> 
  filter(Volume == "4") |> 
  select(Source, Target, Weight)

# Создаём графы
g1 <- graph_from_data_frame(data_vol1, directed = T)
g4 <- graph_from_data_frame(data_vol4, directed = T)

Применим алгоритм InfoMap к графу первого тома. Для повышения наглядности визуализации ограничим анализ 25 наиболее значимыми персонажами по взвешенной степени (strength).

wDegree_2 <- strength(g1, weights = E(g1)$Weight) # Взвешенная степень
top25 <- order(wDegree_2, decreasing = T)[1:25] # Только топ-25 персонажей, чтобы не перегружать сеть (до этого там было невозможно прочитать что-либо)
sub_g <- induced_subgraph(g1, top25) # Подграф, полученный из исходного графа (для ребер) и топ-25 вершин

info_subg <- cluster_infomap(sub_g, e.weights = E(sub_g)$Weight) # В отличие от других функций обнаружений сообщств, здесь, если я правильно поняла необходим именно e.weights взвешенных сетей 
mem_subg <- membership(info_subg) #Извлекаю сообщества
membership(info_subg) |> 
  head()
                Telyanin         Boris_Drubetskoy                  Bilibin 
                       1                        1                        2 
Prince_Nikolay_Bolkonsky          AndreyBolkonsky    Vasily_Vasska_Denisov 
                       2                        2                        1 

Модулярность полученного разбиения составляет:

stringr::str_glue("Модулярность первого тома: {modularity(info_subg)}")
Модулярность первого тома: 0.49706817289548

Подобное значение модулярности в целом высокое, что указывает на достаточно чёткое разделение вершин на группы.

Построим визуализацию:

my_colors <- c("#41678D", "#276235", "#6F4A2F", "#D2B773", "#EEA205", "#AB2524")
vertex_colors <- my_colors[mem_subg]
groups <- split(V(sub_g)$name, mem_subg)

# Граф
set.seed(13032018)
par(mar = rep(0, 4))
plot(info_subg, sub_g,
    col = vertex_colors, # Окрашиваю узлы в свои выбранные цвета 
     vertex.label = V(sub_g)$name,
     vertex.label.cex = 0.5,
     vertex.label.color = "black",
     vertex.label.dist = 0.6,
     vertex.size = 8,
     edge.arrow.size = 0.2,
     mark.groups = groups,
     mark.col = adjustcolor(my_colors, alpha.f = 0.2)[unique(mem_subg)], # Окрашиваю кластеры на фоне тоже в свои цвета
     mark.border = NA, # Убираю обводку фоновых кластеров, потому что они плохо выглядят 
     layout = layout_with_fr(sub_g, weights = E(sub_g)$Weight)) 

  legend("topright",  # Добавляю легенду
       legend = paste("Сообщество", 1:length(unique(mem_subg))),
       fill = my_colors[1:length(unique(mem_subg))],
       bty = "n", cex = 0.8)

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

  1. Армейское общество: Борис Друбецкой, Николай Ростов, Телянин, Василий Денисов, капитан Тушин, Петр Иванович Багратион;
  2. Болконские: князь Андрей Болконский, князь Николай Болконский, княжна Марья Болконская (Мари), Елизавета Карловна Болконская («маленькая княжна»), Билибин, полководец Михаил Илларионович Кутузов, господин Несвицкий;
  3. Светское общество: Пьер Безухов, Анна Павловна Шерер, князь Василий Курагин, Катишь Мамонтова, Анна Михайиловна Друбецкая, граф Илья Андреевич Ростов, графиня-мать Наталья Роства.
  4. Ростовы: Наташа Ростова, Соня Ростова;
  5. Общество Долохова: Федор Долохов, гусарский корнет Жерков, regimental commander.

Все эти пять сообществ крайне логичны и хорошо отображают события первого тома.


Аналогичная процедура проведена для четвёртого тома.

wDegree_4 <- strength(g4, weights = E(g4)$Weight) 
top25 <- order(wDegree_4, decreasing = T)[1:25]

sub_g4 <- induced_subgraph(g4, top25) 

info_subg4 <- cluster_infomap(sub_g4, e.weights = E(sub_g4)$Weight)
mem_subg4 <- membership(info_subg4) 
membership(info_subg4) |> 
  head()
            Platon_Karataev              NatashaRostova 
                          1                           1 
Princess_Mariya_Bolkonskaya             Pierre_Bezukhov 
                          1                           1 
      Vasily_Vasska_Denisov                Petya_Rostov 
                          2                           2 

Модулярность разбиения четвёртого тома оказалась выше, чем для первого:

stringr::str_glue("Модулярность четвертого тома: {modularity(info_subg4)}")
Модулярность четвертого тома: 0.557770657806258

Это свидетельствует о ещё более ярко выраженной кластерной структуре, что может быть связано с поляризацией общества в условиях войны 1812 года.

Построим визуализацию:

my_colors <- c("#41678D", "#276235", "#6F4A2F", "#D2B773", "#EEA205", "#AB2524", "#879598")
vertex_colors <- my_colors[mem_subg4]
groups <- split(V(sub_g4)$name, mem_subg4)

set.seed(13032021)
par(mar = rep(0, 4))
plot(info_subg4, sub_g4,
    col = vertex_colors,
     vertex.label = V(sub_g4)$name,
     vertex.label.cex = 0.5,
     vertex.label.color = "black",
     vertex.label.dist = 1.5,
     vertex.size = 8,
     edge.arrow.size = 0.2,
     mark.groups = groups,
     mark.col = adjustcolor(my_colors, alpha.f = 0.2)[unique(mem_subg4)],
     mark.border = NA,
     layout = layout_with_fr(sub_g4, weights = E(sub_g4)$Weight))

  legend("topright", 
       legend = paste("Сообщество", 1:length(unique(mem_subg4))),
       fill = my_colors[1:length(unique(mem_subg4))],
       bty = "n", cex = 0.8)

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

  1. Центральные персонажи: Соня Ростова, княжна-мать Наталья Ростова, Андрей Болконский, Наташа Ростова, княжна Марья Болконская, Пьер Безухов, генерал Даву, Платон Каратаев;
  2. Участники партизанского движения: Федор Долохов, Василий Дмитриевич Денисов, Тихон Щербатов, Петя Ростов, Лихачев, эсаул Ловайский;
  3. Николай Ростов в доме губернатора: Николай Ростов, губернаторша;
  4. Фигура императора и его окружение: российский император Александр I, полковник Мишо;
  5. Участники войны:Болховитинов, Щербинин;
  6. Главнокомандующий: Кутузов;
  7. Народная среда: плясун, фельдфебель, солдаты;

Кажется, в данном случае получается не так четко разделить сообщества. Что интересно? Если фигура Кутузова интегрирована в различные сюжетные линии и связана с большинством сообществ, то император Александр I демонстрирует нарративную обособленность. Это может быть обусловлено тем, что в последнем томе происходит разрыв между народом и правителем, а также возникают конфликтные ситуации между Александром и Кутузовым.

Особого внимания заслуживает включение Платона Каратаева в кластер главных героев. На первый взгляд второстепенный, данный персонаж, благодаря своей топологической близости к Пьеру Безухову, обретает статус ключевого элемента в системе образов. Это соотносится с сюжетом романа: Каратаев выступает в роли духовного проводника для Безухова, что объясняет его положение в одном сообществе с центральными фигцрами повествования.

Аналогично, выделение партизан в отдельную группу акцентирует внимание на концепции «народной войны», тогда как обособление Николая Ростова в сфере губернаторского дома подчеркивает его временное дистанцирование от боевых действий и погружение в бытовой контекст, что также находит прямое подтверждение в тексте романа.

Таким образом, алгоритм InfoMAP оказывается оптимальным инструментом для анализа сообществ в романе «Война и мир».

4.9 Клики

Помимо выявления сообществ, важным этапом анализа структуры сети является поиск клик — максимальных полных подграфов, в которых каждая вершина соединена со всеми остальными.

Размер наибольшей клики в романе «Война и мир»:

stringr::str_glue("Размер наибольшей клики: {clique_num(war_and_peace_igraph)}")
Размер наибольшей клики: 7

Рассмотрим состав данной клики:

cliques(war_and_peace_igraph, min=7)
[[1]]
+ 7/435 vertices, named, from aa31d2e:
[1] NatashaRostova              Nikolai_Rostov             
[3] AndreyBolkonsky             Pierre_Bezukhov            
[5] Sonya_Rostova               Countess_Natalya_Rostova   
[7] Princess_Mariya_Bolkonskaya

В группу персонажей, наиболее тесно связанных непосредственными отношенями, вновь входят центральные узлы:

  • Наташа Ростова (NatashaRostova);
  • Николай Ростов (Nikolai_Rostov);
  • Андрей Болконский (AndreyBolkonsky);
  • Пьер Безухов (Pierre_Bezukhov);
  • Соня Ростова (Sonya_Rostova);
  • Графиня-мать Наталья Роства (Countess_Natalya_Rostova);
  • Княжна Марья Болконская (Princess_Mariya_Bolkonskaya).

В данную клику вошли исключительно представители двух основых семейств: Ростовых и Болконских. Примечательно, что в нее также попал Пьер Безухов — это может быть обусловлено тем, что данный персонаж в целом является связующим звеном романа, а также тем, что он близок к обеим семьям.

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

5 Заключение

В настоящей работе был проведен сетевой анализ романа Л. Н. Толстого «Война и мир». На основе размеченного XML-файла с помощью цифровых методов был построен граф взаимодействий персонажей, включающий 435 узлов и 1265 ребер.

Анализ структурных характеристик и метрик центральности позволил сделать следующие выводы:

  1. Ядро романа. Расчеты степеней центральности, посредничества и собственного вектора подтвердили, что ключевыми фигурами, скрепляющими повествование, являются Пьер Безухов, Андрей Болконский, Наташа Ростова, Николай Ростов и княжна Марья Болконская. Именно они обладают наибольшим числом и весом связей, выступая главными действующими лицами с точки зрения структуры текста.
  2. Роль связующих звеньев. С помощью анализа точек сочленения были выявлены герои, которые являются связующими звеньями между остальными. Среди них есть не только главные, но и второстепенные персонажи, например, Василий Денисов, Борис Друбецкой, князь Николай Андреевич Болконский и другие. Удаление точек сочленения привело бы к распаду графа на отдельные компоненты.
  3. Сообщества. Благодаря примененному алгоритму InfoMAP были выявлены основные сообщества персонажей в первом и четвертом томах. Если в первом томе более отчётливо выделяются семейно-светские круги, а военные лишь намечаются, то в четвертом структура меняется: сообщества перестраиваются вокруг военных и народных реалий 1812 года, что отражает поляризацию общества в условиях войны.
  4. Плотность связей. Анализ k-ядер показал, что наиболее плотно связанная группа (ядро с k=24) состоит из тех же центральных персонажей. Это математически подтверждает, что основные герои образуют не просто множество связей, а устойчивый и сплоченный «каркас» романа.
  5. Клики. Поиск полных подграфов выявил максимальную клику размером 7, в которую вошли исключительно представители семей Ростовых и Болконских, а также Пьер Безухов. Это ещё раз подчеркивает, что структурным ядром романа остаются семейные связи и личные отношения узкого круга центральных персонажей.

Таким образом, анализ социальной сети романа с помощью цифровых методов позволил не только визуализировать, но и подтвердить литературоведческие наблюдения. Мы увидели, как теория Толстого о «героях-атомах» реализуется на структурном уровне: центральные персонажи формируют ядро, второстепенные выступают связующими звеньями, а динамика исторических событий перестраивает конфигурацию социальных связей в романе.

6 Библиография

Бендерский, Илья Игоревич. 2021. «Война и мир»: от замысла к мифу: 8 лекций для проекта Магистерия. Москва: Rosebud Publishing.
Дуглас, Люк. 2017. Анализ сетей (графов) в среде R. Руководство пользователя. Переведено А. В. Груздев. Москва: ДМК Пресс.
Лу, Бернард, и М. С. Шперберг-Мак-Куин. 1995. Введение в TEI Lite. Не указано.
Толстой, Лев Николаевич. 1952. Полное собрание сочинений: Дневники и записные книжки 1858–1880. Т. 48. Москва: Государственное издательство художественной литературы.