Консенсусные деревья для анализа авторства ‘Тихого Дона’

Автор

Линев Никита

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

16 февраля 2026 г.

Сегодня мы рассмотрим стилеметрический анализ «Тихого Дона» и современной ему отечественной прозы в контексте построения консенсусных деревьев. В данной работе используются данные, подготовленные Б. В. Ореховым.

Импортируем библиотеки

library(tidyverse)
library(ape)
library(dendextend)
library(philentropy)
library(ggsci)

Считываем данные

freq <- read.table(
  "table_with_frequencies.txt",
  header = TRUE,
  row.names = 1,
  sep = " ",
  check.names = FALSE
)

Займемся обработкой данных. Сначала транспонируем матрицу, чтобы строки соответствовали словам, а столбцы — текстам. Затем для анализа отбираем 200 наиболее частотных слов.

freq_t <- t(freq)

mean_freq <- colMeans(freq_t)
top_words <- names(sort(mean_freq, decreasing = TRUE))[1:200]

X <- freq_t[, top_words] |> 
  scale()

get_tree <- function(df) {
  
  X_boot <- df[, sample(ncol(df), replace = TRUE)]
  
  dist_mx <- dist(X_boot, method = "canberra")
  
  tr <- as.phylo(hclust(dist_mx, method = "average"))
  tr
}

Создаем 100 деревьев для последующего построения консенсусного дерева.

set.seed(123)

trees_result <- map(1:100, ~get_tree(X))

par(mfrow = c(1,1), mar = c(1,1,1,1))
walk(trees_result[1], plot)

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

Для наглядной визуализации на графике выделим подходящим цветом тексты Шолохова и отдельно все четыре тома “Тихого Дона”!.

palette <- pal_igv()(6)

tip_cols <- tibble(label = cons$tip.label) |> 
  mutate(author = str_remove(label, "_.+"),
         color = case_when(
           author == "Шолохов" ~ palette[1],
           author == "Dubia"   ~ palette[2],
           TRUE                ~ "grey40"
         ))

Круговое консенсусное дерево

par(
  mar = c(2,2,2,2),
  family = "serif"
)

plot.phylo(
  cons,
  type = "fan",
  use.edge.length = FALSE,
  edge.width = 1.5,
  node.color = "grey30",
  font = 2,
  no.margin = TRUE,
  label.offset = 0.08,
  tip.color = tip_cols$color,
  cex = 0.75
)

nodelabels(
  text = sprintf("%.2f", as.numeric(cons$node.label)),
  node = 1:cons$Nnode + Ntip(cons),
  frame = "circle",
  bg = "white",
  cex = 0.7
)

title(
  "Консенсусное дерево \nCanberra distance, bootstrap по словам (n = 100)",
  line = 0.5
)

Полученные результаты позволяют заметить, что практически все тексты Шолохова образуют два кластера, причем «Тихий Дон» стабильно попадает в эти же группы и не смешивается с текстами других авторов. При этом уровень корелляции со всеми томами, кроме выпущенного сильно позднее четвертого, достаточно высокий (>0.8). В то же время, произведения остальных писателей, тяготеют как раз к собственным отдельным кластерам.

Все это позволяет сделать вывод о том, что настоящий автор романа только один! И мы это сегодня доказали, спасибо Борису Валерьевичу за датасет.