R 插入符号朴素贝叶斯(未调整)结果与 klaR 不同

机器算法验证 r 机器学习 插入符号 e1071
2022-04-08 07:11:15

我正在运行一个朴素贝叶斯分类模型,我注意到插入符号包返回的结果与 klaR(插入符号引用)或 e1071 不同。

我的问题是:我的插入符号语法是否有问题,我无法恢复与 klaR(或 e1071)相同的结果?

请注意,我在插入符号中运行了一个未调整的模型,并为它提供了与我提供给 klaR 的相同规格(usekernal = FALSE 和 fL = 0)。

在下面的示例中,e1071 和 klaR 返回相同的混淆矩阵(这是有道理的,因为 klaR 基于 e1071 但添加了内核和拉普拉斯平滑器,我已在此处禁用)。奇怪的是,当 caret 被要求运行与 klaR 模型具有相同规格的未调整模型时,结果很接近但不完全相同,但我希望结果与 klaR 相同。

这是一个可重现的示例:

# Load Libraries
library(kernlab); #for spam data
library(caret)
library(e1071)
library(klaR)

# Load Data
data(spam)

# e1071 naiveBayes
set.seed(3456)
fit1 <- naiveBayes(spam, spam$type, type="raw")
    pred1 <- predict(fit1, spam, type="class")
    confusionMatrix(pred1, spam$type)

# klaR NaiveBayes
set.seed(3456)
fit2 <- NaiveBayes(spam, spam$type, usekernal = FALSE, fL = 0)
    pred2 <- predict(fit2, spam)
    #Warnings that probability is 0 for some cases
    confusionMatrix(pred2$class, spam$type)

# caret with no tuning, usekernal = FALSE, fL = 0
set.seed(3456)
fit3 <- train(type ~ ., 
         data=spam,
         method = "nb",
         trControl = trainControl(method="none"),
         tuneGrid = data.frame(fL=0, usekernel=FALSE))

pred3 <- predict(fit3, spam, type="raw")
#Warnings that probability is 0 for some cases
confusionMatrix(pred3, spam$type)

以下是从混淆矩阵中选择的输出。

对于 e1071:

Accuracy : 0.7266
Sensitivity : 0.5814          
Specificity : 0.9498         

对于克拉:

Accuracy : 0.7266
Sensitivity : 0.5814          
Specificity : 0.9498 

对于插入符号:

Accuracy : 0.7135
Sensitivity : 0.5610          
Specificity : 0.9482 

非常感谢有关为什么会发生这种情况以及我可以做些什么(如果有的话)的任何信息。

谢谢!

编辑:以防万一这有帮助,来自 sessionInfo()

R version 3.2.2 (2015-08-14)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8 x64 (build 9200)

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] klaR_0.6-12     MASS_7.3-45     e1071_1.6-7     caret_6.0-58    ggplot2_1.0.1   lattice_0.20-33 kernlab_0.9-22 

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.1        magrittr_1.5       splines_3.2.2      munsell_0.4.2      colorspace_1.2-6   foreach_1.4.3     
 [7] minqa_1.2.4        stringr_1.0.0      car_2.1-0          plyr_1.8.3         tools_3.2.2        parallel_3.2.2    
[13] nnet_7.3-11        pbkrtest_0.4-2     grid_3.2.2         gtable_0.1.2       nlme_3.1-122       mgcv_1.8-7        
[19] quantreg_5.19      class_7.3-14       MatrixModels_0.4-1 iterators_1.0.8    lme4_1.1-10        digest_0.6.8      
[25] Matrix_1.2-2       nloptr_1.0.4       reshape2_1.4.1     codetools_0.2-14   stringi_1.0-1      scales_0.3.0      
[31] combinat_0.0-8     stats4_3.2.2       SparseM_1.7        proto_0.3-10  
3个回答

问题在于您在模型中使用了不同的规范。在 fit1 和 fit2 中,您使用 x 和 y 组合,在 fit3 中使用公式表示法

如果您在公式符号中切换所有模型(类型 ~ ., data = spam),您将看到 0.7135 的准确度

如果您以 x / y 表示法(垃圾邮件、垃圾邮件类型)切换所有模型,您将看到 0.7266 的准确度

可能有人可以解释为什么会发生这种差异。我不知道,除了它与 S3 公式符号的处理方式与 x 和 y 的默认符号的区别有关。

据我所知,对于前两个模型,您不应该将整个垃圾邮件数据框作为训练变量(在这种情况下,类标签被视为一个特征)。相反,您应该使用:

fit1 <- naiveBayes(spam[,-58], spam$type, type="raw")

这样,它将产生与 相同的结果(type ~., data=spam)

不同之处在于 x 是否包括包含类变量的完整矩阵,或者 y 是否专门从 x 中排除。

# y included in x -> Accuracy : 0.7266

fit3 <- train(
   x=spam,
   y=spam$type,
   method = "nb",
   trControl = trainControl(method="none"),
   tuneGrid = data.frame(usekernel=FALSE,fL=0,adjust=FALSE))

pred3 <- predict(fit3, spam, type="raw")
#Warnings that probability is 0 for some cases
confusionMatrix(pred3, spam$type)
#Accuracy : 0.7266

不同于:

# y excluded from x -> #Accuracy : 0.7135

fit3 <- train(
   x=spam[,-dim(spam)[2]],
   y=spam$type,
   method = "nb",
   trControl = trainControl(method="none"),
   tuneGrid = data.frame(usekernel=FALSE,fL=0,adjust=FALSE))

pred3 <- predict(fit3, spam, type="raw")
#Warnings that probability is 0 for some cases
confusionMatrix(pred3, spam$type)
#Accuracy : 0.7135