Как найти частоту n-граммов и визуализировать ее в wordcloud с помощью R?

#r #nlp

#r #nlp

Вопрос:

У меня есть фрейм данных со столбцом, который содержит строки текста, которые я хотел бы проанализировать. Я хотел бы знать, какие слова используются чаще всего, и визуализировать это в wordcloud. Для отдельных слов (униграмм) мне удалось это сделать, но я не могу заставить свой код работать для n-граммов (например, биграмм, триграмм). Здесь я включил свой код для униграмм. Я открыт для корректировки своего кода, чтобы он работал, или для создания совершенно нового фрагмента кода. Как мне лучше всего подойти к этому?

 library(wordcloud)
library(RColorBrewer)
library(wordcloud2)
library(tm)
library(stringr)

#Delete special characters and lower text
df$text <- str_replace_all(df$text, "[^[:alnum:]]", " ")
df$text <- tolower(df$text)

#From df to Corpus
corpus <- Corpus(VectorSource(df))

#Remove english stopwords, 
stopwords<-c(stopwords("english"))
corpus <- tm_map(corpus, removeWords,stopwords)
rm(stopwords)

#Make term document matrix
tdm <- TermDocumentMatrix(corpus,control=list(wordLenths=c(1,Inf)))

#Make list of most frequent words
tdm_freq <- as.matrix(tdm) 
words <- sort(rowSums(tdm_freq),decreasing=TRUE) 
tdm_freq <- data.frame(word = names(words),freq=words)
rm(words)

#Make a wordcloud
wordcloud2(tdm_freq, size = 0.4, minSize = 10, gridSize =  0,
           fontFamily = 'Segoe UI', fontWeight = 'normal',
           color = 'red', backgroundColor = "white",
           minRotation = -pi/4, maxRotation = pi/4, shuffle = TRUE,
           rotateRatio = 0.4, shape = 'circle', ellipticity = 0.8,
           widgetsize = NULL, figPath = NULL, hoverFunction = NULL)
  

Ответ №1:

Изменение Corpus на VCorpus so tokenising будет работать.

 # Data
df <- data.frame(text = c("I have dataframe with a column I have dataframe with a column", 
                          "I would like to know what are the most I would like to know what are the most", 
                          "For single words (unigrams) I've managed to do so For single words (unigrams) I've managed to do so",
                          "Here I've included my code for the unigrams Here I've included my code for the unigrams"))

# VCorpus
corpus <- VCorpus(VectorSource(df))
funs <- list(stripWhitespace,
             removePunctuation,
             function(x) removeWords(x, stopwords("english")),
             content_transformer(tolower))
corpus <- tm_map(corpus, FUN = tm_reduce, tmFuns = funs)

# Tokenise data without requiring any particular package
ngram_token <-  function(x) unlist(lapply(ngrams(words(x), 2), paste, collapse=" "), use.names=FALSE)

# Pass into TDM control argument
tdm <- TermDocumentMatrix(corpus, control = list(tokenize = ngram_token))
freq <- rowSums(as.matrix(tdm))
tdm_freq <- data.frame(term = names(freq), occurrences = freq)
tdm_freq


                               term occurrences
code unigrams         code unigrams           2
column dataframe   column dataframe           1
column like             column like           1
dataframe column   dataframe column           2
included code         included code           2
...