朴素贝叶斯文本分类在一个类别中失败。为啥? [关闭]

Posted

技术标签:

【中文标题】朴素贝叶斯文本分类在一个类别中失败。为啥? [关闭]【英文标题】:Naive bayes text classification fails in one category. Why? [closed]朴素贝叶斯文本分类在一个类别中失败。为什么? [关闭] 【发布时间】:2013-05-12 04:07:20 【问题描述】:

我正在实现用于文本类别检测的朴素贝叶斯分类器。 我有 37 个类别,我的测试集的准确率约为 36%。

我想提高准确性,所以我决定按照许多来源的建议实现 37 个双向分类器(Ways to improve the accuracy of a Naive Bayes Classifier? 就是其中之一),这些分类器将回答给定的文本:

specific_category OR everything_else

我会通过依次应用它们来确定文本的类别。

但是我的第一个分类器有问题,它总是在“specific_category”类别中失败。

我有训练数据 - 37 个类别,每个类别大小相同的 100 个文档。 对于每个类别,我找到了我根据互信息标准选择的 50 个特征的列表(特征只是单词)。

为了举例,我使用两个类别“农业”和“everything_else”(农业除外)。

对于“农业”类别:

number of words in all documents of this class 
(first term in denominator in http://nlp.stanford.edu/IR-book/pdf/13bayes.pdf, (13.7))
W_agriculture = 31649.

Size of vocabulary V_agriculture = 6951.
Log probability of Unknown word (UNK) P(UNK|agriculture) = -10.56
Log probability of class P(agriculture) = log(1/37) = -3.61 (we have 37 categories of same-size documents)

对于“everything_else”类别:

W_everything_else = 1030043
V_everything_else = 44221
P(UNK|everything_else) = -13.89
P(everything_else) = log(36/37) = -0.03

然后我有一个与农业无关的文本,让它主要由未知词(UNK)组成。它有 270 个单词,对于“农业”和“everything_else”这两个类别,它们大多是未知的。假设“everything_else”有 260 个单词是 UNK,其他 10 个是已知的。

那么,当我计算概率时

P(text|agriculture) = P(agriculture) + SUM(P(UNK|agriculture) for 270 times) 
P(text|everything_else) = P(everything_else) + SUM(P(UNK|everything_else) for 260 times) + SUM(P(word|everything_else) for 10 times)

在最后一行中,我们将 260 个单词计为 UNK,将 10 个单词计为一个类别。

主要问题。由于 P(UNK|agriculture) >> P(everything_else) (对于 log 它更大),这 270 个术语 P(UNK|agriculture) 的影响超过了对文本中每个单词的 P(word|everything_else) 总和的影响. 因为

SUM(P(UNK|agriculture) for 270 times) = -2851.2
SUM(P(UNK|everything_else) for 260 times) = -3611.4

并且第一个总和要大得多,不能用 P(agriculture) 或 SUM(P(word|everything_else) for 10 words) 来纠正,因为差异很大。然后我总是在“农业”类别中失败,尽管文本不属于它。

问题是:我错过了什么吗?或者我应该如何处理大量的 UNK 词并且它们的概率对于小类别来说明显更高?

UPD:尝试将“农业”类别的训练数据(仅将文档连接 36 次)扩大到文档数量相等。它对少数类别有帮助,对其他类别没有多大帮助,我怀疑由于单词数量和字典大小较少,P(UNK|specific_category) 在求和 270 次时变得更大并且超过 P(UNK|everything_else)。

所以看起来这种方法对训练数据中的单词数量和词汇量非常敏感。如何克服这一点?也许二元组/三元组会有所帮助?

【问题讨论】:

您可以尝试 tf-idf 加权,如果您还没有这样做的话。每个类 100 个文档对于单个问题来说是非常少的训练数据,而且使用朴素贝叶斯并不总是一个好主意。 【参考方案1】:

好的,好的。你很困惑,但我会给你一些基本的指示。

首先,即使您遵循 1-vs-all 方案,也不能为不同的课程使用不同的词汇表。如果你这样做,随机变量的事件空间是不同的,所以概率是不可比的。您需要为所有课程确定一个通用词汇表。

其次,扔掉未知令牌。它对你没有帮助。忽略不属于您决定的词汇的任何单词。

最后,我不知道你在用求和概率做什么。我想你对记录日志感到困惑。这个公式不正确:

P(text|agriculture) = P(agriculture) + SUM(P(UNK|agriculture) 270次)

而是:

p(text|agriculture) = p(agriculture) * p(unk|agriculture)^270 * p(doc|agriculture中的所有其他词)

如果你记录日志,就会变成:

log( p(t|a) ) = log(p(agriculture)) + 270*log(p(unk|agriculture)) + log(p(所有其他词|agriculture))

最后,如果您的分类器是正确的,那么没有真正的理由相信 one-vs-all 会比单纯的 n-way 分类更有效。经验上它可能,但理论上它们的结果应该是等价的。在任何情况下,您都不应该按顺序应用决策,而应该做所有 n 个 2-way 问题并分配给正概率最高的类。

【讨论】:

嗨,本,谢谢你的回答!我已经使用了您对常用词汇的建议(我已经将所有类别的所有特征都放在了那里)并且在我的测试数据上获得了 40% 的准确率,在真实数据上获得了 66% 的准确率!我对此非常满意。希望我能尽快写出详细的帖子。关于对数数学 - 感谢您的关心,我也在谈论对数概率,只是没有说清楚。

以上是关于朴素贝叶斯文本分类在一个类别中失败。为啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

朴素贝叶斯文本分类错误结果

我需要提高朴素贝叶斯文本分类的准确性

机器学习算法--朴素贝叶斯

郑捷《机器学习算法原理与编程实践》学习笔记(第二章 中文文本分类—朴素贝叶斯算法)

朴素贝叶斯文本分类简单介绍

Python 中使用朴素贝叶斯进行简单文本分类 - KeyError