library(dendextend)
library(tidyverse)
library(ape)
library(ggsci)Консенсусные деревья и сети
Установка пакетов
Перед началом работы необходимо скачать и подгрузить необходимые пакеты:
Трансформация данных
В качестве исходных данных используется таблица частот слов из датасета «Стилометрические данные “Тихого Дона” и современной ему прозы», подготовленного Б. В. Ореховым. Датафрейм изначально сохранен в текстовом формате.
После загрузки в среду R данные преобразуются в таблицу, которую затем необходимо привести к требуемому формату.
# Преобразование файла .txt в табличный формат
df <- read.table(
"table_with_frequencies.txt",
header = TRUE,
sep = " ",
check.names = FALSE,
row.names = 1
)
# Транспорнировка таблицы
df_with_frequencies <- as.data.frame(t(df))
# Просмотр фрагмента таблицы
knitr::kable(df_with_frequencies [1:10, 1:10], caption = "Таблица частотности")| и | в | на | не | с | а | что | он | как | то | |
|---|---|---|---|---|---|---|---|---|---|---|
| Булгаков_БелаяГвардия | 4.866468 | 3.347350 | 1.853296 | 1.494054 | 1.1473447 | 0.8800022 | 1.1779777 | 0.7894957 | 0.7059512 | 0.6516472 |
| Булгаков_МастериМаргарита | 4.398680 | 3.195690 | 1.758419 | 1.777723 | 1.1477107 | 0.8546409 | 1.6724286 | 1.0117052 | 0.7765474 | 0.9397540 |
| Иванов_Бронепоезд1469 | 4.349652 | 2.207823 | 2.069834 | 1.715863 | 1.0679146 | 1.7278618 | 0.4259659 | 0.5579554 | 1.0439165 | 1.1339093 |
| Иванов_ГолубыеПески | 3.707162 | 2.702949 | 1.823978 | 1.637254 | 0.9176819 | 1.1977684 | 0.5077992 | 0.7264033 | 0.8061027 | 0.7651144 |
| Крюков_ГруппаБ | 4.318761 | 2.833192 | 1.559847 | 1.490874 | 1.4378183 | 0.6738115 | 0.7268676 | 0.6419779 | 0.6791171 | 0.4456706 |
| Крюков_Зыбь | 4.546693 | 2.371003 | 1.594295 | 1.944041 | 1.2400073 | 1.0265262 | 0.7539971 | 1.1991279 | 0.7948765 | 0.7994186 |
| Крюков_КисточникуИсцелений | 5.462529 | 2.546838 | 1.709602 | 1.176815 | 1.4402810 | 1.3348946 | 0.5620609 | 0.8957845 | 0.5737705 | 1.1416862 |
| Крюков_Мать | 4.038977 | 2.485525 | 1.786471 | 1.835899 | 1.3486796 | 0.8261545 | 0.8473379 | 0.7272984 | 0.9038271 | 0.7484819 |
| Крюков_Шквал | 4.433540 | 2.427374 | 1.459030 | 1.784706 | 1.0421642 | 0.8988666 | 1.3938947 | 1.0378219 | 0.9900560 | 0.8511008 |
| Леонов_Барсуки | 4.266004 | 2.556303 | 1.777759 | 1.826225 | 1.0497443 | 1.2198895 | 0.7991668 | 0.8631001 | 0.7960733 | 0.8795991 |
В результате преобразования таблица приняла корректную структуру: столбцы соответствуют переменным (словам), а ряды — наблюдениям (авторам и текстам). Можно переходить к следующему этапу анализа.
Построение консенсусного дерева
Меня заинтересовало построение танглграмм, позволяющих отслеживать различия между дендрограммами, полученными с использованием различных методов связи, при том что для кластеризации применялась одна и та же матрица расстояний (по умолчанию — евклидова, однако в нашем случае использовалась манхэттенская).
# Создаю матрицу попарных расстояний между объектами
dist_matrix <- dist(df_with_frequencies, method = "manhattan")
# Строю танглграммы
d1 <- as.dendrogram(hclust(dist_matrix, method = "complete")) |>
set("labels_col", value = c("skyblue4", "darkolivegreen4", "sienna4", "plum4", "azure4"), k = 5) |>
set("branches_k_color", value = c("skyblue4", "darkolivegreen4", "sienna4", "plum4", "azure4"), k = 5)
d2 <- as.dendrogram(hclust(dist_matrix, method = "single")) |>
set("labels_col", value = c("skyblue4", "darkolivegreen4", "sienna4", "plum4", "azure4"), k = 5) |>
set("branches_k_color", value = c("skyblue4", "darkolivegreen4", "sienna4", "plum4", "azure4"), k = 5)
dlist <- dendlist(d1, d2)
# Строю график
tanglegram(dlist, common_subtrees_color_lines = F,
highlight_distinct_edges = T,
highlight_branches_lwd = F,
margin_inner = 8,
lwd = 0.6,
axes= F,
main_left = "Полное",
main_right = "Одиночное",
sort = T,
lab.cex = 0.6)Мне было интересно посмотреть на то, как группируются произведения в зависимости от метода связи. В данном случае, это полная связь ("complete") и одиночный метод ("single"). Данные методы выбраны в связи с тем, что они демонстрируют более корректную работу при использовании манхэттенского расстояния.
Для более детального выявления структурных различий каждая дендрограмма была разделена на пять кластеров (k = 5).
Комментарии
Итак, как можно кратко охарактеризовать полученный результат?
- Несмотря на использование разных методов связи, наблюдаются устойчивые тенденции: «Судьба человека» стабильно отделяется от остальных произведений Шолохова и формирует самостоятельный кластер.
- В полном методе по разным кластерам распределяются «Тихий Дон» и «Поднятая целина» Шолохова, в одиночном — все эти произведения находятся рядом. Тем не менее, «Тихий Дон» и «Донские рассказы» в обоих методах расположены по соседству. Это может говорить о сходстве их лексико-частотного профиля.
- Произведения Крюкова более компактно группируются дендраграмме с полным методом: там они все находятся в одном кластере. Это обосновывается тем, что полный метод лучше выявляет плотные авторские группы. При одиночной связи они распадаются, что может свидетельствовать о том, что такой метод сильнее реагирует на локальные сходства.
Как мне кажется, при выбранных параметрах метод полной связи демонстрирует более структурированное и интерпретируемое распределение произведений, поскольку формирует компактные и устойчивые кластеры.
Дополнение
Дополнительно хотелось бы построить обычное дерево, чтобы наглядно увидеть, как располагаются произведения
dist_matrix_new <- dist(df_with_frequencies, method = "manhattan")
hc <- hclust(dist_matrix_new, method = "complete")
phy_tree <- as.phylo(hc)
# Назначаю авторам цвета
palette_colors <- pal_simpsons()(9) # Цвета Симпсонов :)
cols_df <- tibble(label = phy_tree$tip.label) |>
mutate(author = str_remove(label, "_.+"),
color = case_when(
author == "Шолохов" ~ palette_colors[1],
author == "Крюков" ~ palette_colors[2],
author == "Dubia" ~ palette_colors[3],
author == "Платонов" ~ palette_colors[4],
author == "Фадеев" ~ palette_colors[5],
author == "Булгаков" ~ palette_colors[6],
author == "Островский" ~ palette_colors[7],
author == "Иванов" ~ palette_colors[8],
author == "Серафимович" ~ palette_colors[9],
T ~ "grey50"
))
# Строю дерево
par(mar = c(0,0,0,0))
plot.phylo(phy_tree,
type = "tidy",
use.edge.length = T,
edge.width = 1,
node.color = "grey60",
font = 0.6,
no.margin = T,
label.offset = 0.1,
node.depth = 1,
tip.color = cols_df$color,
cex = 0.5)
# Подписываю узлы
nodelabels(
text = phy_tree$node.label,
frame = "circle",
bg = "white",
cex = 0.5
)Поскольку здесь также используется манхэттенское расстояние и кластеризация методом полной связи, наблюдаются сходства с предыдущим графиком.
- «Судьба человека» Шолохова, как и раньше, выделяется и стоит особняком от остальных произведений автора.
- «Тихий Дон» и «Донские рассказы» расположены близко друг к другу, тогда как «Поднятая целина» и «Они сражались за родину» стоят отдельно, но тоже относительно рядом.
- На этом графике цветами выделяются не кластеры, а авторы, поэтому более наглядно видно, что произведения каждого писателя в основном сгруппированы вместе. Это объясняется тем, что у каждого автора свой характерный стиль и язык. Наиболее неоднозначной в этом плане фигурой оказывается Шолохов, что ожидаемо.