Hier ist ein Aufruf für eine bessere Möglichkeit, etwas zu tun, die ich bereits ineffizient tun kann: eine Reihe von N-Gramm-Token mit "Stoppwörter" so filtern Das Auftreten eines Stoppwortbegriffs in einem N-Gramm löst die Entfernung aus.Wie man Stoppwörter effizient aus einer Liste von Ngram-Tokens in R
Ich hätte gerne eine Lösung, die sowohl für Unigramme als auch für N-Gramme funktioniert, obwohl es in Ordnung wäre, zwei Versionen zu haben, eine mit einem "fixed" -Flag und eine mit einem "regex" -Flag. Ich stelle die zwei Aspekte der Frage zusammen, da jemand eine Lösung haben kann, die einen anderen Ansatz versucht, der sowohl Stoppwörter für feste als auch reguläre Ausdrücke anspricht.
Formate:
Tokens sind eine Liste von Schriftzeichenvektoren, die durch ein
_
(Unterstrich) Zeichen verkettete Unigramme oder n-Gramm sein kann.Stoppwörter sind ein Zeichenvektor. Im Moment bin ich damit zufrieden, dies eine feste Zeichenfolge zu sein, aber es wäre ein schöner Bonus, dies auch mit regulären Ausdruck-formatierten Stoppwörtern zu implementieren.
gewünschte Ausgabe: Eine Liste von Zeichen, passend zum Eingang Tokens aber mit jeder Komponente Token ein Stoppwort passenden entfernt wird. (Dies bedeutet einen Unigramm-Spiel oder eine Übereinstimmung mit einem der Begriffe, die das n-Gramm enthält.)
Beispiele, Testdaten und der Arbeitscode und Benchmarks aufbauen:
tokens1 <- list(text1 = c("this", "is", "a", "test", "text", "with", "a", "few", "words"),
text2 = c("some", "more", "words", "in", "this", "test", "text"))
tokens2 <- list(text1 = c("this_is", "is_a", "a_test", "test_text", "text_with", "with_a", "a_few", "few_words"),
text2 = c("some_more", "more_words", "words_in", "in_this", "this_text", "text_text"))
tokens3 <- list(text1 = c("this_is_a", "is_a_test", "a_test_text", "test_text_with", "text_with_a", "with_a_few", "a_few_words"),
text2 = c("some_more_words", "more_words_in", "words_in_this", "in_this_text", "this_text_text"))
stopwords <- c("is", "a", "in", "this")
# remove any single token that matches a stopword
removeTokensOP1 <- function(w, stopwords) {
lapply(w, function(x) x[-which(x %in% stopwords)])
}
# remove any word pair where a single word contains a stopword
removeTokensOP2 <- function(w, stopwords) {
matchPattern <- paste0("(^|_)", paste(stopwords, collapse = "(_|$)|(^|_)"), "(_|$)")
lapply(w, function(x) x[-grep(matchPattern, x)])
}
removeTokensOP1(tokens1, stopwords)
## $text1
## [1] "test" "text" "with" "few" "words"
##
## $text2
## [1] "some" "more" "words" "test" "text"
removeTokensOP2(tokens1, stopwords)
## $text1
## [1] "test" "text" "with" "few" "words"
##
## $text2
## [1] "some" "more" "words" "test" "text"
removeTokensOP2(tokens2, stopwords)
## $text1
## [1] "test_text" "text_with" "few_words"
##
## $text2
## [1] "some_more" "more_words" "text_text"
removeTokensOP2(tokens3, stopwords)
## $text1
## [1] "test_text_with"
##
## $text2
## [1] "some_more_words"
# performance benchmarks for answers to build on
require(microbenchmark)
microbenchmark(OP1_1 = removeTokensOP1(tokens1, stopwords),
OP2_1 = removeTokensOP2(tokens1, stopwords),
OP2_2 = removeTokensOP2(tokens2, stopwords),
OP2_3 = removeTokensOP2(tokens3, stopwords),
unit = "relative")
## Unit: relative
## expr min lq mean median uq max neval
## OP1_1 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 100
## OP2_1 5.119066 3.812845 3.438076 3.714492 3.547187 2.838351 100
## OP2_2 5.230429 3.903135 3.509935 3.790143 3.631305 2.510629 100
## OP2_3 5.204924 3.884746 3.578178 3.753979 3.553729 8.240244 100
das Verfahren zur Entfernung in Stoppwörter tm oder qdap ist nicht genug? Obwohl sie in die andere Richtung arbeiten, entfernen Sie zuerst die Stoppwörter und erstellen Sie dann die N-Gramme. – phiver
Nein, das ist einfach genug. Ich versuche, eine effiziente Methode zu finden, um stopword-enthaltende Ngramme nach der Konstruktion zu entfernen. –
Haben Sie das neue Paket von Tyler Rinker, termco auf GitHub ausgecheckt? Das sieht vielversprechend aus. Ich hatte noch keine Zeit es zu überprüfen. – phiver