一、基础知识篇
条件概率
全概率公式:
贝叶斯推断
同时再思考一个问题,在使用该算法的时候,如果不需要知道具体的类别概率,我们有必要计算P(B)这个全概率吗?要知道我们只需要比较 P(A1|B)和P(A2|B)的大小,找到那个最大的概率就可以。既然如此,两者的分母都是相同的,那我们只需要比较分子即可。即比较P(B|A1)P(A1)和P(B|A2)P(A2)的大小,所以为了减少计算量,全概率公式在实际编程中可以不使用。
朴素贝叶斯
普通贝叶斯公式 相当于 只有一个特征
朴素贝叶斯有多个特征,且不同特征之间相互独立
实例理解朴素贝叶斯
我们看:P(打喷嚏|感冒)*P(建筑工人|感冒)*P(感冒) 这个式子的三项均是从训练集中得到数据,如果我们不考虑分母的话,那么这个式子得到的就是该样本属于 感冒 的概率。
二、补充知识
拉普拉斯平滑(Laplace smoothing)
当某个分量在总样本某个分类中(观察样本库/训练集)从没出现过,这时候会导致条件概率计算为0,最后会导致整个实例的计算结果为0。为了解决这个问题,使用拉普拉斯平滑/加1平滑进行处理。分子+1,分母+类别数。
假设在文本分类中,有3个类,C1、C2、C3,在指定的训练样本中,某个词语F1,在各个类中观测计数分别为=0,990,10,即概率为P(F1/C1)=0,P(F1/C2)=0.99,P(F1/C3)=0.01,对这三个量使用拉普拉斯平滑的计算方法如下:
1/1003 = 0.001,991/1003=0.988,11/1003=0.011
实际应用场景
文本分类
垃圾邮件过滤
病人分类
拼写检查
朴素贝叶斯模型
高斯模型:处理特征是连续型变量的情况
多项式模型:最常见,要求特征是离散数据
伯努利模型:要求特征是离散的,且为布尔类型,即true和false,或者1和0
三、朴素贝叶斯算法实现
# encoding=utf-8
import pandas as pd
import numpy as np
import cv2
import time
# 该方法已被弃用
# from sklearn.cross_validation import train_test_split
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 二值化处理
def binaryzation(img):
cv_img = img.astype(np.uint8) # 类型转化成Numpy中的uint8型
cv2.threshold(cv_img, 50, 1, cv2.THRESH_BINARY_INV, cv_img) # 大于50的值赋值为0,不然赋值为1
return cv_img
# 训练,计算出先验概率和条件概率
def Train(trainset, train_labels):
print(len(trainset))
'''
:param trainset: 特征矩阵
:param train_labels: 类别
:return:
'''
prior_probability = np.zeros(class_num) # 先验概率
conditional_probability = np.zeros((class_num, feature_len, 2)) # 条件概率(10,784,2)
# 计算
for i in range(len(train_labels)): # 遍历所有样本,len(train_labels) 是所有样本数
img = binaryzation(trainset[i]) # 特征图片二值化,让每一个特征都只有0,1两种取值
label = train_labels[i]
prior_probability[label] +&