摘要: 本贴结合例子与程序分析 NB 算法.
Naive Bayes 是一个经典的、有代表性的分类算法. Naive 的 i 上面应该是两个点, 它读作 “哪义乌”, 表示很傻瓜很天真. Bayes 是一个神职人员, 也是概率界的一个神级人物. 中国程序猿喜欢把它读作 “牛逼算法”, 其实也没吹的那么厉害.
符号型数据集, 还是用 weather 吧. 可在 https://gitee.com/fansmale/javasampledata 下载.
@relation weather.symbolic
@attribute outlook {sunny, overcast, rainy}
@attribute temperature {hot, mild, cool}
@attribute humidity {high, normal}
@attribute windy {TRUE, FALSE}
@attribute play {yes, no}
@data
sunny,hot,high,FALSE,no
sunny,hot,high,TRUE,no
overcast,hot,high,FALSE,yes
rainy,mild,high,FALSE,yes
rainy,cool,normal,FALSE,yes
rainy,cool,normal,TRUE,no
overcast,cool,normal,TRUE,yes
sunny,mild,high,FALSE,no
sunny,cool,normal,FALSE,yes
rainy,mild,normal,FALSE,yes
sunny,mild,normal,TRUE,yes
overcast,mild,high,TRUE,yes
overcast,hot,normal,FALSE,yes
rainy,mild,high,TRUE,no
P ( A B ) = P ( A ) P ( B ∣ A ) (1) P(AB) = P(A)P(B|A) \tag{1} P(AB)=P(A)P(B∣A)(1)
其中:
例: A A A 表示天气是晴天, 即 outlook = sunny; B B B 表示湿度高, 即 humidity = high.
14 天中, 有 5 天 sunny, 则 P ( A ) = P ( o u t l o o k = s u n n y ) = 5 / 14 P(A) = P(\mathrm{outlook = sunny}) = 5/14 P(A)=P(outlook=sunny)=5/14.
这 5 个晴天中, 有 3 天温度高, 则 P ( B ∣ A ) = P ( h u m i d i t y = h i g h ∣ o u t l o o k = s u n n y ) = 3 / 5 P(B|A) = P(\mathrm{humidity= high} | \mathrm{outlook = sunny}) = 3/5 P(B∣A)=P(humidity=high∣outlook=sunny)=3/5.
那么, 即是晴天又温度度的概率是 P ( A B ) = P ( o u t l o o k = s u n n y ∧ h u m i d i t y = h i t h ) = 3 / 14 = P ( A ) P ( B ∣ A ) P(AB) = P(\mathrm{outlook = sunny} \wedge \mathrm{humidity= hith})= 3/14 = P(A) P(B | A) P(AB)=P(outlook=sunny∧humidity=hith)=3/14=P(A)P(B∣A).
令 x = x 1 ∧ x 2 ∧ ⋯ ∧ x m \mathbf{x} = x_1 \wedge x_2 \wedge \dots \wedge x_m x=x1∧x2∧⋯∧xm 表示一个条件的组合, 如: o u t l o o k = s u n n y ∧ t e m p e r a t u r e = h o t ∧ h u m i d i t y = h i g h ∧ w i n d y = F A L S E \mathrm{outlook = sunny} \wedge \mathrm{temperature = hot} \wedge \mathrm{humidity = high} \wedge \mathrm{windy = FALSE} outlook=sunny∧temperature=hot∧humidity=high∧windy=FALSE, 它对应于我们数据集的第一行. 令 D i D_i Di 表示一个事件, 如: play = no. 根据 (1) 式可知:
P ( D i ∣ x ) = P ( x D i ) P ( x ) = P ( D i ) P ( x ∣ D i ) P ( x ) (2) P(D_i | \mathbf{x}) = \frac{P(\mathbf{x}D_i)}{P(\mathbf{x})} = \frac{P(D_i)P(\mathbf{x} | D_i)}{P(\mathbf{x})} \tag{2} P(Di∣x)=P(x)P(xDi)=P(x)P(Di)P(x∣Di)(2)
现在我们做一个大胆的假设, 认为各个条件之间是独立的:
P ( x ∣ D i ) = P ( x 1 ∣ D i ) P ( x 2 ∣ D i ) … P ( x m ∣ D i ) = ∏ j = 1 m P ( x j ∣ D i ) (3) P(\mathbf{x} | D_i) = P(x_1 | D_i) P(x_2 | D_i) \dots P(x_m | D_i) = \prod_{j = 1}^m P(x_j | D_i) \tag{3} P(x∣Di)=P(x1∣Di)P(x2∣Di)…P(xm∣Di)=j=1∏mP(xj∣Di)(3)
这个大胆的假设, 就是 Naive 的来源. 在现实数据中, 它是不成立的! 我都承认自己不靠谱了, 你还想怎么样? 反正我的疗效好, 哼!
综合 (2)(3) 式可得:
P ( D i ∣ x ) = P ( x D i ) P ( x ) = P ( D i ) ∏ j = 1 m P ( x j ∣ D i ) P ( x ) (4) P(D_i | \mathbf{x}) = \frac{P(\mathbf{x}D_i)}{P(\mathbf{x})} = \frac{P(D_i) \prod_{j = 1}^m P(x_j | D_i)}{P(\mathbf{x})} \tag{4} P(Di∣x)=P(x)P(xDi)=P(x)P(Di)∏j=1mP(xj∣Di)(4)
如果用例子替换成 P ( p l a y = n o ∣ o u t l o o k = s u n n y ∧ t e m p e r a t u r e = h o t ∧ h u m i d i t y = h i g h ∧ w i n d y = F A L S E ) P(\mathrm{play = no} | \mathrm{outlook = sunny} \wedge \mathrm{temperature = hot} \wedge \mathrm{humidity = high} \wedge \mathrm{windy = FALSE}) P(play=no∣outlook=sunny∧temperature=hot∧humidity=high∧windy=FALSE), 就读作: “在出太阳而且气温高而且湿度高而且没风的天气, 不打球的概率”.
这个概率是算不出来的, 因为我们计算不了分母 P ( x ) P(\mathbf{x}) P(x). 不过我们的目标是进行分类, 也就是说, 哪个类别的概率高, 我们就选谁. 而对不同的类别, 这个式子的分母是完全相同的! 所以我们的预测方案就可以描述为:
d ( x ) = arg max 1 ≤ i ≤ k P ( D i ) P ( D i ∣ x ) = arg max 1 ≤ i ≤ k P ( D i ) ∏ j = 1 m P ( x j ∣ D i ) = arg max 1 ≤ i ≤ k log P ( D i ) + ∑ j = 1 m log P ( x j ∣ D i ) (5) d(\mathbf{x}) = \argmax_{1 \leq i \leq k} P(D_i) P(D_i | \mathbf{x}) = \argmax_{1 \leq i \leq k} P(D_i) \prod_{j = 1}^m P(x_j | D_i) = \argmax_{1 \leq i \leq k} \log P(D_i) + \sum_{j = 1}^m \log P(x_j | D_i)\tag{5} d(x)=1≤i≤kargmaxP(Di)P(Di∣x)=1≤i≤kargmaxP(Di)j=1∏mP(xj∣Di)=1≤i≤kargmaxlogP(Di)+j=1∑mlogP(xj∣Di)(5)
然鹅, (5) 式在预测时会出现问题. 例如:
那么, 如果有一天 o u t l o o k = o v e r c a s t ∧ t e m p e r a t u r e = h o t \mathrm{outlook = overcast} \wedge \mathrm{temperature = hot} outlook=overcast∧temperature=hot, 岂不是打球和不打球的概率都为 0 了?
这里的根源在于 “一票否决权”, 即 (5) 式的连乘因子中, 只要有一个为 0, 则乘积一定为 0. 为了解决该问题, 我们要想办法让这个因子不要取 0 值.
P L ( x j ∣ D i ) = n P ( x j D i ) + 1 n P ( D i ) + v j = n P ( o u t l o o k = s u n n y ∧ p l a y = y e s ) + 1 n P ( p l a y = y e s ) + 3 (7) P^L(x_j | D_i) = \frac{n P(x_j D_i) + 1}{n P(D_i) + v_j} = \frac{n P(\mathrm{outlook = sunny} \wedge \mathrm{play = yes}) + 1}{n P(\mathrm{play = yes}) + 3} \tag{7} PL(xj∣Di)=nP(Di)+vjnP(xjDi)+1=nP(play=yes)+3nP(outlook=sunny∧play=yes)+1(7)
其中, n n n 是对象的数量, v j v_j vj 是第 j j j 个属性的可能取值数, outlook 有 3 种取值. 这样可以保证
问题 1: 为什么要乘以 n n n?
回答: P ( D i ) = P ( p l a y = y e s ) = 9 14 P(D_i) = P(\mathrm{play = yes}) = \frac{9}{14} P(Di)=P(play=yes)=149 是一个概率, 乘以 n n n 之后才是一个整数 9 9 9, 与 v j = 3 v_j = 3 vj=3 相加才合理. v j v_j vj 只是来打辅助的, 不可以起决定性作用.
问题 2: 分子为什么要加 1?
回答: 就是想加一个常数使它大于 0 咯, 1 最方便.
问题 2: 分母为什么要加 v j v_j vj?
回答: 与分子加 1 相适应, 保证平滑后的概率之和为 1.
第二个条件与如下条件保持一定程度的一致:
对于 P ( D i ) P(D_i) P(Di) 也需要进行平滑:
P L ( D i ) = n P ( D i ) + 1 n + c (8) P^L(D_i) = \frac{n P(D_i) + 1}{n + c}\tag{8} PL(Di)=n+cnP(Di)+1(8)
考虑 Laplacian 平滑的优化目标为:
d ( x ) = arg max 1 ≤ i ≤ k log P L ( D i ) + ∑ j = 1 m log P L ( x j ∣ D i ) (9) d(\mathbf{x}) = \argmax_{1 \leq i \leq k} \log P^L(D_i) + \sum_{j = 1}^m \log P^L(x_j | D_i)\tag{9} d(x)=1≤i≤kargmaxlogPL(Di)+j=1∑mlogPL(xj∣Di)(9)
请各位打开 日撸 Java 三百行(51-60天,kNN 与 NB), 对照程序来理解.
399 行是入口, 转到 357 行.
359 行的数据, 可以换成本贴中的数据.
361 行初始化一个对象, 包括
362 行设置数据类型为符号型, 这个与数值型区别.
363 行计算决策属性 (play) 的分布.
364 行计算条件概率.
365 行进行预测.
254-257 行进行逐个样本的测试, 注意本程序仅测试了训练集的数据, 当然, 你很容易把它改成新的测试集.
265 行的方法根据两种数据分别选择, 现在选择的是 classifyNominal().
数值型数据, 没有办法使用 P ( h u m i d i t y = 87 ) P(\mathrm{humidity} = 87) P(humidity=87), 因为湿度刚刚好为 87 (而不是 87.001) 的概率为 0. 实际上, 湿度为任何值的概率都为 0. 当然, P ( 86 ≤ h u m i d i t y < 87 ) P(86 \le \mathrm{humidity} < 87) P(86≤humidity<87) 的概率不为 0.
但是, 如果我们不想把湿度做成 [ 86 , 87 ) [86, 87) [86,87) 这样的区间 (即进行离散化), 能不能也用 NB 算法来预测呢? 可以的!
我们需要做两件事:
400 行是入口, 转到 375 行.
383 行的代码甚至与符号型数据的完全相同.
384 行进行参数计算.
309 行这个方法负责预测.
值型数据的代码居然比符号型的还短!
用其它分布的假设, 可以获得其它结果.
全概率 1:
P ( A ) = P ( A D ) + P ( A ¬ D ) = P ( D ) P ( A ∣ D ) + P ( ¬ D ) P ( A ∣ ¬ D ) (2) P(A) = P(AD) + P(A \neg D) = P(D)P(A | D) + P(\neg D)P(A | \neg D)\tag{2} P(A)=P(AD)+P(A¬D)=P(D)P(A∣D)+P(¬D)P(A∣¬D)(2)
其中, ¬ D \neg D ¬D 表示事件不发生.
这个式子的意思是, 事件 D D D 与 A A A 同时发生的概率, 加上事件 ¬ D \neg D ¬D 与事件 A A A 同时发生的概率, 等于事件 A A A 发生的概率.
例: A A A 表示天气是晴天, 即 outlook = sunny; D D D 表示要打球, 即 play = yes.
14 天中, 有 5 天 sunny, 则 P ( A ) = P ( o u t l o o k = s u n n y ) = 5 / 14 P(A) = P(\mathrm{outlook = sunny}) = 5/14 P(A)=P(outlook=sunny)=5/14.
14 天中, 有 2 天 sunny 且打球, 则 P ( A D ) = P ( o u t l o o k = s u n n y , p l a y = y e s ) = 2 / 14 P(AD) = P(\mathrm{outlook = sunny}, \mathrm{play = yes}) = 2/14 P(AD)=P(outlook=sunny,play=yes)=2/14.
14 天中, 有 3 天 sunny 且不打球, 则 P ( A D ) = P ( o u t l o o k = s u n n y , p l a y = n o ) = 3 / 14 P(AD) = P(\mathrm{outlook = sunny}, \mathrm{play = no}) = 3/14 P(AD)=P(outlook=sunny,play=no)=3/14.
该式的后一部分是通过将式 (1) 代入获得的.
全概率 2: 有的时候决策类不只是两种情况 (例如 iris 的种类为 k = 3 k = 3 k=3), 所以需要推广一下.
假设 D 1 D_1 D1, D 2 D_2 D2, … \dots …, D k D_k Dk 构成一个完备事件组,即它们两两互不相容,其和为全集, 并且 P ( D i ) > 0 P(D_i) > 0 P(Di)>0. 则
P ( A ) = P ( A D 1 ) + P ( A D 2 ) + P ( A D k ) = P ( D 1 ) P ( A ∣ D 1 ) + P ( D 2 ) P ( A ∣ D 2 ) + ⋯ + P ( D k ) P ( A ∣ D k ) = ∑ i = 1 k P ( D i ) P ( A ∣ D i ) (3) \begin{array}{ll}P(A) & = P(A D_1) + P(A D_2) + P(A D_k) \\ &= P(D_1)P(A | D_1) + P(D_2)P(A | D_2) + \dots + P(D_k)P(A | D_k)\\ &= \sum_{i = 1}^k P(D_i)P(A | D_i)\end{array} \tag{3} P(A)=P(AD1)+P(AD2)+P(ADk)=P(D1)P(A∣D1)+P(D2)P(A∣D2)+⋯+P(Dk)P(A∣Dk)=∑i=1kP(Di)P(A∣Di)(3)
P ( D i ∣ x ) = P ( x D i ) P ( x ) = P ( D i ) P ( x ∣ D i ) P ( x ) = ∑ i = 1 k P ( D i ) P ( A ∣ D i ) P ( x ) \begin{array}{ll}P(D_i | x) & = \frac{P(xD_i)}{P(x)} = \frac{P(D_i)P(x | D_i)}{P(x)}\\ & = \frac{\sum_{i = 1}^k P(D_i)P(A | D_i)}{P(x)}\end{array} P(Di∣x)=P(x)P(xDi)=P(x)P(Di)P(x∣Di)=P(x)∑i=1kP(Di)P(A∣Di)
同理, P ( A B ) = P ( B ) P ( A ∣ B ) P(AB) = P(B)P(A|B) P(AB)=P(B)P(A∣B).
因此,
P ( A ) = P ( B ) P ( A ∣ B ) P ( B ∣ A ) (2) P(A) = \frac{P(B)P(A|B)}{P(B|A)} \tag{2} P(A)=P(B∣A)P(B)P(A∣B)(2)
令
P ( X = x ) = ∑ k P ( X = x ∣ Y = c k ) P ( Y = c k ) P(X=x) = \sum_k P(X = x | Y = c_k)P(Y= c_k) P(X=x)=∑kP(X=x∣Y=ck)P(Y=ck)
P ( a 1 = s u n n y ) P(a_1 = sunny) P(a1=sunny)
= P ( a 1 = s u n n y & p l a y = P ) + P ( a 1 = s u n n y & p l a y = N ) = P(a_1 = sunny \& play = P) + P(a_1 = sunny \& play = N) =P(a1=sunny&play=P)+P(a1=sunny&play=N)
= P ( a 1 = s u n n y ∣ p l a y = P ) P ( p l a y = P ) + P ( a 1 = s u n n y ∣ p l a y = N ) P ( p l a y = N ) = P(a_1 = sunny | play = P) P(play = P) + P(a_1 = sunny | play = N) P(play = N) =P(a1=sunny∣play=P)P(play=P)+P(a1=sunny∣play=N)P(play=N)