Я пытаюсь использовать пакеты quanteda
и caret
вместе, чтобы классифицировать текст на основе обученного образца.В качестве тестового прогона я хотел сравнить встроенный наивный байесовский классификатор quanteda
с теми, что в caret
.Однако я не могу заставить caret
работать правильно.
Вот код для воспроизведения.Сначала на стороне quanteda
:
library(quanteda)
library(quanteda.corpora)
library(caret)
corp <- data_corpus_movies
set.seed(300)
id_train <- sample(docnames(corp), size = 1500, replace = FALSE)
# get training set
training_dfm <- corpus_subset(corp, docnames(corp) %in% id_train) %>%
dfm(stem = TRUE)
# get test set (documents not in id_train, make features equal)
test_dfm <- corpus_subset(corp, !docnames(corp) %in% id_train) %>%
dfm(stem = TRUE) %>%
dfm_select(pattern = training_dfm,
selection = "keep")
# train model on sentiment
nb_quanteda <- textmodel_nb(training_dfm, docvars(training_dfm, "Sentiment"))
# predict and evaluate
actual_class <- docvars(test_dfm, "Sentiment")
predicted_class <- predict(nb_quanteda, newdata = test_dfm)
class_table_quanteda <- table(actual_class, predicted_class)
class_table_quanteda
#> predicted_class
#> actual_class neg pos
#> neg 202 47
#> pos 49 202
Неплохо.Точность составляет 80,8% без настройки.Теперь то же самое (насколько я знаю) в caret
training_m <- convert(training_dfm, to = "matrix")
test_m <- convert(test_dfm, to = "matrix")
nb_caret <- train(x = training_m,
y = as.factor(docvars(training_dfm, "Sentiment")),
method = "naive_bayes",
trControl = trainControl(method = "none"),
tuneGrid = data.frame(laplace = 1,
usekernel = FALSE,
adjust = FALSE),
verbose = TRUE)
predicted_class_caret <- predict(nb_caret, newdata = test_m)
class_table_caret <- table(actual_class, predicted_class_caret)
class_table_caret
#> predicted_class_caret
#> actual_class neg pos
#> neg 246 3
#> pos 249 2
Мало того, что точность здесь ужасна (49,6% - примерно вероятность), класс pos вряд ли когда-либо будет предсказан вообще!Так что я почти уверен, что упускаю что-то важное здесь, так как я предполагаю, что реализации должны быть довольно похожими, но не уверен, что.
Я уже посмотрел исходный код для функции quanteda
(надеясь, что это может быть построено на caret
или базовом пакете, в любом случае) и увидит, что происходит некоторое взвешивание и сглаживание.Если я применил то же самое к своему dfm перед тренировкой (установив laplace = 0
позже), точность будет немного лучше.Еще только 53%.