我没有R社区的经验,所以如果这不是合适的论坛,请指向其他地方...
长话短说,恐怕e1071::naiveBayes
倾向于按字母顺序给标签。
在更早的问题here中,我注意到在朴素贝叶斯的e1071
实现中,数值预测变量有一些奇怪的行为。当我得到一个更合理的答案时,某些概率似乎有偏差。
谁能阐明为什么这种模拟最终会如此?我只能想象这是一个错误。
library(e1071)
# get a data frame with numObs rows, and numDistinctLabels possible labels
# each label is randomly drawn from letters a-z
# each label has its own distribution of a numeric variable
# this is normal(i*100, 10), i in 1:numDistinctLabels
# so, if labels are t, m, and q, t is normal(100, 10), m is normal(200, 10), etc
# the idea is that all labels should be predicted just as often
# but it seems that "a" will be predicted most, "b" second, etc
doExperiment = function(numObs, numDistinctLabels){
possibleLabels = sample(letters, numDistinctLabels, replace=F)
someFrame = data.frame(
x=rep(NA, numObs),
label=rep(NA, numObs)
)
numObsPerLabel = numObs / numDistinctLabels
for(i in 1:length(possibleLabels)){
label = possibleLabels[i]
whichAreNA = which(is.na(someFrame$label))
whichToSet = sample(whichAreNA, numObsPerLabel, replace=F)
someFrame[whichToSet, "label"] = label
someFrame[whichToSet, "x"] = rnorm(numObsPerLabel, 100*i, 10)
}
someFrame = as.data.frame(unclass(someFrame))
fit = e1071::naiveBayes(label ~ x, someFrame)
# The threshold argument doesn't seem to change the matter...
someFrame$predictions = predict(fit, someFrame, threshold=0)
someFrame
}
# given a labeled frame, return the label that was predicted most
getMostFrequentPrediction = function(labeledFrame){
names(which.max(sort(table(labeledFrame$prediction))))
}
# run the experiment a few thousand times
mostPredictedClasses = sapply(1:2000, function(x) getMostFrequentPrediction(doExperiment(100, 5)))
# make a bar chart of the most frequently predicted labels
plot(table(mostPredictedClasses))
这给出了如下图:
赋予每个标签相同的正态分布(即均值100,标准差10)可得出:
关于评论混乱:
这也许正在远离这里的Stack Overflow领域,但是无论如何...
虽然我希望分类不太笨拙,但是标准偏差的影响确实使pdf趋于平坦,您可以观察到这样做是否足以使一到两个实际上占主导地位(在这种情况下为红色和黑色) 。
遗憾的是,我们无法利用所有标准偏差都相同的知识。
如果只添加一点噪声,即使仍然存在一些错误分类,它也会变得分布更加均匀。
最佳答案
问题不是naiveBayes
,是您的getMostFrequentPrediction
函数。即使有第一个联系,您也只返回一个值。由于使用的是table()
,因此将在表中按字母顺序对计数进行隐式排序。因此,当您获得第一个最大值时,按字母顺序也将是“最小”值。因此,如果您多次这样做:
getMostFrequentPrediction(data.frame(predictions=sample(rep(letters[1:3], 5))))
即使字母“ a”,“ b”和“ c”都出现5次,您仍将始终获得“ a”。
如果您想随机选择预测最频繁的类别之一,这是另一种可能的实现方式
getMostFrequentPrediction = function(labeledFrame){
tt<-table(labeledFrame$predictions)
names(sample(tt[tt==max(tt)], 1))
}
这给