朴素贝叶斯:不平衡测试数据集

我使用scikit-learn Multinomial朴素贝叶斯分类器进行二进制文本分类(分类器告诉我文档是否属于X类别)。 我使用一个平衡的数据集来训练我的模型和一个平衡的测试集来测试它,结果非常有希望。

这个分类器需要实时运行并不断分析随机抛出的文档。

然而,当我在生产中运行分类器时,误报数量非常高,因此我的精度非常低。 原因很简单:分类器在实时场景中遇到了更多的负面样本(大约90%的时间),这不符合用于测试和训练的理想平衡数据集。

有没有一种方法可以在训练期间模拟此实时案例,或者有什么技巧可以使用(包括对文档进行预处理以查看它们是否适合分类器)?

我计划使用与实时情况下相同比例的不平衡数据集来训练分类器,但我恐怕可能会将朴素贝叶斯偏向负面课程,并且会失去对正面课程的回忆。

任何建议表示赞赏。


您遇到了分类问题中存在的高度不平衡类分布问题之一。 我不同意那些说朴素贝叶斯方法存在问题的人,我会提供一个解释,希望能够说明问题所在。

假设你的假阳性率是0.01,你的真阳性率是0.9。 这意味着你的假阴性率是0.1,你的真阴率是0.99。

设想一个理想化的测试场景,您可以从每个课程中获得100个测试用例。 你会得到(预期)1个假阳性和90个真阳性。 大! 正面课程的精确度为90 /(90 + 1)!

现在想象有1000倍以上的负面例子。 测试中有100个正面例子,但现在有100万个负面例子。 你现在得到相同的90个真正的肯定,但(0.01 * 1000000)= 10000误报。 灾害! 您的精度现在几乎为零(90 /(90 + 10000))。

这里的要点是分类器的性能没有改变; 假阳性和真阳性率保持不变,但余额发生变化,导致您的精确度下降。

该怎么办比较困难。 如果您的分数是可分的但阈值是错误的,您应该根据后验概率查看ROC曲线的阈值,并查看是否有某个地方能够获得您想要的性能。 如果您的分数不可分,请尝试使用一堆不同的分类器,看看您是否可以获得它们(逻辑回归几乎是朴素贝叶斯的替代品;您可能想要试验一些非线性分类器,然而,像神经网络或非线性支持向量机一样,通常会以非线性边界结束,描绘一个非常小的类的空间)。

为了从平衡测试集中模拟这种效应,您可以简单地将实例计数乘以适应表中的适当乘数(例如,如果您的否定类是正数的10倍,则使测试中的每个否定实例都添加10个计数应急表而不是1)。

我希望这至少能帮助你理解你面临的问题。


正如@Ben Allison所说,您面临的问题基本上是您的分类器的准确性不够好 - 或者更具体地说:它的错误肯定率对于它所分类的分类分布来说太高。

“教科书”解决方案确实是使用均衡训练集来训练分类器,获得“好”分类器,然后在分类器的性能曲线(例如ROC曲线)上找到一个能够在您的精度要求之间达到最佳平衡的点; 我认为在你的情况下,它会偏向于较低的假阳性率和较高的假阴性率。

然而,情况很可能是分类器对您的要求不够好 - 在误报处于合理水平的时候,您可能会错过太多好的案例。

一个解决方案当然是使用更多的数据,或尝试另一种类型的分类器; 例如线性/逻辑回归或SVM,其在文本分类中通常具有良好的性能。

话虽如此,这种情况可能是因为某些原因(例如,列车时间限制,频繁添加新班级或预先存在的模型),您更喜欢使用朴素贝叶斯。 在这种情况下,我可以就可以做些什么提供一些实用建议。

  • 假设您已经有了构建朴素贝叶斯分类器的工作流程,那么您可能需要考虑Boosting。 一般来说,这些方法会以一种更强大的分类器的方式训练几个较弱的分类器。 提高朴素贝叶斯分类器已被证明很好地工作,例如见这里。 一个相当大的和干净的火车集将取得最好的结果。
  • 另一个实用且简单的解决方案(尽管不那么“美观”)将是在现有分类器之后添加具有阈值的简单二项式朴素贝叶斯分类器的另一层 - 实质上是“关键字”过滤器,其将仅输出文档的正面文档至少包含给定字典中的n个单词(您还可以允许一些单词被计数多次)。 根据您的问题域,可能需要手动构建这样的字典。 经过一些试验和错误之后,我看到这种方法显着提高了假阳性率,而只是轻微地损害了假阴性。

  • 我认为gustavodidomenico是一个很好的观点。 您可以将朴素贝叶斯视为学习概率分布,在这种情况下属于主题的单词。 所以训练数据的平衡很重要。 如果你使用决策树,比如说一个随机森林模型,你就会学习做出这个任务的规则(是的,涉及到概率分布,我为挥手解释道歉,但有时直觉有帮助)。 出于这个原因,在许多情况下,树比朴素贝叶斯更稳健。

    链接地址: http://www.djcxy.com/p/40155.html

    上一篇: Naive Bayes: Imbalanced Test Dataset

    下一篇: Is Big Oh the only notation used to measure complexity in STL