library(tidyverse)
library(stylo)
<- read.table(file = "table_with_frequencies.txt") |>
freqs t() |>
as.data.frame()
::datatable(freqs, options = list(pageLength = 10)) DT
«Тихий Дон» М.А. Шолохова
1 Что тут происходит?
В рамках статьи Цифровая текстология: атрибуция текста на примере романа М.А. Шолохова «Тихий Дон» Орехова Б. В. был подготовлен датасет стилеметрических данных “Тихого Дона” и современных ему авторов. Этот датасет мы попробуем представить в виде консенснусного дерева и посмотреть, что из этого выйдет.
2 Задаем росток
Загрузим необходимые для работы библиотеки и преобразуем датасет в удобный нам формат с помощью функции transpose t()
Теперь мы можем построить консенсусное дерево с помощью метода BCT (Bootstrap Consensus Tree)
<- stylo(gui = FALSE,
bct_result frequencies = freqs,
analysis.type = "BCT",
mfw.min = 100,
mfw.max = 300,
mfw.incr = 100,
distance.measure = "wurzburg",
custom.graph.title = "Sholohov and other authors",
write.png.file = FALSE,
consensus.strength = 0.5
)
Дерево получилось интересное, но не оформленное. Попробуем его преобразить и добавить визуала.
3 Выращиваем красивое дерево
Для начала напишем функцию, которая возьмет случайные 100 столбцов в таблице с частотностями, посчитает евклидово расстояние между документами и построит дерево.
library(ape)
<- function(df) {
get_tree <- df[ , sample(3000, replace = F, size = 100)]
X <- dist(scale(X))
distmx <- as.phylo(hclust(distmx))
tr
tr }
Запустим ее 15 раз при помощи map(), а затем посчитаем консенсус.
library(purrr)
set.seed(123)
<- map(1:15, ~get_tree(freqs))
trees_result
<- consensus(trees_result, p = 0.5, rooted = FALSE) cons
И начнем строить дерево для наших данных. Для этого мы зададим палетку с 12 цветами для каждого из авторов данного датасета. И присвоим каждый цвет каждому автору. После чего построим дерево с заданными цветами в формате tidy и подпишем узлы.
library(paletteer)
<- c('#121510FF','#6D8325FF', '#D6CFB7FF', '#E5AD4FFF', '#BD5630FF', '#3A488AFF', '#8785B2FF', '#DABD61FF', '#EA879CFF', '#BE3428FF', '#2CB11BFF', '#088BBEFF')
pal
$col <- str_remove_all(cons$tip.label, "_.+")
cons
<- tibble(label = unique(cons$col),
colour_tbl col = pal)
<- tibble(label = cons$col) |>
result left_join(colour_tbl)
par(mar = c(0,0,0,0))
plot.phylo(cons,
type = "tidy",
use.edge.length = TRUE,
edge.width = 1.5,
node.color = "grey30",
font = 1,
no.margin = TRUE,
label.offset = 0.1,
direction = "rightwards",
plot = TRUE,
tip.color = result$col,
lab4ut = "a",
node.depth = 1)
nodelabels(text=sprintf("%.2f", cons$node.label),
node=1:cons$Nnode+Ntip(cons),
frame="circle",
bg = "#BF9BDDFF",
cex = 0.5,
)
Красиво!
4 Оцениваем результат
Как можно видеть из построенных деревьев, произведения в общем случае логично распределяются по кластерам, однако есть некоторые интересные особенности.
Например, в нашем случае с plot.phylo можно увидеть, что большинство авторов и их произведения распределяются с высокой точностью (например, общий кластер формируют “Мастер и Маргарита” и “Белая гвардия” Булгакова или “Чевенгур” и “Котлован” Платонова и др.).
Однако “Донские рассказы” и “Судьба человека” Шолохова сформировали свои собственные кластеры и оказались в некоторой обособленности от остальных произведений автора. А “Тихий Дон” соседствует скорее с кластером Платонова, нежели с кластером Шолохова. В этом смысле дерево получилось хоть и более наглядное, но в некоторой степени менее точное, чем дерево, построенное методом BCT.
В методе BCT мы видим, что хоть произведения и расположены на разных ветвях, оба выше упомянутых рассказа вписываются в два сформированных кластера рассказов Шолохова, куда также относятся четыре тома произведения “Тихий Дон”. Это соответсвует результатам, описанным в статье Б.В. Орехова, и потому кажется, что в нашей учебной попытке воспроизвести схожие результаты данное дерево проявило себя на практике лучше.