rm(list = ls())
date()
## [1] "Mon Feb 21 15:35:07 2022"
sessionInfo()
## R version 4.1.2 (2021-11-01)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur 10.16
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.29 R6_2.5.1 jsonlite_1.7.3 magrittr_2.0.1
## [5] evaluate_0.14 rlang_0.4.12 stringi_1.7.6 jquerylib_0.1.4
## [9] bslib_0.3.1 rmarkdown_2.11 tools_4.1.2 stringr_1.4.0
## [13] xfun_0.29 yaml_2.2.1 fastmap_1.1.0 compiler_4.1.2
## [17] htmltools_0.5.2 knitr_1.37 sass_0.4.0
load(file = "Texts3.RData")
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# library(readtext)
library(quanteda)
## Package version: 3.2.0
## Unicode version: 13.0
## ICU version: 69.1
## Parallel computing: 4 of 4 threads used.
## See https://quanteda.io for tutorials and examples.
library(stringr)
library(quanteda.textstats)
# library(ggplot2)
library(magrittr)
#Создание функции стемминга
Вывод версии программы Mystem
system2("./Mystem/mystem", args = "-v") #Вывод версии программы Mystem
mystem <- function(doc, arg, format = "") { # Можно вствить формат вывода
# " --format xml" и " -- format json"
sdoc <- system2("./Mystem/mystem"
, args = paste0("-", arg, format)
, stdout = TRUE
# TRUE (capture the output
# in a character vector)
, input = doc)
sdoc
}
-n Построчный режим; каждое слово печатается на новой строке. -c Копировать весь ввод на вывод. То есть, не только слова, но и межсловные промежутки. Опция необходима для возврата к полному представлению текста. В случае построчного вывода (когда задана опция n) межсловные промежутки вытягиваются в одну строку, символы перевода строки заменяются на /или . Пробел для большей видимости заменяется на подчеркивание. Символ заменяется на \, подчеркивание на _. Таким образом можно однозначно восстановить исходный текст. -w Печатать только словарные слова. -l Не печатать исходные словоформы, только леммы и граммемы. -i Печатать грамматическую информацию, расшифровка ниже. -g Склеивать информацию словоформ при одной лемме (только при включенной опции -i). -s Печатать маркер конца предложения (только при включенной опции -c). -e Кодировка ввода/вывода. Возможные варианты: cp866, cp1251, koi8-r, utf-8 (по умолчанию). -d Применить контекстное снятие омонимии. –eng-gr Печатать английские обозначения граммем. –filter-gram Строить разборы только с указанными граммемами. –fixlist Использовать файл с пользовательским словарём. –format Формат вывода.Возможные варианты: text, xml, json. Значение по умолчанию — text. –generate-all Генерировать все возможные гипотезы для несловарных слов. –weight Печатать бесконтекстную вероятность леммы.
Части речи
A прилагательное ADV наречие ADVPRO местоименное наречие ANUM числительное-прилагательное APRO местоимение-прилагательное COM часть композита - сложного слова CONJ союз INTJ междометие NUM числительное PART частица PR предлог S существительное SPRO местоимение-существительное V глагол
Стемминг
# aTime <- Sys.time()
# Data_S <- Data
# for (i in 1:length(Data$text)) {
# Data$text[i] <- str_replace_all(Data$text[i], "\n", " ")
# Data_S$text[i] <- paste(paste(mystem(Data$text[i], "cligsd"), collapse = "{\\s}"), "{\\s}") %>%
# # Майстем выдает по абзацам - склеиваю абзацы
# # добавляю маркеры конца предложения + маркер в конце текстов
# # ### !!! похоже работает не так.
# # ### Замена паттерна для склейки ничего не меняет.
# str_extract_all("([{])(([\\\\а-яa-z]+))([^{}]+)([}])") %>%
# # Открывающая скобка, один слеш (нужно написать четыре) или буква русская или латинская, один или несколько любых символов кроме скобок, закрывающая скобка
# unlist(.) %>%
# str_replace("([{])([а-я?-]+)([=])([[:alpha:]]+)([=,])([[:graph:]]*?)()([}])"
# , "\\2_\\4") %>%
# str_replace("([{])([:graph:]*)([}])", "\\2") %>%
# str_c(collapse = " ")
#
# }
# Sys.time() - aTime
# #Data_S$text[1]
# # добавляю конце предложения в разбивку абзацев. Майстем по обзацам выдаёт и нужно объединять
# # # . Точка позволяет вствить в другое место pipe operator
Стемминг2
t <- Sys.time()
Data_S <- Texts3
for (i in 1:length(Data_S$text)) {
Data_S$text[i] <- str_replace_all(Data_S$text[i], "\n", " ") #убираю абзацы
# mystem выдаёт текст по абзацам
Data_S$text[i] <- (mystem(Data_S$text[i], "cligsd")) %>%
paste("{\\s}") %>%
str_extract_all("([{])(([\\\\а-яa-z]+))([^{}]+)([}])") %>%
# Открывающая скобка, один слеш (нужно написать четыре) или буква русская или латинская, один или несколько любых символов кроме скобок, закрывающая скобка
unlist(.) %>%
str_replace("([{])([а-я?-]+)([=])([[:alpha:]]+)([=,])([[:graph:]]*?)()([}])"
, "\\2_\\4") %>%
str_replace(fixed("{\\s}"), "__D") %>% #знак конца предложения
str_c(collapse = " ")
}
Sys.time() - t
## Time difference of 17.28892 mins
__D - конец предложения
Убираю знаки абзацев из текста. Они могут быть случайными или это стихи и эпиграфы, разбивающие предложения
Создание нового корпуса
Corpus_S <- corpus(Data_S)
Статистика по новому корпусу
# CorpusSummary_S <- summary(Corpus_S, n = 10000)
# #CorpusSummary
# table(CorpusSummary_S$Group)
# summary(CorpusSummary_S[-1])
Corpus_S %>%
summary(n = 1000) %>%
extract(2:4) %>%
summary()
## Types Tokens Sentences
## Min. : 34.0 Min. : 52.0 Min. : 1.00
## 1st Qu.: 149.0 1st Qu.: 287.5 1st Qu.: 14.00
## Median : 238.0 Median : 484.5 Median : 22.00
## Mean : 315.7 Mean : 763.5 Mean : 26.94
## 3rd Qu.: 411.2 3rd Qu.: 948.0 3rd Qu.: 33.00
## Max. :1769.0 Max. :8734.0 Max. :387.00
Количество предложений в тексте после стемминга - это нераспознанные слова, которые идут с вопросительным знаком.
Настоящие предложения отделены символами __D
textstat_summary(Corpus_S) %>%
arrange(desc(sents)) %>%
head(25)
## document chars sents tokens types puncts numbers symbols urls
## 1 0436_Психологич.txt 78110 387 8734 1769 1118 0 0 0
## 2 1078_Московский.txt 23833 166 2810 808 531 0 0 0
## 3 1063_Качество_о.txt 47983 138 5130 1352 190 0 3 0
## 4 0207_Учительска.txt 32792 123 3521 1031 131 0 0 0
## 5 0888_Viperson_r.txt 15568 120 1938 678 368 0 0 0
## 6 1079_Страховое_.txt 33019 112 3446 1177 225 0 0 0
## 7 0149_Forbes_ru_.txt 22242 107 2500 948 163 0 0 0
## 8 1033_Клуб_Учите.txt 45354 107 3996 711 145 0 0 0
## 9 0924_Промышленн.txt 56535 104 5829 1469 115 0 0 0
## 10 0563_Новая_газе.txt 61171 100 6628 1613 120 0 0 0
## 11 0851_Федеральны.txt 20246 99 2101 650 143 0 0 0
## 12 0987_Russkieves.txt 32375 99 3469 1159 158 0 0 0
## 13 1158_Bipkro_ru_.txt 5719 99 832 270 215 0 0 0
## 14 1134_Федеральны.txt 15788 98 1726 674 139 0 0 0
## 15 0450_РАНХиГС__r.txt 6944 89 865 224 145 0 0 0
## 16 0601_Координаци.txt 39993 86 4136 1198 145 0 0 0
## 17 0716_Открытое_о.txt 10919 85 1328 329 159 0 0 0
## 18 0992_Кугарчинск.txt 15236 85 1746 680 111 0 0 0
## 19 0903_News_Life_.txt 26674 84 2895 1133 131 0 0 0
## 20 0099_Реальное_в.txt 13002 83 1566 582 133 0 0 0
## 21 0727_Федеральны.txt 27915 82 2990 778 147 0 0 0
## 22 0820_Форум_Доно.txt 7290 81 865 397 140 0 0 0
## 23 0386_Вести_обра.txt 24418 80 2711 958 133 0 0 0
## 24 0980_Seldon_New.txt 30928 80 3600 1070 205 0 0 0
## 25 0663_Городская_.txt 28973 79 3073 952 147 0 0 0
## tags emojis
## 1 0 0
## 2 0 0
## 3 0 0
## 4 0 0
## 5 0 0
## 6 0 0
## 7 0 0
## 8 0 0
## 9 0 0
## 10 0 0
## 11 0 0
## 12 0 0
## 13 0 0
## 14 0 0
## 15 0 0
## 16 0 0
## 17 0 0
## 18 0 0
## 19 0 0
## 20 0 0
## 21 0 0
## 22 0 0
## 23 0 0
## 24 0 0
## 25 0 0
Нераспознанные слова - английские из интернет адресов. Надо, наверное, чистить. Они в фигурных скобках - не сложно будет удалить.
Corpus_S %>%
tokens(what = "fastestword") %>%
tokens_remove("^[{]", valuetype = "regex") %>% # удаление слов,
# которые начинаются с фигурной скобки
textstat_summary() %>%
extract(4:5) %>%
summary()
## tokens types
## Min. : 27.0 Min. : 26.0
## 1st Qu.: 219.5 1st Qu.: 134.0
## Median : 413.0 Median : 220.0
## Mean : 674.5 Mean : 300.1
## 3rd Qu.: 845.0 3rd Qu.: 395.0
## Max. :7230.0 Max. :1617.0
Corpus_S %>%
tokens(what = "fastestword") %>%
#tokens_remove("^[{]", valuetype = "regex") %>%
textstat_summary() %>%
extract(4:5) %>%
summary()
## tokens types
## Min. : 32.0 Min. : 31.0
## 1st Qu.: 230.0 1st Qu.: 144.0
## Median : 424.0 Median : 233.5
## Mean : 686.8 Mean : 311.0
## 3rd Qu.: 857.0 3rd Qu.: 405.5
## Max. :7474.0 Max. :1762.0
можно не очищать от неопознанных слов, которые в фигурных скобках. они не имеют признака части речи и не пойдут в DFM
# DFM_S <- Corpus_S %>%
# tokens(what = "fastestword") %>%
# tokens_remove("^[{]", valuetype = "regex") %>%
# dfm()
Таблица слов с удаленным признаком части речи
Tokens_S <- tokens(Corpus_S
, what = "fasterword"
, include_docvars = FALSE
, verbose = TRUE)
## Creating a tokens object from a corpus input...
## ...starting tokenization
## ...0002_Мои_года__.txt to 1178_Федеральны.txt
## ...22,457 unique types
## ...removing separators
## ...complete, elapsed time: 0.574 seconds.
## Finished constructing tokens from 876 documents.
Words <- data.frame(W1 = types(Tokens_S)
, W2 = str_replace(types(Tokens_S)
, "([[:alpha:]]+)(_[[:alpha:]]+)"
, "\\1")
, stringsAsFactors = FALSE)
DFM <- Tokens_S %>%
tokens_keep(pattern = c("*_S", "*_V", "*_A", "*_ADV")) %>%
tokens_replace(Words$W1, Words$W2, valuetype = "fixed") %>%
dfm() %>%
dfm_trim(min_docfreq = 2)
# Оставляем слова которые встрчаются больше чем в одном тексте
# Только существительные, глаголы и прилагательные и наречия
Самые частые слова:
topfeatures(DFM, n = 20)
## образование быть школа образовательный ребенок
## 6263 5094 4419 3605 3274
## год цифровой обучение программа учитель
## 3271 3233 2894 2481 2396
## платформа проект новый развитие работа
## 2395 2286 2237 2153 1782
## сбербанк педагог система технология мочь
## 1496 1478 1467 1382 1373
plot(topfeatures(DFM, n = 100))
Слова, которые встречаются в самом большом числе текстов
Stat <- DFM %>%
textstat_frequency() %>%
arrange(desc(docfreq)) %>%
head(20)
Stat
## feature frequency rank docfreq group
## 1 образование 6263 1 875 all
## 4 образовательный 3605 4 725 all
## 2 быть 5094 2 719 all
## 3 школа 4419 3 693 all
## 6 год 3271 6 648 all
## 9 программа 2481 9 646 all
## 8 обучение 2894 8 643 all
## 14 развитие 2153 14 635 all
## 7 цифровой 3233 7 633 all
## 13 новый 2237 13 627 all
## 5 ребенок 3274 5 597 all
## 12 проект 2286 12 567 all
## 15 работа 1782 15 566 all
## 11 платформа 2395 11 565 all
## 34 персонализировать 1024 34 546 all
## 10 учитель 2396 10 512 all
## 24 становиться 1287 24 501 all
## 22 возможность 1344 22 500 all
## 32 получать 1119 32 500 all
## 27 также 1227 27 498 all
plot(Stat$docfreq)
DFM <- dfm_remove(DFM, names(topfeatures(DFM))[1:4])
save(Corpus_S, file = "Corpus_S.RData")
save(DFM, file = "DFM.RData")