2016-05-02 23 views
2

Ich habe einen Datensatz von BBC Artikel mit zwei Spalten: 'Kategorie' und 'Text'. Ich muss einen naiven Bayes-Algorithmus konstruieren, der die Kategorie (d. H. Geschäft, Unterhaltung) eines Artikels basierend auf dem Typ vorhersagt.Implementieren Naive Bayes für die Textklassifizierung mit Quanteda

Ich versuche, dies mit Quanteda und habe den folgenden Code:

library(quanteda) 

bbc_data <- read.csv('bbc_articles_labels_all.csv') 
text <- textfile('bbc_articles_labels_all.csv', textField='text') 
bbc_corpus <- corpus(text) 
bbc_dfm <- dfm(bbc_corpus, ignoredFeatures = stopwords("english"), stem=TRUE) 


# 80/20 split for training and test data 
trainclass <- factor(c(bbc_data$category[1:1780], rep(NA, 445))) 
testclass <- factor(c(bbc_data$category[1781:2225])) 

bbcNb <- textmodel_NB(bbc_dfm, trainclass) 
bbc_pred <- predict(bbcNb, testclass) 

Es scheint reibungslos zu funktionieren, bis vorhersagen(), das gibt:

Error in newdata %*% log.lik : 
    requires numeric/complex matrix/vector arguments 

Kann jemand gibt einen Einblick darüber, wie um das zu lösen? Ich bekomme immer noch den Dreh für Textanalyse und Quanteda. Vielen Dank!

Here is a link to the dataset.

+0

Sie sollten genügend Daten zur Verfügung stellen, um Ihr Beispiel [reproduzierbar] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) zu machen. Es hat wahrscheinlich etwas mit Ihren Daten zu tun, aber da wir nicht sehen können, dass es unmöglich ist, mit Sicherheit zu sagen. – MrFlick

+0

@MrFlick Ich habe den Post bearbeitet, um einen direkten Link zu der .csv-Datei aufzunehmen. Gibt es zusätzliche Informationen, die ich zur Verfügung stellen sollte? Neu dazu! – Matt

+0

'newdata' das zweite Argument zu' predicate() 'kann kein Faktor sein, der' test class' ist, stattdessen muss es ein dfm sein. Siehe '?? predict.textmodel_NB_fitted'. Wenn deine letzte Zeile "Predicate (bbcNb)" ist, sollte das funktionieren - tut es aber nicht. Anscheinend gibt es einen Fehler in der Vorhersage-Methode, wenn * k *> 2. Bitte reichen Sie ein Problem unter https://github.com/kbenoit/quanteda/issues ein. –

Antwort

4

Als stilistische Note, Sie müssen nicht separat, um die Etiketten/Klassen/Kategorien zu laden, wird das Corpus sie als eine seiner docvars haben:

library("quanteda") 

text <- readtext::readtext('bbc_articles_labels_all.csv', text_field='text') 
bbc_corpus <- corpus(text) 
bbc_dfm <- dfm(bbc_corpus, remove = stopwords("english"), stem = TRUE) 

all_classes <- docvars(bbc_corpus)$category 
trainclass <- factor(replace(all_classes, 1780:length(all_classes), NA)) 
bbcNb <- textmodel_nb(bbc_dfm, trainclass) 

Sie don‘ t muss sogar ein zweites Argument für predict angeben. Wenn Sie dies nicht tun, wird es die ganze ursprüngliche DFM verwenden:

bbc_pred <- predict(bbcNb) 

Schließlich können Sie die Vorhersagegenauigkeit bewerten wollen. Dies gibt Ihnen einen Überblick über die Entwicklung des Modells auf dem Test-Set:

library(caret) 

confusionMatrix(
    bbc_pred$docs$predicted[1781:2225], 
    all_classes[1781:2225] 
) 

Doch wie @ ken-benoit erwähnt, gibt a bug in quanteda ist die Vorhersage verhindert mit mehr als zwei Klassen von der Arbeit. Bis das fest ist, könnten Sie die Klassen mit so etwas wie Binarisierung:

docvars(bbc_corpus)$category <- factor(
    ifelse(docvars(bbc_corpus)$category=='sport', 'sport', 'other') 
) 

(beachten Sie, dass dies getan werden muss, bevor man all_classes aus bbc_corpus oben extrahieren).

+1

Fehler behoben in 0.9.6. Funktioniert jetzt. –