bnlearn中的多项朴素贝叶斯,预测澄清

时间:2016-06-18 11:16:11

标签: r

对于大型数据集文本分类问题,我使用了各种分类器,包括LDA,RandomForest,kNN等,准确率达到78-85%。然而,使用bnlearn的Multinomial Naive Bayes给出了97%的准确度。调查了为什么准确度如此之高以及问题似乎与bnlearn中的预测有关 - 也许我使用了错误的参数。

使用示例数据集进行说明。

Long    Sweet   Yellow  Fruit

Yes Yes Yes Banana

Yes Yes Yes Banana

Yes Yes Yes Banana

Yes Yes Yes Banana

No  Yes Yes Banana

No  Yes Yes Orange

No  Yes Yes Orange

No  Yes Yes Orange

Yes Yes Yes Other

No  Yes No  Other

Yes Yes Yes Banana

Yes Yes Yes Banana

Yes No  Yes Banana

Yes No  No  Banana

No  No  Yes Banana

No  No  Yes Orange

No  No  Yes Orange

No  No  Yes Orange

Yes Yes No  Other

No  No  No  Other

Yes Yes Yes Banana

No  Yes Yes Banana

No  Yes Yes Orange

No  Yes Yes Orange

No  Yes No  Other

以上是25行作为数据帧bn.X加载的数据集 这可以分成20行训练数据集和5行测试数据集。

第1步:加载数据

Y=bn.X[,4] # Outcome column
train=1:20
cols=1:4
bn.X[,cols] <- data.frame(apply(bn.X[cols], 2, as.factor))
trainbn.X=bn.X[train,]
testbn.X=bn.X[-train,]
trainbn.Y=Y[train]
testbn.Y=Y[-train]

第2步:使用bnlearn进行分类

library(bnlearn)

NB.fit = naive.bayes(trainbn.X, "Fruit")   

# Prediction    
NB.pred=predict(NB.fit,testbn.X,prob=TRUE)
writeLines("\n Multinomial Naive Bayes\n")
table(NB.pred, testbn.Y)
cat("Accuracy %:", mean(NB.pred == testbn.Y )*100)  

步骤3:使用LDA进行分类

library(MASS)

lda.fit=lda(Fruit~.,data=trainbn.X)

# Prediction
lda.pred=predict(lda.fit,testbn.X)
lda.class=lda.pred$class
writeLines("\n LDA \n")
table(lda.class,testbn.Y)
cat("Accuracy %:", mean(lda.class == testbn.Y )*100)  

bnlearn Naive Bayes和LDA都给出了相同的预测,5行的准确率为80%。

然而,bnlearn似乎也在使用测试行的结果值以及预测。这似乎是我为我正在研究的文本分类场景获得高准确度值的原因。

如果我在预测之前做了以下任何一项,

testbn.X$Fruit=NA
testbn.X$Fruit="Orange"
testbn.X[1:3,]$Fruit="Orange"

对LDA的结果没有影响 - 如果提供,LDA完全忽略测试数据的结果值。这是理想的行为。

然而,对于bnlearn,情况并非如此。 在预测期间,接收到NA的错误并且所有值=&#34;橙&#34; 。对于第三次数据操作,bnlearn预测会返回完全不同的结果

问题: 我使用bnlearn的预测功能的方式对吗?我应该使用不同的参数吗?

1 个答案:

答案 0 :(得分:3)

似乎函数naive.bayes实际上并不适合网络,它只根据提供的数据定义朴素贝叶斯网络的结构。如果您希望执行样本外预测,则需要首先在训练集上使用bn.fit来估算网络参数。

这引起的混淆是因为predict方法接受网络结构 适合的网络作为其{{ 1}}参数。如果object仅是网络结构(例如object返回的对象),则网络参数将根据提供给naive.bayes方法的data进行估算。因此,在您的示例中获得的预测实际上是来自测试数据的样本内预测。来自注释部分下的predict

  

?naive.bayes接受predictbn对象作为其第一个参数。   对于前者,网络的参数适合bn.fit   是,该类标记函数正在尝试的观察结果   预测。

但是,如果提供适合的网络作为data,则拟合的网络参数用于预测,并且object中的training变量的值提供给data predict方法不会影响预测。 (由于某些原因,即使使用适合的网络,NA变量似乎仍然不允许training值。)您可以通过在网络结构中调用bn.fit来获取适合的网络。 bn对象和training_data bn.fit(bn, training_data)

我之前没有使用bnlearn包,但这些是我通过测试和阅读文档得出的结论。以下是我根据您的工作测试行为的一些代码:

# training and testing data
set.seed(1)  # bnlearn uses stochastic tie-breaking
train_idx <- 1:20

train_fruit <- fruit[train_idx, ]
test_fruit <- fruit[-train_idx, ]

library(bnlearn)

nb.net <- naive.bayes(train_fruit, "Fruit")  # network structure
nb.fit <- bn.fit(nb.net, train_fruit)  # fit the network
nb.pred <- predict(nb.fit, test_fruit)  # oos prediction

mean(nb.pred == test_fruit$Fruit)
#    [1] 0.8

# manipulated test data
test_fruit2 <- test_fruit
test_fruit2[1:3, "Fruit"] <- "Orange"

# fitted network as predict object
nb.pred2_fit <- predict(nb.fit, test_fruit2)
identical(nb.pred2_fit, nb.pred)
#    [1] TRUE

# network structure as predict object
nb.pred2_net <- predict(nb.net, test_fruit2)
#     Warning messages:
#     1: In check.data(data, allowed.types = discrete.data.types) :
#       variable Sweet has levels that are not observed in the data.
#     2: In check.data(data, allowed.types = discrete.data.types) :
#       variable Fruit has levels that are not observed in the data.
identical(nb.pred2_net, nb.pred)
#    [1] FALSE

以下是我在示例代码中使用的fruit数据集,从您的帖子中读取:

fruit <- read.table(header = TRUE, text = "
Long    Sweet   Yellow  Fruit
Yes Yes Yes Banana
Yes Yes Yes Banana
Yes Yes Yes Banana
Yes Yes Yes Banana
No  Yes Yes Banana
No  Yes Yes Orange
No  Yes Yes Orange
No  Yes Yes Orange
Yes Yes Yes Other
No  Yes No  Other
Yes Yes Yes Banana
Yes Yes Yes Banana
Yes No  Yes Banana
Yes No  No  Banana
No  No  Yes Banana
No  No  Yes Orange
No  No  Yes Orange
No  No  Yes Orange
Yes Yes No  Other
No  No  No  Other
Yes Yes Yes Banana
No  Yes Yes Banana
No  Yes Yes Orange
No  Yes Yes Orange
No  Yes No  Other
")