Изучение Тихого Дона методами стилометрии

Author

Максимов Алексей

Published

February 21, 2025

К постановке проблемы

На излёте существования Советского Союза начался логичный процесс деконструкции существовавших идеалов и личностей, эти идеалы отображающих. Михаил Шолохов ещё при жизни был признан классиком советской литературы, к тому же получившим Нобелевскую премию по литературе (и не пострадавшим от этого в отличие от Пастернака). Именно в те десятилетия был поставлен вопрос авторства его знаменитого романа “Тихий Дон”. Сам ли Шолохов написал его? Если да, то тогда не слишком ли это серьезный текст для начинающего литератора? Предлагались разные варианты. Одним из способов ответить стала стилометрия, которая показал свою эффективность даже на китайских стихотворных антологиях эпохи Тан (618-907 гг). Об установлении авторства “Тихового Дона” можно посмотреть в статье Н.П. Великановой и Б.В. Орехова. Мы же в рамках обучения посстараемся на их данных, в некотором роде, повторить их исследование.

Подготовка к работе

Для успешного достижения нашей цели необходимо подгрузить следующие библиотеки

library(tidyverse)
library(stylo)
library(ape)
library(purrr)
library(TreeTools)
library(phangorn)

Загружаем таблицу с частотностями слов и сохраняем в окружении в виде дата-фрейма

data <- read.table('table_with_frequencies.txt', sep = ' ') %>% 
  t() %>% 
  as.data.frame()

Консенсусные деревья

Консенсусное дерево - это, можно сказть, “обобщённое” дерево, полученное путём объединения более мелких дендрограмм. В stylo за консенсусные деревья отвечает метод BCT (Bootstrap Consensus Tree), которым мы воспользуемся.

bct_result <- stylo(gui = FALSE, 
                    frequencies = data,
                    analysis.type = 'BCT',
                    mfw.min = 100,
                    mfw.max = 500,
                    mfw.incr = 100,
                    distance.measure = 'wurzburg',
                    write.png.file = FALSE,
                    consensus.strength = 0.5,
                    plot.custom.width = 8, 
                    plot.custom.height = 8
)

Полученный график

На полученном графике сетко видно, что все четыре тома “Тихого Дона” кластеризуются вместе с другими произведениями Шолохова. Правда, стоит отметить, что тома 1-3 объединены с ранней его литературой, а последний с более поздней. Это выглядит логично и, возможно, связано с естественным творческим развитем автора, изменение тематики произведений (и из-за этого лексики).

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

Сощдадим функцию get_tree, которая возьмет случайные 100 столбцов из таблицы с частотностями, посчитает евклидово расстояние между документами и построит дерево

get_tree <- function(df) {
  X <- df[ , sample(2000, replace = FALSE, size = 100)]
  distmx <- dist(scale(X))
  tr <- as.phylo(hclust(distmx))
  tr
}

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

set.seed(2606)
trees_result <- map(1:12, ~get_tree(data))

cons <- consensus(trees_result, p = 0.5, rooted = TRUE)

pal <- c('#FF1E00',
         '#FF7F00',
         '#04819E',
         '#00BF32',
         '#5F4690FF',
         '#00A67C',
         '#FBFE00',
         '#666666FF',
         '#D5F800',
         '#3C13AF',
         '#C861D3',
         '#8A6ED7')

cons$col <- str_remove_all(cons$tip.label, '_.+')

cons_col_tbl <- tibble(label = unique(cons$col),
                       col = pal)

cons_color_group <- tibble(label = cons$col) |> 
  left_join(cons_col_tbl)

cons$col <- cons_color_group$col

Строим дерево. В качестве типа использую ‘fan’ (веер).

par(mfrow = c(1,1), mar = c(5,5,5,5))

plot.phylo(cons, 
           type = 'fan', 
           use.edge.length = TRUE,
           edge.width = 1.5, 
           node.color = 'black',
           font = 1, 
           no.margin = TRUE, 
           label.offset = 0.1,
           direction = 'rightwards', 
           plot = TRUE, 
           tip.color = cons$col,
           lab4ut = 'a',
           node.depth = 1)
nodelabels(text=sprintf('%.2f', cons$node.label),
           node=1:cons$Nnode+Ntip(cons),
           frame='circle',
           bg = 'steelblue',
           cex = 0.5)

Полученный график

“Веер” оказался не очень удобной для визуализации такого количества произведений типом. Меняем на ‘phylogram’.

par(mfrow = c(1,1), mar = c(5,5,5,5))

plot.phylo(cons, 
           type = 'phylogram', 
           use.edge.length = TRUE,
           edge.width = 1.5, 
           node.color = 'black',
           font = 1, 
           no.margin = TRUE, 
           label.offset = 0.1,
           direction = 'rightwards', 
           plot = TRUE, 
           tip.color = cons$col,
           lab4ut = 'a',
           node.depth = 1)
nodelabels(text=sprintf('%.2f', cons$node.label),
           node=1:cons$Nnode+Ntip(cons),
           frame='circle',
           bg = 'steelblue',
           cex = 0.5)

Полученный график

Можно заметить, что произведения Шолохова распределились на 3 разные группы: в одной “Тихий Дон” и “Донские рассказы” (ранние произведения; произведение, где место действия - “Дон”, время действия - начало ХХ века ), в другой “Они сражались за Родину” и “Поднятая целина” (поздние произвеения), отдельно стоит “Судьба человека”. В принципе, результат ожидаемый. Выше на дереве, построенном BCT методом, “Судьба человека” раннее других отделяется от основного “ствола”.

Консенсусная сеть

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

mph <- as.multiPhylo(trees_result)
cons.nw <- consensusNet(mph, prob = 0.3, rooted = FALSE)

cons.nw$col <- cons_color_group$col

Ставим зерно и визуализируем

set.seed(2606)
par(mar = c(0,0,0,0))
plot(cons.nw, type = '2D', 
     direction = 'axial',
     tip.color = cons.nw$col,
     edge.color = 'grey',
     edge.width = 1,)

Полученный график

Результаты построения этого дерева близки к предыдущему графику. Три кластера: “донские” произведения, поздние произведения и “Судьба человека”. Поэтому можно сказать, что с высокой вероятностью Шолохов - автор “Тихого Дона”. Возможные неурядицы в визуализации, скорее, связаны с развитием во времени творчества автора, различной тематики произведений, и в каком-то смысле, с определенными. жанровыми различиями и, честно говоря, учебным характером этой работы.