Trouver les Phrases de mots 2 et 3 en utilisant le paquet TM
j'essaie de trouver un code qui fonctionne réellement pour trouver les phrases de deux et trois mots les plus fréquemment utilisées dans R text mining package (peut-être qu'il y a un autre package que je ne connais pas). J'ai essayé d'utiliser le générateur de jetons, mais semblent n'avoir aucune chance.
Si vous avez travaillé sur une situation similaire dans le passé, pourriez-vous poster un code qui est testé et fonctionne réellement? Merci beaucoup!
7 réponses
vous pouvez passer dans une fonction de tokenizing personnalisée à la fonction tm
's DocumentTermMatrix
, donc si vous avez le paquet tau
installé, c'est assez simple.
library(tm); library(tau);
tokenize_ngrams <- function(x, n=3) return(rownames(as.data.frame(unclass(textcnt(x,method="string",n=n)))))
texts <- c("This is the first document.", "This is the second file.", "This is the third text.")
corpus <- Corpus(VectorSource(texts))
matrix <- DocumentTermMatrix(corpus,control=list(tokenize=tokenize_ngrams))
où n
dans la fonction tokenize_ngrams
est le nombre de mots par phrase. Cette fonctionnalité est également implémentée dans le paquet RTextTools
, ce qui simplifie encore plus les choses.
library(RTextTools)
texts <- c("This is the first document.", "This is the second file.", "This is the third text.")
matrix <- create_matrix(texts,ngramLength=3)
renvoie une classe de DocumentTermMatrix
pour utilisation avec paquet tm
.
Ceci est la partie 5 du FAQ du tm paquet:
5. Puis-je utiliser des bigrammes au lieu de simples jetons dans une matrice terme-document?
Oui. RWeka fournit un tokenizer pour n-grammes arbitraire qui peut être transmis directement au constructeur de matrice de document-terme. Par exemple:
library("RWeka")
library("tm")
data("crude")
BigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 2, max = 2))
tdm <- TermDocumentMatrix(crude, control = list(tokenize = BigramTokenizer))
inspect(tdm[340:345,1:10])
c'est ma propre création faite pour différents buts, mais je pense que peut être applicable à vos besoins aussi:
#User Defined Functions
Trim <- function (x) gsub("^\s+|\s+$", "", x)
breaker <- function(x) unlist(strsplit(x, "[[:space:]]|(?=[.!?*-])", perl=TRUE))
strip <- function(x, digit.remove = TRUE, apostrophe.remove = FALSE){
strp <- function(x, digit.remove, apostrophe.remove){
x2 <- Trim(tolower(gsub(".*?($|'|[^[:punct:]]).*?", "\1", as.character(x))))
x2 <- if(apostrophe.remove) gsub("'", "", x2) else x2
ifelse(digit.remove==TRUE, gsub("[[:digit:]]", "", x2), x2)
}
unlist(lapply(x, function(x) Trim(strp(x =x, digit.remove = digit.remove,
apostrophe.remove = apostrophe.remove)) ))
}
unblanker <- function(x)subset(x, nchar(x)>0)
#Fake Text Data
x <- "I like green eggs and ham. They are delicious. They taste so yummy. I'm talking about ham and eggs of course"
#The code using Base R to Do what you want
breaker(x)
strip(x)
words <- unblanker(breaker(strip(x)))
textDF <- as.data.frame(table(words))
textDF$characters <- sapply(as.character(textDF$words), nchar)
textDF2 <- textDF[order(-textDF$characters, textDF$Freq), ]
rownames(textDF2) <- 1:nrow(textDF2)
textDF2
subset(textDF2, characters%in%2:3)
le corpus la bibliothèque a une fonction appelée term_stats
qui fait ce que vous voulez:
library(corpus)
corpus <- gutenberg_corpus(55) # Project Gutenberg #55, _The Wizard of Oz_
text_filter(corpus)$drop_punct <- TRUE # ignore punctuation
term_stats(corpus, ngrams = 2:3)
## term count support
## 1 of the 336 1
## 2 the scarecrow 208 1
## 3 to the 185 1
## 4 and the 166 1
## 5 said the 152 1
## 6 in the 147 1
## 7 the lion 141 1
## 8 the tin 123 1
## 9 the tin woodman 114 1
## 10 tin woodman 114 1
## 11 i am 84 1
## 12 it was 69 1
## 13 in a 64 1
## 14 the great 63 1
## 15 the wicked 61 1
## 16 wicked witch 60 1
## 17 at the 59 1
## 18 the little 59 1
## 19 the wicked witch 58 1
## 20 back to 57 1
## ⋮ (52511 rows total)
Ici, count
est le nombre d'apparitions, et support
est le nombre de documents contenant le terme.
j'ajoute un problème similaire en utilisant les paquets tm
et ngram
.
Après avoir débogué mclapply
, j'ai vu là où les problèmes sur les documents avec moins de 2 mots avec l'erreur suivante
input 'x' has nwords=1 and n=2; must have nwords >= n
donc j'ai ajouté un filtre pour supprimer le document avec le nombre de mots bas:
myCorpus.3 <- tm_filter(myCorpus.2, function (x) {
length(unlist(strsplit(stringr::str_trim(x$content), '[[:blank:]]+'))) > 1
})
alors ma fonction tokenize ressemble à:
bigramTokenizer <- function(x) {
x <- as.character(x)
# Find words
one.list <- c()
tryCatch({
one.gram <- ngram::ngram(x, n = 1)
one.list <- ngram::get.ngrams(one.gram)
},
error = function(cond) { warning(cond) })
# Find 2-grams
two.list <- c()
tryCatch({
two.gram <- ngram::ngram(x, n = 2)
two.list <- ngram::get.ngrams(two.gram)
},
error = function(cond) { warning(cond) })
res <- unlist(c(one.list, two.list))
res[res != '']
}
ensuite vous pouvez tester la fonction avec:
dtmTest <- lapply(myCorpus.3, bigramTokenizer)
et enfin:
dtm <- DocumentTermMatrix(myCorpus.3, control = list(tokenize = bigramTokenizer))
Try tidytext package
library(dplyr)
library(tidytext)
library(janeaustenr)
library(tidyr
)
supposez que j'ai un CommentData de dataframe qui contient une colonne de commentaires et je veux trouver occurrence de deux mots ensemble. Alors essayez
bigram_filtered <- CommentData %>%
unnest_tokens(bigram, Comment, token= "ngrams", n=2) %>%
separate(bigram, c("word1","word2"), sep=" ") %>%
filter(!word1 %in% stop_words$word,
!word2 %in% stop_words$word) %>%
count(word1, word2, sort=TRUE)
le code ci-dessus crée des tokens, puis supprime les mots d'arrêt qui n'aident pas à l'analyse(par ex. le,la, un,etc. Ensuite, vous compter l'apparition de ces mots. Vous utiliserez alors la fonction unite pour combiner des mots individuels et consignez leur occurrence.
bigrams_united <- bigram_filtered %>%
unite(bigram, word1, word2, sep=" ")
bigrams_united
essayez ce code.
library(tm)
library(SnowballC)
library(class)
library(wordcloud)
keywords <- read.csv(file.choose(), header = TRUE, na.strings=c("NA","-","?"))
keywords_doc <- Corpus(VectorSource(keywords$"use your column that you need"))
keywords_doc <- tm_map(keywords_doc, removeNumbers)
keywords_doc <- tm_map(keywords_doc, tolower)
keywords_doc <- tm_map(keywords_doc, stripWhitespace)
keywords_doc <- tm_map(keywords_doc, removePunctuation)
keywords_doc <- tm_map(keywords_doc, PlainTextDocument)
keywords_doc <- tm_map(keywords_doc, stemDocument)
c'est la section bigrams ou tri grammes que vous pouvez utiliser.""
BigramTokenizer <- function(x)
unlist(lapply(ngrams(words(x), 2), paste, collapse = " "), use.names = FALSE)
# creating of document matrix
keywords_matrix <- TermDocumentMatrix(keywords_doc, control = list(tokenize = BigramTokenizer))
# remove sparse terms
keywords_naremoval <- removeSparseTerms(keywords_matrix, 0.95)
# Frequency of the words appearing
keyword.freq <- rowSums(as.matrix(keywords_naremoval))
subsetkeyword.freq <-subset(keyword.freq, keyword.freq >=20)
frequentKeywordSubsetDF <- data.frame(term = names(subsetkeyword.freq), freq = subsetkeyword.freq)
# Sorting of the words
frequentKeywordDF <- data.frame(term = names(keyword.freq), freq = keyword.freq)
frequentKeywordSubsetDF <- frequentKeywordSubsetDF[with(frequentKeywordSubsetDF, order(-frequentKeywordSubsetDF$freq)), ]
frequentKeywordDF <- frequentKeywordDF[with(frequentKeywordDF, order(-frequentKeywordDF$freq)), ]
# Printing of the words
wordcloud(frequentKeywordDF$term, freq=frequentKeywordDF$freq, random.order = FALSE, rot.per=0.35, scale=c(5,0.5), min.freq = 30, colors = brewer.pal(8,"Dark2"))
Espérons que cette aide. C'est un code entier que vous pouvez utiliser.