朴素贝叶斯法--机器学习(3)

1.导读

朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法;之所以为朴素,就是假设特征条件独立,使得计算简单;如果没有假设特征条件独立,则应该考虑各特征条件之间的关系,从而形成贝叶斯网络;本次博客主要从基础公式,朴素贝叶斯法的学习与分类、参数估计、高斯朴素贝叶斯等方面介绍朴素贝叶斯法。

2.原始数学公式

无论是在高中数学还是概率论中,我们都会学到条件概率公式,条件概率公式如下:
.

  P ( A ∣ B ) = P ( A B ) P ( B ) \ P(A|B)= \cfrac {P(AB)}{P(B)}  P(AB)=P(B)P(AB)---------(1)
.

也可以写成
.
  P ( A B ) = P ( A ∣ B ) P ( B ) \ P(AB)=P(A|B) P(B)  P(AB)=P(AB)P(B)---------(2)
.

当事件A和B互不相关时,有
.
  P ( A B ) = P ( A ∣ B ) P ( B ) = P ( A ) P ( B ) \ P(AB)=P(A|B) P(B)=P(A)P(B)  P(AB)=P(AB)P(B)=P(A)P(B)---------(3)
.

全概率公式有
.
  P ( B ) = ∑ i = 1 n P ( B ∣ A i ) P ( A i ) \ P(B)= \displaystyle\sum_{i=1}^{n}P(B|A_i)P(A_i)  P(B)=i=1nP(BAi)P(Ai)---------(4)
.

贝叶斯定理为:
.
  P ( A i ∣ B ) = P ( B ∣ A i ) P ( A i ) ∑ i = 1 n P ( B ∣ A i ) P ( A i ) \ P(A_i|B)= \frac{P(B | A_i) P(A_i)}{ \displaystyle\sum_{i=1}^{n}P(B|A_i)P(A_i)}  P(AiB)=i=1nP(BAi)P(Ai)P(BAi)P(Ai)---------(5)
.

看到了这里,不禁想问,这些个公式对我们有什么帮助呢?首先,我们先有这么一个模型的前提:对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布,然后基于这个模型,对给定的输入x,利用此定理(公式5)求出后验概率最大的输出y。我们把公式5中的符合都换成模型描述中常用的x与y可得:
.
  P ( Y = c k ∣ X = x ) = P ( X = x ∣ Y = c k ) P ( Y = c k ) ∑ k = 1 n P ( X = x ∣ Y = c k ) P ( Y = c k ) \ P(Y=c_k|X=x)= \frac{P(X=x | Y=c_k) P(Y=c_k)}{ \displaystyle\sum_{k=1}^{n}P(X=x|Y=c_k)P(Y=c_k)}  P(Y=ckX=x)=k=1nP(X=xY=ck)P(Y=ck)P(X=xY=ck)P(Y=ck)---------(6)
.

3.朴素贝叶斯分类器

上文提到,朴素贝叶斯法之所以为朴素,是因为假设特征条件独立;我们的输入数据X有着多种特征,将他们假设为独立,就好像公式(3)中那样,各个特征的概率累乘,就可得最后的结果,下面公式给出:
.

  P ( X = x ∣ Y = c k ) = P ( X ( 1 ) = x ( 1 ) , . . . , X ( n ) = x ( n ) ∣ Y = c k ) = ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) \ P(X=x|Y=c_k)= P(X^{(1)}=x^{(1)},...,X^{(n)}=x^{(n)}|Y=c_k)=\\ \displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k)  P(X=xY=ck)=P(X(1)=x(1),...,X(n)=x(n)Y=ck)=j=1nP(X(j)=x(j)Y=ck)---------(7)
.

将(7)代入到(6)中可得
.
  P ( Y = c k ∣ X = x ) = P ( Y = c k ) ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) ∑ k = 1 n ( P ( Y = c k ) ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) ) \ P(Y=c_k|X=x)= \frac{ P(Y=c_k)\displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k)}{ \displaystyle\sum_{k=1}^{n}(P(Y=c_k)\displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k))}  P(Y=ckX=x)=k=1n(P(Y=ck)j=1nP(X(j)=x(j)Y=ck))P(Y=ckj=1nP(X(j)=x(j)Y=ck)---------(8)
.

于是可得,朴素贝叶斯分类器为:
.
  y = f ( x ) = a r g max ⁡ c k = P ( Y = c k ) ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) ∑ k = 1 n ( P ( Y = c k ) ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) ) \ y=f(x)=arg \displaystyle\max_{c_k}= \frac{ P(Y=c_k)\displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k)}{ \displaystyle\sum_{k=1}^{n}(P(Y=c_k)\displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k))}  y=f(x)=argckmax=k=1n(P(Y=ck)j=1nP(X(j)=x(j)Y=ck))P(Y=ckj=1nP(X(j)=x(j)Y=ck)---------(9)
.

可见,分母对所有的   c k \ c_k  ck都是相同的,所以公式9可写为:
.
  y = f ( x ) = a r g max ⁡ c k = P ( Y = c k ) ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) \ y=f(x)=arg \displaystyle\max_{c_k}= P(Y=c_k)\displaystyle\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_k)  y=f(x)=argckmax=P(Y=ckj=1nP(X(j)=x(j)Y=ck)---------(10)
.

为什么要取最大值呢?因为后验概率最大等价于期望风险最小化,换个角度来看,就是希望通过这样的方法所取得的结果的损失是最小的;有如下推导:
1.选择0-1损失函数:   L ( Y , f ( X ) ) = { 1 Y   / = f ( X ) 0 Y = f ( X ) \ L(Y,f(X))=\begin{cases} 1&\text{} Y \mathrlap{\,/}{=}f(X) \\ 0&\text{} Y=f(X) \\ \end{cases}  L(Y,f(X))={10Y/=f(X)Y=f(X)
2.根据联合分布可取得条件期望为:   E X ∑ k = 1 K L ( c k , f ( X ) ) P ( c k ∣ X ) \ E_X \displaystyle\sum_{k=1}^{K}L(c_k,f(X))P(c_k|X)  EXk=1KL(ck,f(X))P(ckX)
3.使期望风险最小化,对各个x最小化有
.
  f ( x ) = a r g min ⁡ y ∈ Y ∑ k = 1 K L ( c k , f ( X ) ) P ( c k ∣ X = x ) = a r g min ⁡ y ∈ Y ∑ k = 1 K P ( y   / = c k ∣ X = x ) = a r g min ⁡ y ∈ Y ∑ k = 1 K ( 1 − P ( y = c k ∣ X = x ) ) = a r g max ⁡ c k P ( y = c k ∣ X = x ) \ f(x)=arg \displaystyle\min_{y \in Y} \displaystyle\sum_{k=1}^{K}L(c_k,f(X))P(c_k|X=x) \\ =arg \displaystyle\min_{y \in Y} \displaystyle\sum_{k=1}^{K}P(y\mathrlap{\,/}{=}c_k|X=x) \\ =arg \displaystyle\min_{y \in Y} \displaystyle\sum_{k=1}^{K}(1-P(y=c_k|X=x))\\ =arg \displaystyle\max_{c_k}P(y=c_k|X=x)  f(x)=argyYmink=1KL(ck,f(X))P(ckX=x)=argyYmink=1KP(y/=ckX=x)=argyYmink=1K(1P(y=ckX=x))=argckmaxP(y=ckX=x)
.

4.推导完成,得到   a r g max ⁡ c k P ( y = c k ∣ X = x ) \ arg \displaystyle\max_{c_k}P(y=c_k|X=x)  argckmaxP(y=ckX=x)

4.朴素贝叶斯法的参数估计

看到了这,我们还不知道怎么去让模型“学习”,在此,学习意味着估计   P ( Y = c k ) \ P(Y=c_k)  P(Y=ck)   P ( X ( j ) = x ( j ) ∣ Y = c k ) \ P(X^{(j)}=x^{(j)}|Y=c_k)  P(X(j)=x(j)Y=ck);在此使用极大似然估计有:
.

  P ( Y = c k ) = ∑ i = 1 N I ( y = c k ) N \ P(Y=c_k)=\frac {\displaystyle\sum_{i=1}^{N}I(y=c_k)}{N}  P(Y=ck)=Ni=1NI(y=ck)---------(11)
.

.
  P ( X ( j ) = x ( j ) ∣ Y = c k ) = ∑ i = 1 N I ( X ( j ) = x ( j ) , y = c k ) ∑ i = 1 N I ( y = c k ) \ P(X^{(j)}=x^{(j)}|Y=c_k)=\frac {\displaystyle\sum_{i=1}^{N}I(X^{(j)}=x^{(j)},y=c_k)}{\displaystyle\sum_{i=1}^{N}I(y=c_k)}  P(X(j)=x(j)Y=ck)=i=1NI(y=ck)i=1NI(X(j)=x(j),y=ck)---------(12)
.

但是,使用极大似然估计有时候会出现为0的情况,会影响到后续的计算结果,那么我们可以采用贝叶斯估计,如下:
.
  P ( Y = c k ) = ∑ i = 1 N I ( y = c k ) + λ N + K λ \ P(Y=c_k)=\frac {\displaystyle\sum_{i=1}^{N}I(y=c_k)+\lambda}{N+K\lambda}  P(Y=ck)=N+Kλi=1NI(y=ck)+λ---------(13)
.

.
  P ( X ( j ) = x ( j ) ∣ Y = c k ) = ∑ i = 1 N I ( X ( j ) = x ( j ) , y = c k ) + λ ∑ i = 1 N I ( y = c k ) + S j λ \ P(X^{(j)}=x^{(j)}|Y=c_k)=\frac {\displaystyle\sum_{i=1}^{N}I(X^{(j)}=x^{(j)},y=c_k)+\lambda}{\displaystyle\sum_{i=1}^{N}I(y=c_k)+S_j\lambda}  P(X(j)=x(j)Y=ck)=i=1NI(y=ck)+Sjλi=1NI(X(j)=x(j),y=ck)+λ---------(14)
.

常取   λ = 1 \ \lambda=1  λ=1,这时称为拉普拉斯平滑。
上面考虑的情况为分散的,如果特征值为连续的呢?我们又应该怎么做?我们可以假设在   c k \ c_k  ck的条件下,x服从高斯分布(正态分布)。根据正态分布的概率密度函数即可计算出   P ( X = x ∣ Y = c k ) \ P(X=x|Y=c_k)  P(X=xY=ck),公式如下:
.
  P ( X = x ∣ Y = c k ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 \ P(X=x|Y=c_k)= \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}  P(X=xY=ck)=σ2π 1e2σ2(xμ)2---------(15)
.

注意:在代码实现的时候最好先按类别分好X,然后再进行操作。在多特征值的时候,将其累乘即可。

5.优缺点分析

由于特征条件独立这一假设为一个较强的假设,模型所包含的条件概率大大减小,使得模型的学习与预测大为简化,因此高效而又易实现;但是缺陷在于分类的性能不高。

6.代码实现

class NaiveBayes:
    def __init__(self):
        self.model = None
        
    def mean(X):
        return sum(X) / float(len(X))

    # 标准差(方差)
    def stdev(self, X):
        avg = self.mean(X)
        return math.sqrt(sum([pow(x-avg, 2) for x in X]) / float(len(X)))

    # 概率密度函数
    def gaussian_probability(self, x, mean, stdev):
        exponent = math.exp(-(math.pow(x-mean,2)/(2*math.pow(stdev,2))))
        return (1 / (math.sqrt(2*math.pi) * stdev)) * exponent

    # 处理X_train
    def summarize(self, train_data):
        summaries = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)]
        return summaries

    # 分类别求出数学期望和标准差
    def fit(self, X, y):
        labels = list(set(y))
        data = {label:[] for label in labels}
        for f, label in zip(X, y):
            data[label].append(f)
        self.model = {label: self.summarize(value) for label, value in data.items()}
        return 'gaussianNB train done!'

    # 计算概率
    def calculate_probabilities(self, input_data):
        probabilities = {}
        for label, value in self.model.items():
            probabilities[label] = 1
            for i in range(len(value)):
                mean, stdev = value[i]
                probabilities[label] *= self.gaussian_probability(input_data[i], mean, stdev)
        return probabilities

    # 类别
    def predict(self, X_test):
        label = sorted(self.calculate_probabilities(X_test).items(), key=lambda x: x[-1])[-1][0]
        return label

    def score(self, X_test, y_test):
        right = 0
        for X, y in zip(X_test, y_test):
            label = self.predict(X)
            if label == y:
                right += 1

        return right / float(len(X_test))

7.总结

因为这次属于复习一遍概念,所以代码没有码,从电脑里不知道什么时候从github下的代码贴了上来,大家参考一下就好~最近报夏令营什么的真的头晕脑胀辽,下一个写决策树;这次的朴素贝叶斯总体上来说还是比较简单的,公式的推导也比较简单,毕竟这一“特征条件独立”的假设太强了,剩下的就是之前学过的公式的应用了,主要要关注在期望风险最小化的推导以及高斯那里,其他的问题都不大。(手动狗头)水了水了,看不懂公式的去补一下概率论 知识就好,简单的很。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值