第四章 朴素贝叶斯法(naive_Bayes)

总结

  • 朴素贝叶斯法实质上是概率估计。
  • 由于加上了输入变量的各个参量条件独立性的强假设,使得条件分布中的参数大大减少。同时准确率也降低。
  • 概率论上比较反直觉的一个问题:三门问题:由于主持人已经限定了他打开的那扇门是山羊,即已经有前提条件了,相对应的概率也应该发生改变,具体公式啥的就不推导了。这个问题与朴素贝叶斯方法有关系,即都用到了先验概率。
  • 其中有两种方法来计算其概率分布。
    • 极大似然法估计:
    • 贝叶斯估计:无法保证其中所有的情况都存在,故再求其条件概率的时候加上一个偏置项,使其所有情况的条件概率在所给的有限的训练集上都不为0。

       

  • 下面对极大似然法和贝叶斯估计进行推导。(习题内容)习题内容可能要拖一拖了,枯辽
  • 下面是代码实现,代码注释还是挺清楚的
# encoding=utf-8

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import time


def binaryzation(array):
    #二值化
    # 大于50的为1,小于50的为0,二值化后,参数总量从255降到了2
    array[array[:, :] <= 50] = 0
    array[array[:, :] > 50] = 1
    return array


def read_data(path):
    raw_data = pd.read_csv(path, header=0)
    data = raw_data.values

    imgs = data[:, 1:]
    labels = data[:, 0]
    imgs = binaryzation(imgs)

    # 选2/3的数据作为数据集,1/3的数据作为测试集
    tra_x, test_x, tra_y, test_y = train_test_split(imgs, labels, test_size=0.33, random_state=2019526)
    return tra_x, test_x, tra_y, test_y


def naive_Bayes(x, y, class_num=10, feature_len=784, point_len=2, lamba=1):
    """
    :param x: 学习的数据集
    :param y: 学习的标签
    :param class_num: y的类别的数目
    :param feature_len: 每个训练数据的特征向量有多少维
    :param point_len: 每个训练集数据的特征向量有多少种取值情况
    :return: 先验概率和条件概率
    """
    # 这里我们使用贝叶斯估计法来做
    prior_probability = np.zeros(class_num)
    conditional_probability = np.zeros((class_num, feature_len, point_len))
    # 先得到每个对应的数目,计算先验概率
    for i in range(10):
        prior_probability[i] += len(y[y[:] == i])

    # 计算条件概率
    for i in range(class_num):
        # 取出x中label对应数据为i的点
        data_ith = x[y == i]
        for j in range(feature_len):
            for k in range(point_len):
                # 在之前的数据中取出第j列为1,或者为0的点
                conditional_probability[i, j, k] += len(data_ith[data_ith[:, j] == k]) + lamba
        conditional_probability[i, :, :] /= (prior_probability[i] + point_len * lamba)

    prior_probability += lamba
    prior_probability /= (len(y) + class_num * lamba)

    return prior_probability, conditional_probability


def predict(pp, cp, data, class_num=10,feature_len=784):
    """
    预测
    :param pp: prior_probability
    :param cp: conditional_probability
    :param data: 输入数据
    :return: 预测结果
    """
    pre_label = np.zeros(len(data)+1)
    for i in range(len(data)):
        max_possibility = 0
        max_label = 0
        for j in range(class_num):
            tmp=pp[j]
            for k in range(feature_len):
                tmp*=cp[j,k,data[i,k]]
            if tmp>max_possibility:
                max_possibility=tmp
                max_label=j
        pre_label[i]=max_label
    return pre_label



if __name__ == '__main__':
    time_1=time.time()
    tra_x, test_x, tra_y, test_y = read_data('data/Mnist/mnist_train.csv')
    time_2=time.time()
    prior_probability, conditional_probability = naive_Bayes(tra_x, tra_y, 10, 784, 2, 1)
    time_3=time.time()
    pre_label = predict(prior_probability, conditional_probability, test_x, 10,784)
    cous=0
    for i in range(len(test_y)):
        if pre_label[i]==test_y[i]:
            cous+=1
    print(cous/len(pre_label))
    time_4=time.time()
    print("time of reading data: ",int(time_2-time_1))
    print("time of getting model: ",int(time_3-time_2))
    print("time of predictting: ",int(time_4-time_3))
View Code

这个是他的准确率及所消耗的时间

反思:

其实这个准确率低是可以修正的将point_len修改的大点应该就可以提升一点准确率了,因为在我的代码里对每个像素点的划分太过于大了,大于50就为1,小于50就为0,可以分成3段或者更多。

posted @ 2019-05-27 16:55  老哈球  阅读(298)  评论(0编辑  收藏  举报