python程序实现朴素贝叶斯算法

朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。本文将讲解二分类的朴素贝叶斯分类器的原理以及程序实现。

模型

已知一组有 n n n个样本的训练集
{ ( x i , y i ) } i = 1 n , x i ∈ R t , y i ∈ { 1 , . . . , k } \{(x_i,y_i)\}_ {i=1}^n,x_i\in\mathbb R^t,y_i\in\{1,...,k\} {(xi,yi)}i=1n,xiRt,yi{1,...,k}
其中,每个输入变量 x i x_i xi都有 t t t个特征,输出变量 y i y_i yi表示类别标签值。

模型假设

1.输入变量 x x x和输出变量 y y y都假定为随机变量。
2.输入变量 x x x的各特征间都具有条件独立性,即任意两个特征都是独立的。

算法原理

对于一个输入样本 x x x,通过计算该样本属于不同类别的概率,然后将最大概率所对应的类别作为该样本的类别。首先
P ( Y = c ∣ X = x ) P(Y=c|X=x) P(Y=cX=x)
表示在样本是 x x x的条件下,类别是 c c c的概率。之后由条件概率的公式,可以得到它等于
P ( Y = c , X = x ) P ( X = x ) = P ( X = x ∣ Y = c ) P ( Y = c ) P ( X = x ) \frac{P(Y=c,X=x)}{P(X=x)}=\frac{P(X=x|Y=c)P(Y=c)}{P(X=x)} P(X=x)P(Y=c,X=x)=P(X=x)P(X=xY=c)P(Y=c)
再由全概率公式拆解等式的分母,得到
P ( X = x ∣ Y = c ) P ( Y = c ) ∑ i = 1 k P ( X = x ∣ Y = c i ) P ( Y = c i ) \frac{P(X=x|Y=c)P(Y=c)}{\sum_{i=1}^kP(X=x|Y=c_i)P(Y=c_i)} i=1kP(X=xY=ci)P(Y=ci)P(X=xY=c)P(Y=c)
然后又因为样本的各特征间具有独立性,所以等式的分子又可以化为
P ( Y = c ) ∏ i = 1 t P ( X ( i ) = x ( i ) ∣ Y = c ) ∑ i = 1 k P ( X = x ∣ Y = c i ) P ( Y = c i ) \frac{P(Y=c)\prod_{i=1}^t P(X^{(i)}=x^{(i)}|Y=c)}{\sum_{i=1}^kP(X=x|Y=c_i)P(Y=c_i)} i=1kP(X=xY=ci)P(Y=ci)P(Y=c)i=1tP(X(i)=x(i)Y=c)
最后,对于同一个样本 x x x,上述等式的分母计算结果都是一样的,因此可以不用计算分母,直接计算分子,然后比较概率大小,选取最大的概率所对应的类别作为样本 x x x的预测类别。

程序实现

训练函数fit

这个函数先计算并保存后验概率
P ( Y = c k ) P(Y=c_k) P(Y=ck)
和每个类别下不同特征的条件概率
P ( X ( i ) = x ( i ) ∣ Y = c j ) P(X^{(i)}=x^{(i)}|Y=c_j) P(X(i)=x(i)Y=cj)

预测函数predict

根据公式对预测样本的概率进行计算,需要注意的是,有些特征的取值并没有出现在训练样本中,这时可以用一个比较小的概率进行替代。

封装成类
class NaiveBayes:
    def fit(self, X, y):
        n_sample,n_feature = X.shape
        
        # 计算P(Y=ck)的概率
        self.y_set = set(y) 
        Py = [sum(y==label)/len(y) for label in self.y_set]
        self.Py = dict(zip(self.y_set,Py))
        
        # 计算各条件概率
        self.PXY = {}
        for label in self.y_set:
            cur_x = X[y==label]
            Sum = len(cur_x)
            value = []
            for i in range(n_feature):
                feature = cur_x[:,i]
                PXY = [sum(feature==fea)/Sum for fea in set(feature)]
                PXY = dict(zip(set(feature), PXY))
                value.append(PXY)
            self.PXY[label] = value
        
    def predict(self, X):
        def check(x):
            dic = {}
            for label in self.y_set:
                cur_fea = self.PXY[label]
                prod = self.Py[label]
                for i in range(len(x)):
                    # 不存在对应特征时,赋一个比较小的概率
                    if x[i] not in cur_fea[i]:
                        prod *= 0.00001
                    else:
                        prod *= cur_fea[i][x[i]]
                dic[label] = prod
            return sorted(dic.items(), key=lambda x:x[1], reverse=True)[0][0]
        y_pred = []
        for x in X:
            y_pred.append(check(x))
        return np.array(y_pred)       
实例化
clf = NaiveBayes()
clf.fit(X, y)
clf.predict(x_test)
----end----
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值