R e1071 Naive Bayes中的错误?

时间:2014-09-18 01:10:48

标签: r machine-learning classification

我没有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))

这给出了如下情节:

enter image description here

给每个标签提供相同的正态分布(即平均值100,stdev 10)给出:

enter image description here

关于评论中的混淆:

这可能在这里远离Stack Overflow领域,但无论如何...... 虽然我希望分类不那么块,但是标准偏差的影响对于平坦化pdf很有帮助,你可以观察一下你是否做到这一点足以使一两个实际上倾向于占主导地位(在这种情况下是红色和黑色)

enter image description here

太糟糕了,我们无法利用所有标准偏差相同的知识。

如果你只是在平均值上加一点噪音就会变得更加均匀分布,即使还有一些错误分类。

enter image description here

1 个答案:

答案 0 :(得分:1)

问题不是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))
}

这给出了

enter image description here