python 实现朴素贝叶斯分类器(离散数据)

有用请点赞,没用请差评。

欢迎分享本文,转载请保留出处。

 

朴素贝叶斯算法步骤: 

 

python 实现朴素贝叶斯分类器(离散数据)_第1张图片

贝叶斯估计 

python 实现朴素贝叶斯分类器(离散数据)_第2张图片 

 代码:

# -*- coding:utf-8 -*-
# naive Bayes  朴素贝叶斯法
#author:Tomator

"""
算法参考与李航博士《统计学习方法》
采用贝叶斯估计(拉普拉斯平滑)计算先验概率和条件概率
"""

from collections import Counter, defaultdict
import  numpy as np
import  operator

class NBayes(object):
    def __init__(self,smooth=1):
        self.smooth = smooth  # 贝叶斯估计方法的平滑参数smooth=1,当smooth=0时即为最大似然估计
        self.p_prior = {}  # 先验概率
        self.p_condition = {}  # 条件概率

    def train(self, vector_data , label_data):

        n_samples = label_data.shape[0]       #计算样本数
        # 统计不同类别的样本数,并存入字典,key为类别,value为样本数
        # Counter类的目的是用来跟踪值出现的次数。以字典的键值对形式存储,其中元素作为key,其计数作为value。
        dict_label = Counter(label_data)
        K = len(dict_label)
        for key, val in dict_label.items():
            # 计算先验概率
            self.p_prior[key] = (val + self.smooth) / (n_samples + K * self.smooth)

        # 计算后验概率
        # 分别对每个特征维度进行计算,vector_data.shape[1]为特征向量的维度
        for d in range(vector_data.shape[1]):
            # defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值
            nums_vd = defaultdict(int)
            # 抽取特定维度
            vector_d = vector_data[:, d]
            # unique函数去除其中重复的元素,并按元素由大到小返回一个新的无元素重复的元组或者列表
            nums_s = len(np.unique(vector_d))   #每个特征向量的可能取值个数
            for xd, y in zip(vector_d, label_data):
                nums_vd[(xd, y)] += 1
            for key, val in nums_vd.items():
                #  d为维度,key[0]为每个特征向量每个维度的的值, key[1]为类别
                self.p_condition[(d, key[0], key[1])] = (val + self.smooth) / (dict_label[key[1]] + nums_s * self.smooth)


    # 预测未知特征向量的类别
    def predict(self, input_v):
        p_predict = {}
        # y为类别,p_y为每个类别的先验概率
        for y, p_y in self.p_prior.items():
            p=p_y  #计算每种后验概率
            for d, v in enumerate(input_v):
                p *= self.p_condition[(d, v, y)]
            p_predict[y] = p
        #     对字典按value进行排序
        p_predict_sorted=sorted(p_predict.items(),key=operator.itemgetter(1),reverse=True)
        # 获取字典中value最大值所对应键的大小
        # return max(p_predict, key=p_predict.get)
        return p_predict_sorted[0]


if __name__ == "__main__":
    # 以《统计学习方法》中的例4.1计算,为方便计算,将例子中"S"设为0,“M"设为1。
    data = np.array([[1, 0, -1], [1, 1, -1], [1, 1, 1], [1, 0, 1],
                     [1, 0, -1], [2, 0, -1], [2, 1, -1], [2, 1, 1],
                     [2, 2, 1], [2, 2, 1], [3, 2, 1], [3, 1, 1],
                     [3, 1, 1], [3, 2, 1], [3, 2, -1]])
    # 提取特征向量
    vector_data = data[:, :-1]
    # 提取label类别
    label_data = data[:, -1]
    # 采用贝叶斯估计计算条件概率和先验概率,此时拉普拉斯平滑参数为1,为0时即为最大似然估计
    bayes = NBayes(smooth=1)
    # 实例化
    bayes.train(vector_data, label_data)
    # 朴素贝叶斯分类
    print(bayes.predict(np.array([2, 0])))

输出 

 参考李航《统计学习方法》

你可能感兴趣的:(机器学习,彭湃的专栏)