朴素贝叶斯算法原理与实现

一、模型

我们要求的最终结果是使 P(Y=c_{k}|X=x)最大的c_{k}值,而依据贝叶斯定理可知:

以上公式中x为,待遇测的样本,c为具体的分类标签,由最后的等式可知分母不会发生变化,要求

argminP(Y=c_{k}|X=x),即求argminP(X=x|Y=c_{k}|)P(Y=c_{k})

损失函数为0,1损失函数。

二、拉布拉斯平滑

从原始模型可以看到,某些情况下概率为0,则整个计算结果为0,这会影响最后的预测结果,所以这里引入了拉布拉斯平滑。

一般的引入方法是在分子中统一加1,而在分母上加上标签类的数目(边缘概率或者条件概率时则是条件标签数目)

三、代码实现

与网上传统的词袋模型不一样,这里我实现了一种更通用的贝叶斯预测模型,适用于多分类和多个特征多个取值的情况,至于词袋模型,我也会在以后贴出代码。不当之处,欢迎批评指正,相互交流,相互提高。

__author__ = 'Gujun(Bill)'
#朴素贝叶斯一般实现
#2018/11/05

class bayes(object):#朴素贝叶斯多分类多特征多取值的通用实现非词袋模型
    def __init__(self,class_num,charact_num):
        self.class_num = class_num#标签类别数
        self.charact_num = charact_num
        self.dict_c = {}
        self.dict_fun = {}
        self.dict_pro = {}
        self.dict_fun_pro = {}
    def training(self,dataMat):#适用于多分类问题
        charact_num = dataMat.shape[1] - 1 #特征数
        data_num = dataMat.shape[0] #训练的数据量
        sum_c = self.class_num*[0] #用于统计
        dict_c = {} #新建字典统计每个类的样本数
        dict_fun = {}#某一个类某一个特征取某一值的样本数
        dict_pro = {}#每个类的概率
        dict_fun_pro = {}#某一类某一特征取某一值的概率
        for i in range(data_num):
            dict_c[dataMat[i][-1]] += 1
            for j in range(charact_num):
                dict_fun[dataMat[i][-1]][j][dataMat[i][j]] += 1#第j个特征取的值字典嵌套{A:{B:{C:x}}}
        for key in dict_c:
            #分子分母分别加了拉布拉斯平滑
            dict_pro[key] = (dict_c[key] + 1)/(data_num+self.class_num)
            for key1 in dict_fun[key]:
                for key2 in  dict_fun[key][key1]:
                    #分子分母分别加了拉布拉斯平滑
                    dict_fun_pro[key][key1][key2] = (dict_pro[key][key1][key2]+1)/(dict_c[key]
                    + len(dict_pro[key][key1][key2])) #计算一类某一特征取某一值的概率
        self.dict_c = dict_c
        self.dict_fun = dict_fun
        self.dict_pro = dict_pro
        self.dict_fun_pro = dict_fun_pro
        return dict_pro,dict_fun_pro,dict_c,dict_fun

    def predict(self,dict_pro,dict_fun_pro,input_vec,dict_c,dict_fun):#预测
        pro_max = 0
        c_k = dict_c.keys()[0]
        for key in dict_pro:
            pro_temp = dict_pro[key]
            for j in range(self.charact_num):#第j个特征
                if input_vec[j] not in dict_fun_pro[key][j]:#如果这一特征出现了训练数据未出现的值
                    dict_fun_pro[key][j][input_vec[j]] = 1/(dict_c[key] + 1)
                pro_temp *= dict_fun_pro[key][j][input_vec[j]]
            if pro_temp > pro_max:
                pro_max = pro_temp
                c_k = key
        print("prediction result :",c_k)
        return c_k

    def predict_to_training(self):#用于将新的预测数据转为训练集中
        pass

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值