目录
一、概述
贝叶斯分类算法是基于贝叶斯方法的一列分类算法,包括朴素贝叶斯、半朴素贝叶斯、贝叶斯网络、EM算法等,朴素贝叶斯分类器是贝叶斯分类器中最简单,也是最常见的一种分类方法。
- 先验概率:是指根据以往经验和分析得到的概率。
- 后验概率:事情已经发生,要求这件事情发生的原因是由某个因素引起的可能性的大小。后验概率类似于条件概率
- 联合概率:设二维离散型随机变量(X,Y)所有可能取得值为,记则称 为随机变量X和Y的联合概率,计算如下:
1. 贝叶斯定理
贝叶斯公式是建立在条件概率的基础上寻找事件发生的原因(即大事件A已经发生的条件下,分割中的小事件 Bi 的概率),设 B1,B2,…, 是样本空间 Ω 的一个划分,则对任一事件A(P(A)>0),有贝叶斯定理:
对于每个特征 x,想要知道样本在这个特性 x下属于哪个类别,即求后验概率 P(c|x) 最大的类标记。这样基于贝叶斯公式,可以得到:
2. 基于贝叶斯决策理论的分类方法
若,则类别为1,反之则类别为2。因此,概率大的为决策结果。
- 优点:在数据较少的情况下仍然有效,可以处理多类别问题
- 缺点:对于输入数据的准备方式较为敏感
- 适用数据类型:标称型数据(分类数据)
公式:
二、Python实例
1.训练集样本
编号 | 天气 | 温度 | 湿度 | 风力 | 适合打网球 |
1 | sunny | hot | high | weak | no |
2 | sunny | hot | high | strong | no |
3 | overcast | hot | high | weak | yes |
4 | rain | mild | high | weak | yes |
5 | rain | cool | normal | weak | yes |
6 | rain | cool | normal | strong | no |
7 | overcast | cool | normal | strong | yes |
8 | sunny | mild | high | weak | no |
9 | sunny | cool | normal | weak | yes |
10 | rain | mild | normal | weak | yes |
11 | sunny | mild | normal | strong | yes |
12 | overcast | mild | high | strong | yes |
13 | overcast | hot | normal | weak | yes |
14 | rain | mild | high | strong | no |
依据给定的训练例子,使用朴素贝叶斯分类器进行分类:
编号 | 天气 | 温度 | 湿度 | 风力 | 适合打网球 |
测1 | sunny | hot | high | weak | ? |
具体代码实现
import numpy as np
import math
import pandas as pd
# 加载数据集
def loadDataSet():
# 训练集
dataSet=[['sunny','hot','high','weak','no'],
['sunny','hot','high','strong','no'],
['overcast','hot','high','weak','yes'],
['rain','mild','high','weak','yes'],
['rain','cool','normal','weak','yes'],
['rain','cool','normal','strong','no'],
['overcast','cool','normal','strong','yes'],
['sunny','mild','high','weak','no'],
['sunny','cool','normal','weak','yes'],
['rain','mild','normal','weak','yes'],
['sunny','mild','normal','strong','yes'],
['overcast','mild','high','strong','yes'],
['overcast','hot','normal','weak','yes'],
['rain','mild','high','strong','no']]
# 测试集
testSet= ['sunny','hot','high','weak']
# 样本的特征名称
labels = ['天气','温度','湿度','风力']
return dataSet,testSet,labels
- 输出训练集、测试集、特征名
dataSet,testSet,labels = loadDataSet()
print("训练集:",dataSet)
print("测试集:",testSet)
print("特征名称:",labels)
2.计算先验概率
# 计算先验概率
def prior():
dataSet = loadDataSet()[0] # 载入数据集
countY = 0 # 初始化适宜打网球天数
countN = 0 # 初始化不适宜打网球天数
countAll = len(dataSet)
for item in dataSet:
if item[-1] == "yes":
countY += 1
for item in dataSet:
if item[-1] == "no":
countN += 1
# 计算先验概率P(c)
P_Y = round(countY/countAll,3)
P_N = round(countN/countAll,3)
return P_Y,P_N
P_Y,P_N = prior()
print("P(适宜打网球)=",P_Y)
print("P(不适宜打网球)=",P_N)
- 先验概率结果显示如下:
3.计算各属性的条件概率
#计算离散属性的条件概率P(xi|c)
def P(index,cla):
dataSet,testSet,labels = loadDataSet()
countY = 0
countN = 0
for item in dataSet:
if item[-1] == "yes":
countY += 1
for item in dataSet:
if item[-1] == "no":
countN += 1
# lst为cla类中第index个属性上取值为xi的样本组成的集合
lst = [item for item in dataSet if(item[-1]==cla)&(item[index]==testSet[index])]
P = round(len(lst)/(countY if cla=="yes" else countN),3) # 计算条件概率
return P
P0_Y = P(0,"yes") # P(sunny|yes)
P0_N = P(0,"no") # P(sunny|no)
P1_Y = P(1,"yes") # P(hot|yes)
P1_N = P(1,"no") # P(hot|no)
P2_Y = P(1,"yes") # P(high|yes)
P2_N = P(1,"no") # P(high|no)
P3_Y = P(1,"yes") # P(weak|yes)
P3_N = P(1,"no") # P(weak|no)
print("P(sunny|yes)=",P0_Y,"P(sunny|no)=",P0_N)
print("P(hot|yes)=",P1_Y,"P(hot|no)=",P1_N)
print("P(high|yes)=",P2_Y,"P(high|no)=",P2_N)
print("P(weak|yes)=",P3_Y,"P(weak|no)=",P3_N)
- 我选的数据集中属性都是离散的,因此不用分开计算。如果有密度、概率等则需要计算其连续属性的条件概率。以上各条件概率计算如下:
4. 计算后验概率
# 计算后验概率
isYes = P_Y*P0_Y*P1_Y*P2_Y*P3_Y
isNo = P_N*P0_N*P1_N*P2_N*P3_N
print("P(yes|xi)=",isYes)
print("P(no|xi)=",isNo)
- 后验概率计算完,分类也就到达尾声了,对比两个特征,概率大的就为决策结果,实验结果如下:
实验结果分析:在当前测试集下,预测结果为这天不适宜打网球。与训练集结果一致。
三、实验总结
与之前实验对比:数据集手动输入,没有调库,测试集和训练集的设置也更加方便。朴素贝叶斯运用到的概率公式有接触过,对于计算也更容易理解。