Введение

Действительно ли молодой Михаил Шолохов создал эту эпопею, или рукопись принадлежит перу Федора Крюкова или другого забытого белогвардейского автора?

В данной работе мы отходим от традиционных филологических споров и обращаемся к стилометрии — математическому анализу авторского стиля.

Подготовка данных

Мы используем матрицу Z-оценок частотности слов, подготовленную Б.В. Ореховым (корпус включает тексты Булгакова, Платонова, Фадеева, Крюкова, Шолохова и др.). Для анализа мы отберем топ-1000 наиболее частотных слов, чтобы исключить статистический шум

# Загрузка необходимых библиотек
library(tidyverse)
library(igraph)
library(ggrepel)
library(ggsci)

# Отбор 1000 самых частотных слов (предикторов)
raw_data <- read.table("table_with_frequencies.txt", header = TRUE, row.names = 1)
data_matrix <- t(raw_data)
data_subset <- data_matrix[, 1:1000]
dim(data_subset)
## [1]   30 1000

Методология

Чтобы сделать результаты интуитивно понятными, мы используем комбинацию двух методов. MDS (Multidimensional Scaling) — метод многомерного шкалирования. Он сжимает сложное пространство из 1000 измерений (слов) в 2D-карту. Чем ближе точки на карте, тем более схож стиль авторов. MST (Minimum Spanning Tree) — минимальное остовное дерево. Мы соединяем точки линиями, но не всеми подряд, а только кратчайшими. Это позволяет увидеть «скелет» стилистических связей (кто является ближайшим соседом для каждого текста).

# Расчет расстояний
dist_mx <- dist(data_subset, method = "manhattan")

# Создание координат для карты (MDS)
mds_model <- cmdscale(dist_mx, eig = TRUE, k = 2)
df_plot <- as.data.frame(mds_model$points)
colnames(df_plot) <- c("X", "Y")

# Добавление метаданных (Имя автора из названия файла)
df_plot$Label <- rownames(df_plot)
df_plot$Author <- str_remove(df_plot$Label, "_.*")

# Построение скелета связей (MST)
g <- graph_from_adjacency_matrix(as.matrix(dist_mx), mode = "undirected", weighted = TRUE)
mst <- mst(g) # Находим минимальное остовное дерево

# Извлекаем ребра для отрисовки
edges <- as_data_frame(mst, what = "edges")

# Привязываем координаты к концам линий
edges_plot <- edges |>
  left_join(df_plot, by = c("from" = "Label")) |>
  rename(X1 = X, Y1 = Y) |>
  left_join(df_plot, by = c("to" = "Label")) |>
  rename(X2 = X, Y2 = Y)

Стилометрическая карта

На графике ниже мы выделили цветом главную интригу: Шолохова (красный) и спорные тексты «Тихого Дона» (голубой). Остальные авторы-современники оставлены серым фоном для контекста.

# Подготовка категорий для раскраски
df_plot <- df_plot |>
  mutate(IsHero = case_when(
    Author == "Шолохов" ~ "Шолохов",
    Author == "Dubia" ~ "Тихий Дон", # Dubia - авторство достоверно не установлено
    TRUE ~ "Современники"
  ))

# Настройка цветов (Акцентные vs Фоновые)
my_colors <- c("Шолохов" = "#E64B35",    
               "Тихий Дон" = "#4DBBD5",  
               "Современники" = "#999999")

# Отрисовка
ggplot() +
  # Рисуем связи (линии MST)
  geom_segment(data = edges_plot, 
               aes(x = X1, y = Y1, xend = X2, yend = Y2), 
               color = "grey85", linewidth = 0.8) +
  
  stat_ellipse(data = df_plot |> filter(IsHero %in% c("Шолохов", "Тихий Дон")),
               aes(x = X, y = Y), 
               type = "t", level = 0.9, color = "grey80", linetype = 2) +
  
  # Рисуем точки (Тексты)
  geom_point(data = df_plot, 
             aes(x = X, y = Y, color = IsHero, size = IsHero), 
             alpha = 0.9) +
  
  # Добавляем подписи
  geom_text_repel(data = df_plot, 
                  aes(x = X, y = Y, label = Label),
                  size = 3, 
                  family = "sans", 
                  fontface = "bold",
                  color = "grey30",
                  max.overlaps = 20,
                  box.padding = 0.5) +
  
  # Косметика
  scale_color_manual(values = my_colors) +
  scale_size_manual(values = c("Шолохов" = 5, "Тихий Дон" = 5, "Современники" = 3)) +
  theme_void() +
  theme(
    legend.position = "top",
    legend.title = element_blank(),
    plot.title = element_text(size = 18, face = "bold", hjust = 0.5, color = "grey20"),
    plot.subtitle = element_text(size = 14, hjust = 0.5, color = "grey50"),
    plot.margin = margin(20, 20, 20, 20)
  ) +
  labs(title = "Стилометрическая карта: Кто написал «Тихий Дон»?")

Итог

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