2016-04-14 22 views
1

Ich möchte zwei Buchstaben Akronyme in meiner Unigramm Häufigkeit Tabelle, die durch Perioden wie "t.v." getrennt sind beibehalten und wir.". Wenn ich meine Unigramm-Häufigkeitstabelle mit Quanteda baue, wird die Teminationszeit abgeschnitten. Hier ist ein kleiner Testkorpus zur Veranschaulichung. Ich habe Perioden als Satztrennzeichen entfernt:Wie behalte ich Intra-Word-Perioden in Unigrammen? R quanteda

SOS This is the u.s. where our politics is crazy EOS

SOS In the US we watch a lot of t.v. aka TV EOS

SOS TV is an important part of life in the US EOS

SOS folks outside the u.s. probably don't watch so much t.v. EOS

SOS living in other countries is probably not any less crazy EOS

SOS i enjoy my sanity when it comes to visit EOS

, die ich in R als Zeichenvektor laden:

acro.test <- c("SOS This is the u.s. where our politics is crazy EOS", "SOS In the US we watch a lot of t.v. aka TV EOS", "SOS TV is an important part of life in the US EOS", "SOS folks outside the u.s. probably don't watch so much t.v. EOS", "SOS living in other countries is probably not any less crazy EOS", "SOS i enjoy my sanity when it comes to visit EOS") 

Hier ist der Code, den ich meine Unigramm- Frequenztabelle zu bauen verwenden:

library(quanteda) 
dat.dfm <- dfm(acro.test, ngrams=1, verbose=TRUE, concatenator=" ", toLower=FALSE, removeNumbers=TRUE, removePunct=FALSE, stopwords=FALSE) 
dat.mat <- as.data.frame(as.matrix(docfreq(dat.dfm))) 
ng.sorted <- sort(rowSums(dat.mat), decreasing=TRUE) 
freqTable <- data.frame(ngram=names(ng.sorted), frequency = ng.sorted) 
row.names(freqTable) <- NULL 
freqTable 

Dies ergibt folgendes:

 ngram frequency 
1  SOS   6 
2  EOS   6 
3  the   4 
4   is   3 
5   .   3 
6  u.s   2 
7  crazy   2 
8   US   2 
9  watch   2 
10  of   2 
11  t.v   2 
12  TV   2 
13  in   2 
14 probably   2 
15  This   1 
16  where   1 
17  our   1 
18 politics   1 
19  In   1 
20  we   1 
21   a   1 
22  lot   1 
23  aka   1 

etc ...

Ich würde gerne t behalten Die Terminalzeiträume am t.v. und wir. sowie eliminieren Sie den Eintrag in der Tabelle für. mit einer Frequenz von 3.

Ich verstehe auch nicht, warum die Periode (.) eine Zählung von 3 in dieser Tabelle haben würde, während die u.s und t.v Unigramme richtig gezählt werden (je 2).

Antwort

2

Der Grund für dieses Verhalten ist, dass quanteda ‚s Standardwort tokeniser die ICU-basierte verwendet Definition für Grenzen Wort (vom stringi Paket). u.s. erscheint als das Wort u.s. gefolgt von einem Zeitraum . Token. Das ist toll, wenn Ihr Name will.i.am ist, aber vielleicht nicht so toll für Ihre Zwecke. Aber Sie können leicht zum White-Space-Tokeniser wechseln, indem Sie das Argument what = "fasterword" an tokens() übergeben, eine Option, die in dfm() über den ...-Teil des Funktionsaufrufs verfügbar ist.

tokens(acro.test, what = "fasterword")[[1]] 
## [1] "SOS"  "This"  "is"  "the"  "u.s."  "where" "our"  "politics" "is"  "crazy" "EOS" 

Sie hier das sehen können, ist u.s. erhalten. Als Antwort auf Ihre letzte Frage hatte das Terminal . eine Dokumenthäufigkeit von 3, weil es in drei Dokumenten als ein separates Token erschien, welches das Standard-Tokeniser-Verhalten ist, wenn remove_punct = FALSE.

Um dies durch zu dfm() und dann erstellen Sie Ihre Daten.Frame der Dokumenthäufigkeit der Wörter, funktioniert der folgende Code (Ich habe es ein wenig für Effizienz aufgeräumt). Beachten Sie den Kommentar zum Unterschied zwischen Dokument- und Termhäufigkeit. Ich habe festgestellt, dass einige Benutzer etwas verwirrt sind über docfreq().

# I removed the options that were the same as the default 
# note also that stopwords = TRUE is not a valid argument - see remove parameter 
dat.dfm <- dfm(acro.test, tolower = FALSE, remove_punct = FALSE, what = "fasterword") 

# sort in descending document frequency 
dat.dfm <- dat.dfm[, names(sort(docfreq(dat.dfm), decreasing = TRUE))] 
# Note: this would sort the dfm in descending total term frequency 
#  not the same as docfreq 
# dat.dfm <- sort(dat.dfm) 

# this creates the data.frame in one more efficient step 
freqTable <- data.frame(ngram = featnames(dat.dfm), frequency = docfreq(dat.dfm), 
         row.names = NULL, stringsAsFactors = FALSE) 
head(freqTable, 10) 
## ngram frequency 
## 1 SOS   6 
## 2 EOS   6 
## 3 the   4 
## 4  is   3 
## 5 u.s.   2 
## 6 crazy   2 
## 7  US   2 
## 8 watch   2 
## 9  of   2 
## 10 t.v.   2 

Meiner Ansicht der genannte Vektor von docfreq() auf der DFM hergestellt ist ein effizienteres Verfahren für die Ergebnisse als Ihre data.frame Ansatz zu speichern, aber Sie können auch andere Variablen hinzufügen möchten.

+1

Perfekt. Das war genau das, wonach ich gesucht habe. Gute Bearbeitung für den Titel. Danke für die gründliche Antwort und für die großartige Arbeit an diesem Paket. –