Я использую набор данных USCongress из пакета R RTextTools, чтобы поэкспериментировать с классификацией текста с использованием Наивного Байеса. Из полей данных из набора данных USCongress я создаю новый фрейм данных tibble (который я называю congress_df), сохраняя только поля «текст» и «основные», которые я называю «описание» и «класс». Поэтому снимок данных congress_df:
description class
To suspend temporarily the duty on Fast Magenta 2 Stage. 18
To suspend temporarily the duty on Fast Black 286 Stage. 18
To repeal subtitle B of title III of the Gramm-Leach-Bliley Act. 15
To extend the Irish Peace Process Cultural and Training Program. 19
Я написал приведенный ниже код ядра, который, кажется, работает достаточно хорошо, когда я использую наивную байесовскую функцию e1071 - точность 75,28%
library(tidyverse)
library(tidytext)
library(caret)
library(tm)
library(RTextTools)
library(e1071)
data(USCongress, package = "RTextTools")
#Change the data-frame to a tibble data-frame and change the datatype of
#the 'text' field from Factor to Character, and retain only the 'text'
#field and 'major' fields
congress_df <- tibble::as_tibble(USCongress[,c(6, 5)]) %>%
mutate(text = as.character(text))
#Rename columns
colnames(congress_df) <- c("description", "class")
#Create corpus
congress_corpus <- tm::VCorpus(VectorSource(congress_df$description))
#Create document term matrix
congress_dtm <- tm::DocumentTermMatrix(congress_corpus, control =
list(tolower = TRUE,
removeNumbers = TRUE,
stopwords = TRUE,
removePunctuation = TRUE,
stemming = TRUE))
#Remove infrequent terms
min_term_pthreshold <- 0.001 #as a percentage
min_freq <- round(congress_dtm$nrow*min_term_pthreshold, 0)
#Create vector of most frequent words
freq_words <- congress_dtm %>%
tm::findFreqTerms(lowfreq = min_freq)
#Only keep frequent terms
congress_dtm <- congress_dtm[, freq_words]
#Training & Test set
train_split <- 0.8
num_records <- nrow(congress_dtm)
train_records <- floor(num_records * train_split)
test_records <- train_records + 1
congress_dtm_train <- congress_dtm[1 : train_records, ]
congress_dtm_test <- congress_dtm[test_records : num_records, ]
#Training & Test Label
congress_train_labels <- as.factor(congress_df[1 : train_records, ]$class)
congress_test_labels <- as.factor(congress_df[test_records : num_records,
]$class)
convert_values <- function(x) {
x <- ifelse(x > 0, "Yes", "No")
x <- as.factor(x)
}
congress_dtm_train <- apply(congress_dtm_train, MARGIN = 2, convert_values)
congress_dtm_test <- apply(congress_dtm_test, MARGIN = 2, convert_values)
Если я теперь применю функцию naiveBayes из пакета e1071, я получу разумный результат:
congress_classifier <- e1071::naiveBayes(congress_dtm_train,
congress_train_labels)
#Make predictions on test set
congress_test_pred <- predict(congress_classifier, congress_dtm_test)
#Create confusion matrix
confusion_mat <- caret::confusionMatrix(data = congress_test_pred, reference
= congress_test_labels, dnn = c("Prediction", "Actual"))
confusion_mat
Общая статистика
Accuracy : 0.7528
95% CI : (0.7231, 0.7808)
No Information Rate : 0.1607
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.7313
Mcnemar's Test P-Value : NA
Однако, если я попытаюсь применить наивную байесовскую модель из пакета карет, это не сработает. Я пробовал всевозможные варианты следующего:
model <- caret::train(as.matrix(congress_dtm_train),
congress_train_labels,'nb')
или
model <- caret::train(as.matrix(congress_dtm_train),
congress_train_labels,'nb',trControl=trainControl(method='cv',number=10)
Во всех моих попытках я не могу получить каретный подход к работе. В зависимости от того, какие настройки я пытаюсь внести в приведенные выше строки, я получаю разные ошибки, в том числе:
задача 1 не выполнена - "(преобразовано из предупреждения) сбой прогнозов для Resample01: usekernel = TRUE, fL = 0, настройка = 1 Ошибка в data.matrix (newdata):
(преобразовано из предупреждения) НС, введенные по принуждению
задача 1 не выполнена - "(преобразовано из предупреждения) сбой прогнозов для Fold01: usekernel = TRUE, fL = 0, настройка = 1 Ошибка в data.matrix (newdata):
(преобразовано из предупреждения) НС, введенные по принуждению
задача 1 не выполнена - "(преобразовано из предупреждения) не удалось подгонка модели для Fold01: usekernel = FALSE, fL = 1, настройка = FALSE Ошибка в [.default` (x,, 2): нижний индекс вне границ
Хотя я мог бы просто придерживаться подхода e1071, я хочу знать, что не так с подходом Caret, поскольку они оба должны давать одинаковые результаты ??
Кроме того, в целом, кто-нибудь может предложить какие-либо улучшения или модификации моего кода - всегда рады узнать!
Наконец, какие подходы к ОД предложили бы люди, чтобы попытаться улучшить точность? Можно ли получить точность выше, чем, скажем, 85%?