gpt4 book ai didi

r - Quanteda 中的朴素贝叶斯与插入符号 : wildly different results

转载 作者:行者123 更新时间:2023-12-03 02:42:00 25 4
gpt4 key购买 nike

我正在尝试结合使用 quantedacaret 包来根据训练样本对文本进行分类。作为测试运行,我想将 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%。

最佳答案

答案是 caret (使用 naivebayes 包中的 naive_bayes )假设高斯分布,而 quanteda::textmodel_nb() 则采用高斯分布。基于更适合文本的多项分布(也可以选择伯努利分布)。

textmodel_nb() 的文档复制了 IIR 书中的示例(Manning、Raghavan 和 Schütze 2008),并且还引用了 Jurafsky 和 ​​Martin(2018)的进一步示例。请参阅:

另一个包 e1071 产生的结果与您发现的结果相同,因为它也基于高斯分布。

library("e1071")
nb_e1071 <- naiveBayes(x = training_m,
y = as.factor(docvars(training_dfm, "Sentiment")))
nb_e1071_pred <- predict(nb_e1071, newdata = test_m)
table(actual_class, nb_e1071_pred)
## nb_e1071_pred
## actual_class neg pos
## neg 246 3
## pos 249 2

然而,carete1071 都适用于稠密矩阵,这也是它们与 quanteda 方法相比慢得令人 NumPy 的原因之一它在稀疏 dfm 上运行。因此,从分类器的适当性、效率和(根据您的结果)性能的角度来看,应该非常清楚哪个是首选!

library("rbenchmark")
benchmark(
quanteda = {
nb_quanteda <- textmodel_nb(training_dfm, docvars(training_dfm, "Sentiment"))
predicted_class <- predict(nb_quanteda, newdata = test_dfm)
},
caret = {
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 = FALSE)
predicted_class_caret <- predict(nb_caret, newdata = test_m)
},
e1071 = {
nb_e1071 <- naiveBayes(x = training_m,
y = as.factor(docvars(training_dfm, "Sentiment")))
nb_e1071_pred <- predict(nb_e1071, newdata = test_m)
},
replications = 1
)
## test replications elapsed relative user.self sys.self user.child sys.child
## 2 caret 1 29.042 123.583 25.896 3.095 0 0
## 3 e1071 1 217.177 924.157 215.587 1.169 0 0
## 1 quanteda 1 0.235 1.000 0.213 0.023 0 0

关于r - Quanteda 中的朴素贝叶斯与插入符号 : wildly different results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54427001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com