我使用scikit-learn的多项式朴素贝叶斯分类器进行二元文本分类(分类器告诉我文档是否属于类别X)。我使用平衡数据集来训练模型,并使用平衡测试集进行测试,结果非常 promising。
这个分类器需要实时运行,并不断分析随机输入的文档。
然而,当我在生产环境中运行分类器时,误报率非常高,因此我的精确度非常低。原因很简单:在实时场景中,分类器遇到的负样本数量要多得多(约90%的时间),这与我用于测试和训练的理想平衡数据集不符。
有没有办法在训练过程中模拟这种实时情况,或者有什么技巧可以使用(包括对文档进行预处理,以查看它们是否适合分类器)?
我计划使用与实时情况相同比例的不平衡数据集来训练我的分类器,但我担心这可能会使朴素贝叶斯偏向负类,从而失去我在正类上的召回率。
任何建议都将不胜感激。
回答:
你遇到了类分布高度不平衡的分类问题之一。我必须不同意那些认为问题出在朴素贝叶斯方法上的人,我将提供一个解释,希望能说明问题所在。
假设你的误报率为0.01,真阳性率为0.9。这意味着你的漏报率为0.1,真阴性率为0.99。
想象一个理想化的测试场景,你有来自每个类的100个测试案例。你将得到(预期中)1个误报和90个真阳性。太棒了!在你的正类上,精确度是90 / (90+1)!
现在想象负例比正例多1000倍。测试时仍有100个正例,但现在有1000000个负例。你现在得到相同的90个真阳性,但(0.01 * 1000000)= 10000个误报。灾难!你的精确度现在几乎为零(90 / (90+10000))。
这里的重点是,分类器的性能没有改变;误报和真阳性率保持不变,但平衡发生了变化,你的精确度因此急剧下降。
如何解决这个问题更难。如果你的分数是可分的但阈值不对,你应该查看基于后验概率的ROC曲线,看看是否有你想要的性能的地方。如果你的分数不可分,尝试多种不同的分类器,看看是否能找到一个它们是可分的(逻辑回归几乎是朴素贝叶斯的直接替代品;然而,你可能想尝试一些非线性分类器,比如神经网络或非线性SVM,因为你经常可以得到非线性边界来划分一个非常小的类的空间)。
要从平衡测试集中模拟这种效果,你可以简单地在列联表中将实例计数乘以适当的乘数(例如,如果你的负类是正类的10倍大小,使测试中的每个负实例在列联表中增加10个计数而不是1)。
我希望这至少对你理解所面临的问题有所帮助。