使用Quanteda实现朴素贝叶斯进行文本分类

时间:2016-05-02 03:56:52

标签: r quanteda

我有一个BBC文章的数据集,其中有两列:'category'和'text'。我需要构建一个朴素贝叶斯算法,该算法根据类型预测文章的类别(即商业,娱乐)。

我正在尝试使用Quanteda并使用以下代码:

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)

似乎工作顺利,直到predict(),这给出了:

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

任何人都可以提供有关如何解决此问题的见解吗?我仍然掌握文本分析和quanteda。谢谢!

Here is a link to the dataset.

1 个答案:

答案 0 :(得分:4)

作为一种风格说明,您不需要单独加载标签/类/类别,语料库会将它们作为docvars之一:

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)

您甚至不需要为predict指定第二个参数。如果你不这样做,它将使用整个原始dfm:

bbc_pred <- predict(bbcNb)

最后,您可能想要评估预测准确性。这将为您提供模型在测试集上的性能摘要:

library(caret)

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

然而,正如@ ken-benoit所指出的那样,a bug in quanteda会阻止预测使用两个以上的类。在修复之前,您可以使用以下内容对类进行二值化:

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

(请注意,必须在从all_classes上方提取bbc_corpus之前完成此操作。