rm(list = ls())
date()
## [1] "Wed May 20 23:21:12 2020"
sessionInfo()
## R version 3.6.1 (2019-07-05)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Catalina 10.15.4
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/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] compiler_3.6.1 magrittr_1.5 tools_3.6.1 htmltools_0.4.0
## [5] yaml_2.2.0 Rcpp_1.0.2 stringi_1.4.3 rmarkdown_1.16
## [9] knitr_1.25 stringr_1.4.0 xfun_0.10 digest_0.6.21
## [13] rlang_0.4.6 evaluate_0.14
##Библиотеки
library(quanteda)
## Package version: 1.5.1
## Parallel computing: 2 of 4 threads used.
## See https://quanteda.io for tutorials and examples.
##
## Attaching package: 'quanteda'
## The following object is masked from 'package:utils':
##
## View
library(topicmodels)
## Warning: package 'topicmodels' was built under R version 3.6.2
library(ldatuning)
## Warning: package 'ldatuning' was built under R version 3.6.2
library(wordcloud2)
library(data.table)
# library(dplyr)
# library(stringr)
library(ggplot2)
require(pals)
## Loading required package: pals
library(magrittr)
# # library(tibble)
# #
# library(igraph)
# library(Matrix)
# load(file = "Tokens_S2.RData")
load(file = "Tokens_S.RData")
# load(file = "Corpus_S2.RData")
Tokens_S <- Tokens_S %>%
tokens_keep(pattern = c("*_S", "*_V", "*_A")
, padding = TRUE
) # оставляю пустоты вместо удаленных слов
Collocation <- Tokens_S %>%
textstat_collocations(min_count = 25)
#Tokens_S <- tokens_compound(Tokens_S, Collocation)
head(Collocation)
## collocation count count_nested length lambda z
## 1 окружающий_a среда_s 293 0 2 7.674044 59.21067
## 2 мочь_v позволять_v 227 0 2 5.041889 52.95458
## 3 природный_a ресурс_s 124 0 2 5.101227 43.70098
## 4 живой_a существо_s 71 0 2 6.589237 38.18878
## 5 вырубать_v лес_s 77 0 2 6.426373 34.63412
## 6 огромный_a количество_s 51 0 2 6.132416 33.24050
Получаются тройные сочетания - нужно ли их ограничивать?
DTM <- Tokens_S %>%
tokens_remove("") %>% # убираем пустые места, которые были нужны для поиска словосочетаний
dfm() %>%
dfm_trim(min_docfreq = 2, max_docfreq = Inf)
# Слова которые встрчаются больше чем в одном тексте
dim(DTM)
## [1] 225 4286
topfeatures(DTM)
## природа_s человек_s быть_v мочь_v отношение_s жизнь_s
## 4337 4145 1398 1097 1062 626
## животное_s мир_s должный_a позволять_v
## 579 565 559 511
FriqWord <- names(topfeatures(DTM))[1:5]
DTM <- dfm_remove(DTM, FriqWord)
dim(DTM)
## [1] 225 4281
t <- Sys.time()
DTM2topicmodels <- convert(DTM, to = "topicmodels")
LDAtuning.metrics_Gibbs <- FindTopicsNumber(DTM2topicmodels
, topics = seq(from = 4, to = 15, by = 1)
, metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014")
, method = "Gibbs"
, control = list(seed = 77)
, mc.cores = 2L, verbose = TRUE
)
## fit models... done.
## calculate metrics:
## Griffiths2004... done.
## CaoJuan2009... done.
## Arun2010... done.
## Deveaud2014... done.
Sys.time() - t
## Time difference of 1.078525 mins
FindTopicsNumber_plot(LDAtuning.metrics_Gibbs)
K <- 8 # Количество тем
set.seed(9161)
TopicModel <- LDA(DTM, K, method = "Gibbs", control = list(iter = 500, verbose = 25))
## K = 8; V = 4281; M = 225
## Sampling 500 iterations!
## Iteration 25 ...
## Iteration 50 ...
## Iteration 75 ...
## Iteration 100 ...
## Iteration 125 ...
## Iteration 150 ...
## Iteration 175 ...
## Iteration 200 ...
## Iteration 225 ...
## Iteration 250 ...
## Iteration 275 ...
## Iteration 300 ...
## Iteration 325 ...
## Iteration 350 ...
## Iteration 375 ...
## Iteration 400 ...
## Iteration 425 ...
## Iteration 450 ...
## Iteration 475 ...
## Iteration 500 ...
## Gibbs sampling completed!
# have a look a some of the results (posterior distributions)
TmResult <- posterior(TopicModel)
# format of the resulting object
attributes(TmResult)
## $names
## [1] "terms" "topics"
ncol(DTM)
## [1] 4281
Связь термина и темы
# topics are probability distribtions over the entire vocabulary
beta <- TmResult$terms # get beta from results
dim(beta) # K distributions over ncol(DTM) terms
## [1] 8 4281
rowSums(beta)
## 1 2 3 4 5 6 7 8
## 1 1 1 1 1 1 1 1
Во всех стобцах сумма равна единице
Связь темы и текста
theta <- TmResult$topics
dim(theta)
## [1] 225 8
rowSums(theta)[1:5]
## Bio1 Bio2 Bio3 Bio4 Bio5
## 1 1 1 1 1
Cумма вероятностей по темам тоже единица.
выведем по наиболее значимых терминов из каждой темы
terms(TopicModel, 15)
## Topic 1 Topic 2 Topic 3 Topic 4
## [1,] "природный_a" "ребенок_s" "позволять_v" "мусор_s"
## [2,] "экологический_a" "лес_s" "животное_s" "проблема_s"
## [3,] "развитие_s" "новый_a" "ресурс_s" "вода_s"
## [4,] "общество_s" "земля_s" "вопрос_s" "год_s"
## [5,] "потребность_s" "относиться_v" "человечество_s" "океан_s"
## [6,] "цель_s" "должный_a" "должный_a" "количество_s"
## [7,] "являться_v" "поколение_s" "становиться_v" "отходы_s"
## [8,] "человеческий_a" "среда_s" "делать_v" "выбрасывать_v"
## [9,] "проблема_s" "окружающий_a" "говорить_v" "происходить_v"
## [10,] "человечество_s" "оставлять_v" "считать_v" "земля_s"
## [11,] "закон_s" "богатство_s" "данный_a" "страна_s"
## [12,] "мир_s" "река_s" "иметь_v" "загрязнение_s"
## [13,] "становиться_v" "жить_v" "начинать_v" "хотеть_v"
## [14,] "система_s" "природный_a" "думать_v" "большой_a"
## [15,] "качество_s" "вырубать_v" "помогать_v" "пакет_s"
## Topic 5 Topic 6 Topic 7 Topic 8
## [1,] "среда_s" "мир_s" "планета_s" "жизнь_s"
## [2,] "окружающий_a" "жизнь_s" "лес_s" "давать_v"
## [3,] "ресурс_s" "существо_s" "время_s" "животное_s"
## [4,] "вид_s" "существовать_v" "вид_s" "жить_v"
## [5,] "вода_s" "любовь_s" "животное_s" "земля_s"
## [6,] "жизнь_s" "брать_v" "становиться_v" "дерево_s"
## [7,] "природный_a" "являться_v" "растение_s" "воздух_s"
## [8,] "влияние_s" "сила_s" "год_s" "мир_s"
## [9,] "изменение_s" "место_s" "воздух_s" "понимать_v"
## [10,] "использовать_v" "образ_s" "газ_s" "живой_a"
## [11,] "приводить_v" "дом_s" "рыба_s" "вред_s"
## [12,] "использование_s" "правило_s" "сохранение_s" "защищать_v"
## [13,] "являться_v" "делать_v" "завод_s" "гармония_s"
## [14,] "человечество_s" "иметь_v" "создавать_v" "лес_s"
## [15,] "должный_a" "называть_v" "приводить_v" "современный_a"
Создадим имена для тем в виде первых пяти слов
TopicNames <- TopicModel %>%
terms(5) %>%
apply(2, paste, collapse = " ")
TopicNames[1]
## Topic 1
## "природный_a экологический_a развитие_s общество_s потребность_s"
set.seed(1991)
#for (i in 1:K) {
i <- 1
TmResult$terms %>%
extract(i,) %>%
sort(decreasing = TRUE) %>%
extract(1:40) %>%
data.frame(names(.), .) %>%
wordcloud2(shuffle = FALSE, size = 0.4
, fontWeight = "normal", rotateRatio = 0)
#}
i <- 1
TmResult$terms %>%
extract(i,) %>%
sort(decreasing = TRUE) %>%
extract(1:40) %>%
data.frame(names(.), .) %>%
wordcloud2(shuffle = FALSE, size = 0.4
, fontWeight = "normal", rotateRatio = 0)
Вариант1. Сортировка на основе вероятности появления темы по всей коллекции
# What are the most probable topics in the entire collection?
topicProportions <- colSums(theta) / nrow(DTM) # mean probablities over all paragraphs
names(topicProportions) <- TopicNames # assign the topic names we created before
sort(topicProportions, decreasing = TRUE) # show summed proportions in decreased order
## позволять_v животное_s ресурс_s вопрос_s человечество_s
## 0.1392022
## среда_s окружающий_a ресурс_s вид_s вода_s
## 0.1379369
## природный_a экологический_a развитие_s общество_s потребность_s
## 0.1276058
## мусор_s проблема_s вода_s год_s океан_s
## 0.1257142
## жизнь_s давать_v животное_s жить_v земля_s
## 0.1242554
## ребенок_s лес_s новый_a земля_s относиться_v
## 0.1242005
## планета_s лес_s время_s вид_s животное_s
## 0.1174876
## мир_s жизнь_s существо_s существовать_v любовь_s
## 0.1035975
Разница минимальна.
Вариант 2. Как часто тема становится первой в тексте.
countsOfPrimaryTopics <- rep(0, K)
names(countsOfPrimaryTopics) <- TopicNames
for (i in 1:nrow(DTM)) {
topicsPerDoc <- theta[i, ] # select topic distribution for document i
# get first element position from ordered list
primaryTopic <- order(topicsPerDoc, decreasing = TRUE)[1]
countsOfPrimaryTopics[primaryTopic] <- countsOfPrimaryTopics[primaryTopic] + 1
}
sort(countsOfPrimaryTopics, decreasing = TRUE)
## позволять_v животное_s ресурс_s вопрос_s человечество_s
## 45
## мусор_s проблема_s вода_s год_s океан_s
## 41
## среда_s окружающий_a ресурс_s вид_s вода_s
## 32
## природный_a экологический_a развитие_s общество_s потребность_s
## 29
## жизнь_s давать_v животное_s жить_v земля_s
## 24
## ребенок_s лес_s новый_a земля_s относиться_v
## 23
## планета_s лес_s время_s вид_s животное_s
## 22
## мир_s жизнь_s существо_s существовать_v любовь_s
## 9
a <- aggregate(theta, by = list(group = docvars(DTM)[, 1]), mean)
colnames(a)[2:(K + 1)] <- TopicNames
a <- melt(a, id.vars = "group")
# plot topic proportions per deacde as bar plot
ggplot(a, aes(x = group, y = value, fill = variable)) +
geom_bar(stat = "identity") + ylab("proportion") +
scale_fill_manual(values = paste0(alphabet(20), "FF"), name = "group") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))