我需要在学校演示贝叶斯垃圾邮件过滤器。
要做到这一点,我想用GUI编写一个小型Java应用程序(这不是问题)。
在开始编写代码之前,我只是想确保我真正掌握了过滤器的概念。所以我将描述我将要构建的内容以及我将如何编程,如果你能给出一个"竖起大拇指,我将非常感激。或者"大拇指向下"。
请记住:这是一个简短的演示文稿,只是为了演示。它不一定是高性能或其他东西;)
我想这个节目有2个textareas。
在第一篇文章中,我想输入一个文本,例如
"快速的棕色狐狸跳过懒狗"
然后我希望在这个字段下有两个按钮" good"或者"坏"。
当我按下其中一个按钮时,程序会计算每个部分中每个单词的外观。
例如,当我输入以下文字时:
"你好,伟哥" |坏
"你好,你好吗? |好
"你好药物伟哥" |坏
对于单词,我不知道我假设概率为0.5
我的"数据库"然后看起来像这样:
<word>, <# times word appeared in bad message>
hello, 2
you, 1
viagra, 2
how, 0
are, 0
drugs, 1
在第二个textarea中,我想输入一个文本来评估它是否是好的&#34;或者&#34;坏&#34;。
例如:
&#34;你好,伟哥如何销售&#34;
然后算法将整个文本分开,并查找每个单词的概率出现在&#34;坏&#34;消息。
现在这就是我被困的地方:
如果我计算一个单词出现在坏消息中的概率#次出现在坏消息中/#次出现在所有消息中,则上述文本将有0个概率属于任何类别,因为:< / p>
当我现在乘以单个概率时,在两种情况下都会给出0。
请你解释一下,我如何计算单个词的概率&#34; good&#34;或者&#34;坏&#34;?
致以最诚挚的问候和许多感谢 我
答案 0 :(得分:2)
对于看不见的单词,您希望Laplace smoothing。这意味着什么:对某些单词计数为零是违反直觉的,因为它意味着这个单词的概率为0,对于你能想象的任何单词都是假的:-)因此你想为每个单词增加一点但是肯定的概率字。
另外,考虑使用对数。长消息将具有许多单词概率&lt; 1.当您在计算机上乘以大量小浮点数时,很容易遇到数值问题。为了克服它,你可能会注意到:
log (p1 * ... * pn) = log p1 + ... + log pn
因此,我们交换了n个小数的乘法,用于n个相对大(和负)的加法。然后,您可以exp
改变结果以获得概率估计值。
UPD :实际上,这是您演示的一个有趣的子主题。它显示了输出零概率的NB的缺点以及可以修复它的方法。并且它不是一个临时补丁,而是应用贝叶斯方法的结果(它相当于添加先验)
UPD 2 :第一次没有注意到,但看起来你的Naive Bayes概念错了。特别是贝叶斯的一部分。
基本上,NB由2个组成部分组成:
p(class|X) = p(X|class) p(class) / p(X)
提供了p(X)
所有class
的相同内容,因此它对概率的顺序没有任何影响。或者,另一种说法相同的方式是,p(class|X)
与p(X|class) p(class)
成比例(最多为常数)。你可能已经猜到了,那就是贝叶斯的来源。p(X|class)
表示在X
中遇到消息 class
的概率。我们无法获得足够的数据来估计每条消息的可能性。所以这里是我们的模型假设:我们说消息的单词是独立的(显然,错误和不正确,因此方法天真)。这导致我们p(X|class) = p(x1|class) * ... * p(xn|class)
n
X
中的单词数量为p(x|class)
。现在我们需要以某种方式估计概率x
。 word
这里不是一个完整的信息,而是一个(一个)字。直观地,从给定的class
获得一些#(word, class) / #(class)
的概率等于该类中该单词的出现次数除以该类的总大小:p(x|class) = p(x, class) / p(class)
(或者,我们可以再次使用贝叶斯规则:p(x|class)
)。
因此,由于x
是p(x|class) = (#(x, class) + a) / Z
以上的分布,我们需要它总和为1.因此,如果我们通过说Z
sum_x p(x|class) = 1
来应用拉普拉斯平滑是一个规范化常量,我们需要强制执行以下约束:sum_x(#(x, class) + a) = Z
,或等效地Z = #(class) + a * N
。它给了我们N
,其中{{1}}是所有单词的数量(只是单词的数量,而不是它们的出现次数!)