Записка Н.М. Карамзина [1] представляет интерес для исследователей не только благодаря витиеватой красоте своего слога и монументальности амбиций ее создателя, которому удалось на нескольких страницах уместить историю народа, его покровителей и тиранов, вместе с анализом актуальной политической ситуации, сложившейся на Европейском континенте на момент написания текста в 1811 году. Интересна она прежде всего благодаря тому месту, которая Записка занимает в становлении общественно-политического (и более того, в значительной степени оппозиционного) дискурса в России того периода.
Содержащаяся в Записке критика политики монарха (в том числе относящаяся к действиям правителей прошлого) во многом определила судьбу этого текста. Изначально не запланированный к публикации, он вышел в свет с обширными цензурными правками в 1837 году в пушкинском “Современнике”, уже после смерти историка. И впоследствии он несколько раз в урезанном формате возникал в публичном поле и вскоре вымарывался из печати, согласно высочайшему распоряжению. Изучению столь нехарактерного для Карамзина (особенно в свете сложившейся в советской историографии его репутации как «придворного историографа») исторического и общественно-политического пафоса, как и поиску возможных связей произведения с критическими полутонами «общественного пространства» империи, во многом оппозиционного к реформистскому духу правления Александра, и посвящали свои труды многочисленные исследователи творческого наследия мастера.
Собственно, исследованию исторического нарратива Карамзина в Записке и сравнению его с более известным творением автора - “Историей государства Российского”, была посвящена моя дипломная работа на истфаке ВШЭ. В настоящем же проекте передо мной стоит гораздо более приземлённая задача, заключающаяся в проверке на базе Записки Карамзина некоторых возможностей освоенных мною инструментов компьютерного анализа текстов, о чем ниже.
Традиционно в Записке выделяются две неравные по размеру части: меньшая, посвященная истории Росси, начиная от истории населявших эту территорию племен и заканчивая правлением Павла I, и более объемную, содержащую аналитическую характеристику правления Александра, внутренне- и внешнеполитическому состоянию империи в период разгара Наполеоновских войн в Европе. Основным же исследовательским направлением проекта является попытка выяснить насколько количественные метрики, применимые к тексту под разными углами, способны выразить этот очевидный обычному читателю семантический переход. В качестве тестируемых метрик я возьму сравнительный анализ частотности слов и словесных коллокаций в обоих частях Записки.
Для большей структурированности проекта разумным видится выделить следующие гипотезы относительно предполагаемых результатов количественного анализа Записки:
Устанавливаем необходимые библиотеки:
library(gutenbergr)
library(stringr)
library(tidyverse)
library(rvest)
library(udpipe)
library(tidytext)
Считываем текст Записки (в англоязычной историографии - memoir):
url <- "https://www.hist.msu.ru/ER/Etext/karamzin.htm"
html <- read_html(url)
memoir <- html %>%
html_elements("center+ pre") %>%
html_text2()
Очищаем текст от оставшихся символов переноса строки, цифр и вставок издателей в квадратных скобках:
mem <- memoir %>%
str_replace_all("\\n", " ")%>%
str_replace_all("[[:digit:]]", " ") %>%
str_replace_all("\\[(.+?)\\]", "\\1")
Разделяем две анализируемые части Записки (повествование о современности начинается со слов: “Доселе говорил я о царствованиях минувших — буду говорить о настоящем”) в разные переменные и удаляем примечания издателей в конце текста:
old_rus <- mem %>%
str_replace("^.*(Настоящее бывает.*)Доселе говорил я.*", "\\1") %>%
str_squish()
new_rus <- mem %>%
str_replace("^.*(Доселе говорил я.*)\\. Гнездо племен.*", "\\1") %>%
str_squish()
Соединяем данные в таблицу и токенизируем:
mem_tbl <- tibble(topic = c("old_rus", "new_rus"), text = c(old_rus, new_rus))
mem_words <- mem_tbl %>%
unnest_tokens(word, text, token = "words", to_lower = TRUE)
Для начала протестируем метрику подсчета частотности слов в тексте. Для этого очистим текст от стандартных стоп-слов и некоторых устаревших слов, не схватываемых этими стандартными списками:
library("stopwords")
SW = stopwords("ru", source = "stopwords-iso")
other <- c("россии", "нежели", "надобно", "сей", "ибо", "столь", "сего", "т.е", "сии", "ныне", "проч", "вместо", "весьма")
mem_words_nosp <- mem_words %>%
filter(!word %in% SW) %>%
filter(!word %in% other)
mem_words_top <- mem_words_nosp %>%
count(topic, word) %>%
arrange(-n)
DT::datatable(mem_words_top, caption = "(Табл.1)")
Визуализируем полученные данные:
mem_words_nosp %>%
group_by(topic) %>%
count(word, sort = TRUE) %>%
slice_head(n = 15) %>%
ggplot(aes(reorder_within(word, n, topic), n, fill = word)) +
geom_col(show.legend = F) +
facet_wrap(~topic, scales = "free") +
scale_x_reordered() +
coord_flip()
На диаграмме видны недостатки этого метода. В частности, несколько слов в разных формах попали в разные столбцы, что для русского языка особенно чувствительно. Но уже здесь заметна пропорционально большая встречаемость в первой части текста (old_rus) таких слов как “народ”, “россияне”, “государство” (вместе с дериватами), “власть” (в разных формах). Во второй же (new_rus) части текста преобладают такие слова, как “государь”, “законы”, “правительство”, “совет”. Это должно склонять нас скорее в пользу принятия второй гипотезы. В то же время в пользу третей гипотезы говорят частотность на диаграмме old_rus слов типа “петр”, “князей”, “бояр”, “екатерина”.
Гораздо большую точность, как ожидается, способны продемонстрировать следующие метрики. Лемматизация и разметка текста по частям речи с последующим анализом сочетаемостей слов позволяет поставить слова в контекст, что, в свою очередь, дает возможность более корректно представить семантическую нагруженность отдельных слов.
Для лемматизации и разметки я использую модель Taiga из анализатора UDPipe, т.к. она натренирован, среди прочего, на художественных текстах (fiction), что представляется наиболее близкой из предложенных категорий к стилистической специфике Записки. Плюс полезным кажется и присутствие в списке категорий энциклопедических текстов (wiki) из-за обилия специальной и устаревшей лексики в тексте:
udpipe_download_model(language = "russian-taiga")
## language file_model
## 1 russian-taiga C:/Users/Acer/Documents/russian-taiga-ud-2.5-191206.udpipe
## url
## 1 https://raw.githubusercontent.com/jwijffels/udpipe.models.ud.2.5/master/inst/udpipe-ud-2.5-191206/russian-taiga-ud-2.5-191206.udpipe
## download_failed download_message
## 1 FALSE OK
rus_taiga <- udpipe_load_model(file = "russian-taiga-ud-2.5-191206.udpipe")
mem_tbl_old <- mem_tbl %>%
filter(topic == "old_rus")
mem_udp_old <- as_tibble(udpipe_annotate(rus_taiga, mem_tbl_old$text))
mem_tbl_new <- mem_tbl %>%
filter(topic == "new_rus")
mem_udp_new <- as_tibble(udpipe_annotate(rus_taiga, mem_tbl_new$text))
Для начала выведем самые частотные существительные:
mem_udp_old_N <- mem_udp_old %>%
filter(upos == "NOUN") %>%
count(lemma) %>%
arrange(-n)
mem_udp_new_N <- mem_udp_new %>%
filter(upos == "NOUN") %>%
count(lemma) %>%
arrange(-n)
DT::datatable(mem_udp_old_N, caption = "(Табл.2)_Old_Russia")
DT::datatable(mem_udp_new_N, caption = "(Табл.3)_New_Russia")
Среди характерных изменений по сравнению с результатами предыдущих экспериментов можно выделить восхождение на первое по частотности место леммы “народ” для первой исторической части, и леммы “человек” для второй - в подтверждение второй гипотезы. К тому же можно отнести и “подъем” леммы “ассигнация” во второй части, специфичной именно для описания современности - способствует принятию третей гипотезы. Наконец, мы видим в историческом сегменте появление “века” как термина, относимого к длительности, т.е. верификаторам первой гипотезы. Однако, лемма “время”, имеющая схожую семантическую категорию, чаще встречается во второй современной части.
Далее, предлагаю вниманию читателей ряд таблиц, содержащих результаты анализа коллокаций, объединенных согласно расположению в рамках одного предложения: существительных и прилагательных (Табл.4-5), существительных и глаголов (Табл.6-7).
old_N_ADJ <- mem_udp_old %>%
subset(upos %in% c("NOUN", "ADJ"))
mem_cooc_old_adj <- old_N_ADJ %>%
cooccurrence(term = "lemma", group = c("paragraph_id", "sentence_id")) %>%
as_tibble()
old_N_V <- mem_udp_old %>%
subset(upos %in% c("NOUN", "VERB"))
mem_cooc_old_v <- old_N_V %>%
cooccurrence(term = "lemma", group = c("paragraph_id", "sentence_id")) %>%
as_tibble()
new_N_ADJ <- mem_udp_new %>%
subset(upos %in% c("NOUN", "ADJ"))
mem_cooc_new_adj <- new_N_ADJ %>%
cooccurrence(term = "lemma", group = c("paragraph_id", "sentence_id")) %>%
as_tibble()
new_N_V <- mem_udp_new %>%
subset(upos %in% c("NOUN", "VERB"))
mem_cooc_new_v <- new_N_V %>%
cooccurrence(term = "lemma", group = c("paragraph_id", "sentence_id")) %>%
as_tibble()
DT::datatable(mem_cooc_old_adj, caption = "(Табл.4)_Old_Russia_N_ADJ")
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html
DT::datatable(mem_cooc_new_adj, caption = "(Табл.5)_New_Russia_N_ADJ")
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html
DT::datatable(mem_cooc_old_v, caption = "(Табл.6)_Old_Russia_N_V")
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html
DT::datatable(mem_cooc_new_v, caption = "(Табл.7)_New_Russia_N_V")
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html
Помимо подтверждения некоторых предыдущих результатов, настоящие данные привлекают внимание рядом следующих положений. Так, на первых местах в Табл.4 мы видим пары “государь-народ”, “государственный-власть”, “государственный-россиянин” а в Табл.5 - “государь-закон”, “государственный-новый”, “государственный-ассигнации”. Совпадение первых слов в парах между этими таблицами может говорить о том, что в схожих контекстах в первой части преимущество отдается “коллективным” терминам (Гипотеза 2), а во второй - “институциональным”, а также временным, но относящимся к новому, актуальному положению дел (Гипотеза 1).
Среди глагольных коллокация (Табл.6-7) примечательно, что во второй части (Табл.6) лемма “иметь”, как глагол более характерный для описания актуальных состояний (по сравнению, к примеру, с глаголом “мочь”), встречается в большем количестве контекстов, чем в первой (Табл.7).
Наконец, следующие две таблицы (Табл.8-9) могут представлять интерес с важных для нас позиций. Слова там сгруппированы в коллокации по признаку ближайшего расположения (skipgram = 1), а не нахождения в одних предложениях.
old_skip <- mem_udp_old %>%
subset(upos %in% c("NOUN", "ADJ"))
mem_skip_old_adj <- cooccurrence(old_skip$lemma, relevant = old_skip$upos %in% c("NOUN", "ADJ"), skipgram = 1) %>%
as_tibble()
new_skip <- mem_udp_new %>%
subset(upos %in% c("NOUN", "ADJ"))
mem_skip_new_adj <- cooccurrence(new_skip$lemma, relevant = new_skip$upos %in% c("NOUN", "ADJ"), skipgram = 1) %>%
as_tibble()
DT::datatable(mem_skip_old_adj, caption = "(Табл.8)_Old_Russia_skip")
DT::datatable(mem_skip_new_adj, caption = "(Табл.9)_New_Russia_skip")
Здесь, в первую очередь, интересно “течение-век” как самая популярная коллокация в первой части (Табл.8), что говорит в пользу первой гипотезы, и “Тайная-канцелярия” - в пользу третей. При этом во второй части (Табл.9) нет практически ничего, что могло бы противоречить рассматриваемым гипотезам. Из спорного и не обсуждавшегося выше можно выделить, пожалуй, только сочетание “гражданский-общество”, но и его частотное употребление именно во второй части характерно, т.к. оно употребляется Карамзиным именно в институциональном смысле “законного, единообразного течения в делах правительства” [1, с. 64].
Последняя метрика, которую я предлагаю использовать на нашем материале, позволит выявить частотность слов в каждой из частей Записки, не встречающихся при этом в другой части. Хотя больше смысла эта метрика имеет при применении на большем количестве источников (чем две наши части), но все же она наилучшим из доступных мне образом позволит выявить именно отличия между фрагментами текста:
mem_topic_word_top <- mem_words %>%
count(topic, word, sort = TRUE) %>%
ungroup()
mem_words_tfidf <- mem_topic_word_top %>%
bind_tf_idf(word, topic, n) %>%
arrange(-tf_idf)
Визуализируем результаты:
mem_words_tfidf %>%
group_by(topic) %>%
top_n(15) %>%
ungroup() %>%
ggplot(aes(reorder_within(word, tf_idf, topic), tf_idf, fill = topic)) +
geom_col(show.legend = F) +
labs(x = NULL, y = "tf-idf") +
facet_wrap(~topic, scales = "free") +
scale_x_reordered() +
coord_flip()
## Selecting by tf_idf
Как мы видим, именно во второй части (и только в ней) часто употребляется слова “ныне”, “ассигнации”, “правительство”, “меры”, “крестьяне”, “наполеон”, что красноречиво свидетельствует в пользу каждой из трех гипотез. На второй диаграмме впервые появляются слова “дух”, “древних”, “царей”, “московских”, а также римские обозначения порядкового номера царей (вероятнее всего, относимых к Ивану III и Ивану IV), что также подтверждает все гипотезы. Любопытным, пожалуй, является уникальное для первой исторической части Записки употребление понятия “дух”, но анализ этого обстоятельства правильно было бы отнести скорее к области потенциального самостоятельного исследования.
Таким образом, как показало проведенное небольшое исследование, используемые количественные метрики по преимуществу подтверждают каждую из принятых в начале проекта гипотез, выведенных из “наивного” прочтения текста. Это говорит о том, что с помощью количественных методов можно измерить текст на предмет семантического разграничения его частей (по крайней мере, одного из способов этого разграничения).
Вместе с тем не стоит забывать, что успех этого анализа зависит от характера исходных предположений, и вполне возможно получить противоположный результат, если иначе подойти к предполагаемой специфике разграничения и выдвинуть иные гипотезы. Несмотря на это, явным позитивным результатом моего исследования можно считать доказательство возможности прийти к выводам обычного читателя, т.е. в некотором смысле измерить понимание текста Записки.