【问题标题】:Bug in R e1071 Naive Bayes?R e1071 朴素贝叶斯中的错误?
【发布时间】:2014-11-12 04:53:45
【问题描述】:

我在 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 变平,并且您可以观察到如果您这样做的程度足以使一两个实际上倾向于占主导地位(在这种情况下是红色和黑色) .

太糟糕了,我们不能利用标准差对所有这些都相同的知识。

如果你在平均值上添加一点噪音,它会变得更加均匀分布,即使仍然存在一些错误分类。

【问题讨论】:

    标签: r machine-learning classification


    【解决方案1】:

    问题不是naiveBayes,而是你的getMostFrequentPrediction 函数。即使第一个有关系,您也只返回一个值。由于您使用的是table(),因此计数在表中按字母顺序隐式排序。因此,当您获取第一个最大值时,它也将是按字母顺序排列的“最小”值。因此,如果您多次对此进行催款:

    getMostFrequentPrediction(data.frame(predictions=sample(rep(letters[1:3], 5))))
    

    您将总是得到“a”,即使字母“a”、“b”和“c”都出现了 5 次。

    如果您想随机选择最常预测的类别之一,这是另一种可能的实现

    getMostFrequentPrediction = function(labeledFrame){
        tt<-table(labeledFrame$predictions)
        names(sample(tt[tt==max(tt)], 1))
    }
    

    这给了

    【讨论】:

    • 你对平局的看法确实是正确的。感谢您指出了这一点!我正在尝试重新创建工作中发生的事情,可以通过更改标签来更改主要预测,但也许我在吠叫错误的树......
    • 你有什么解释为什么删除 100*i (即给所有标签相同的分布)会消除这种平局的影响?我认为对 a 和 b 之类的字母仍然会有一些偏见,但从我的第二个情节和进一步的修补来看,没有。
    • 当你给它们所有这些不同的分布时(平均 =100*i, sd=10),它们几乎不会重叠,因此类别更容易区分。你的预测几乎是完美的,所以你有很多联系。完全重叠(平均 =100, sd=10 为所有),你得到更少的联系,所以不会发生同样的问题。
    • 哦,谢谢。还有一件事:在相同分布下,我正在经历预测中似乎很高的“聚集”。我做了 200 次“doExperiments”,在 5 个班级中有 100 次观察,发现平均预测最少的班级有 1.1 次观察,6.3 次之少,...,预测最多的班级(5 个)有 46.4 行与之相关一般。事实上,在 70% 的情况下,一个类根本没有得到 no 预测。 (我认为放置一个“print(tt)”并重新运行代码会给你这个想法)。这似乎很奇怪......
    • 没关系,我已经掌握了它。用图表查看我对原始问题的更新。谢谢!
    猜你喜欢
    • 2016-06-23
    • 1970-01-01
    • 2013-06-23
    • 2015-12-20
    • 2012-11-10
    • 2012-02-21
    • 2011-12-28
    • 2018-12-07
    • 2013-11-24
    相关资源
    最近更新 更多