赞
踩
1. 朴素贝叶斯介绍
朴素贝叶斯法是基于贝叶斯定理()与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入x, 利用贝叶斯定理求出后验概率最大的输出y。
2. 朴素贝叶斯特点
优点:在数据较少的情况下仍然有效,可以处理多类别问题
缺点:对于输入数据的准备方式较为敏感。
使用数据类型:标称型数据
3. 朴素贝叶斯法的学习与分类
3.1.1基本方法
设输入空间
由独立同分布产生。
朴素贝叶斯法通过训练数据集学习联合概率分布。具体地,学习以下先验概率分布和条件概率分布。先验概率分布:
条件概率分布
于是就学到了联合概率分布
条件概率有指数级数量的参数,其估计实际是不可行的。事实上,假设,假设可取值有个,,Y可取值有K个,那么参数个数为 .
由可取值有个,可知
个取值;
个取值
......
又由于
参数个数为
关于朴素贝叶斯的条件独立性假设的理解:
朴素贝叶斯分类时,对于给定的输入的,通过学习到的模型计算后验概率 分布,将后验概率最大的类作为的类输出。后验概率计算根据贝叶斯定理可知:
推导过程如下:
由贝叶斯定理得
根据全概率公式可知
所以可知
将式(3.3)带入式(3.4)得
这是朴素贝叶斯分类的基本公式,于是有朴素贝叶斯分类器可表示为
又因为,在式中(3.7)分母对所有的都是相同的,所以
4.1.2后验概率最大化的含义
假设选择0-1损失函数:
式中是分类决策函数。这时,期望风险函数为
期望是对联合分布取的,由此条件期望为
具体这一步是怎么来的呢,如下所示:
要是期望风险最小,也就是这个图中的积分最小,那么对于任意的一个X=x在P(X=x)为常数条件下内层积分最小,即期望风险最小等价于条件期望最小。
而为了使得期望风险最小化,只需对X=x逐个极小化,则有:
由期望风险最小化就可以得到后验概率最大化准则:
也就是朴素贝叶斯所采用的原理。
4. 朴素贝叶斯法的参数估计
4.1 极大似然估计
在朴素贝叶斯学习中,学习意味着估计和。可以应用极大似然估计法估计相应的概率。先验概率的极大似然估计是
设第j个特征可能取值的集合为,条件概率的极大似然估计是
式中,是第i个样本的第j个特征;是第j个特征可能取的第个值;为指示函数。
4.2 学习与分类算法
输入:训练数据
其中,是第i个样本的第j个特征,,是第j个特征可能取的第个值,
输出:实例的分类。
(1)计算先验概率及条件概率
先验概率:
条件概率:
(2)对于给定的实例
(3)确定实例的类
例1.试由表1的训练数据学习朴素贝叶斯分类器并确定
表1 训练数据
解答如下:
代码如下:
#!/usr/bin/env python3 #coding=utf-8 import numpy as np class NaiveBeyes(object): #获取训练数据 def getTrainSet(self): dataSet=np.array([[1,'S'],[1,'M'],[1,'M'],[1,'S'],[1,'S'],[2,'S'],[2,'M'],[2,'M'],[2,'L'],[2,'L'],[3,'L'], [3,'M'],[3,'M'],[3,'L'],[3,'L']]) labels=[-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1] return dataSet,labels def classify(self,trainData,labels,features): #先计算先验概率 #用于存放不同类别的先验概率 labelProb={} for label in labels: labelProb[label]=labels.count(label)/float(len(labels)) #计算特征和标签同时发生的概率 # 用来存放特征和标签同时发生时的概率 p_xy = {} for tagvalue in labelProb.keys(): #获取Labels中出现tagvalue值的所有数值的下标索引 tagvalueIndex=[index for index,label in enumerate(labels) if label==tagvalue] for i in range(len(features)): #获取features中的值在训练集中出现的所有下标索引 x_index=[index for index,feature in enumerate(trainData[:,i]) if feature==features[i]] xy_count=len(set(tagvalueIndex) & set(x_index)) #如果它们索引相同,说明它们特征和标签同时发生 key=str(features[i])+'*'+str(tagvalue) p_xy[key]=xy_count/float(len(labels)) #计算条件概率 #创建空字典,并将条件概率存入其中 prob={} for tagvalue in labelProb.keys(): for feature in features: pkey=str(feature)+'|'+str(tagvalue) prob[pkey]=p_xy[str(feature)+'*'+str(tagvalue)]/float(labelProb[tagvalue]) #计算[2,S]所属类别 #创建空字典用于存放[2,S]所属不同类别的概率 resultProb={} for tagvalue in labelProb.keys(): resultProb[tagvalue]=labelProb[tagvalue] for x in features: resultProb[tagvalue]=resultProb[tagvalue]*prob[str(x)+'|'+str(tagvalue)] #max(dict,key=dict.get)表示获取字典中值最大所对应的键 result_feature=max(resultProb,key=resultProb.get) return result_feature if __name__=='__main__': NB=NaiveBeyes() #训练数据 trainData,labels=NB.getTrainSet() features=np.array([2,'S']) result=NB.classify(trainData,labels,features) print("[2,'S']的类别标记为:{}".format(result))
4.3贝叶斯估计
用极大似然估计可能会出现所要估计的概率值为0的情况,这时会影响到后验概率的计算结果,使分类产生偏差。解决这一问题的方法是采用朴素贝叶斯估计。具体的是如下所示:
式中
表明式(4.3)确实是一个概率分布,同时,先验概率的贝叶斯估计为
这里的K应该是指类别数
例2. 同例1,按照拉普拉斯平滑估计概率,即取
解答过程如下:
代码如下:
#!/usr/bin/env python3 #coding=utf-8 import numpy as np class NaiveBeyes(object): #初始化K,j,λ值 def __init__(self): self.D=1 #表示λ=1 self.K=2 self.S=3 #获取训练数据 def getTrainSet(self): dataSet=np.array([[1,'S'],[1,'M'],[1,'M'],[1,'S'],[1,'S'],[2,'S'],[2,'M'],[2,'M'],[2,'L'],[2,'L'],[3,'L'],[3,'M'],[3,'M'],[3,'L'],[3,'L']]) labels=[-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1] return dataSet,labels def classify(self,trainData,labels,features): #先计算先验概率 #用于存放不同类别的先验概率 labelProb={} for label in labels: labelProb[label]=(labels.count(label)+self.D)/float(len(labels)+self.K*self.D) #计算条件概率 # 用来存放特征和标签同时发生时的概率 prob = {} for tagvalue in labelProb.keys(): #获取labels中出现tagvalue值的所有数值的下标索引 tagvalueIndex=[index for index,label in enumerate(labels) if label==tagvalue] #获取labels中每个标签出现的个数 tagvalueCount=labels.count(tagvalue) for i in range(len(features)): #获取features中的值在训练集中出现的所有下标索引 x_index=[index for index,feature in enumerate(trainData[:,i]) if feature==features[i]] xy_count=len(set(tagvalueIndex) & set(x_index)) #如果它们索引相同,说明它们特征和标签同时发生 key=str(features[i])+'|'+str(tagvalue) prob[key]=(xy_count+self.D)/float(tagvalueCount+self.S*self.D) #计算[2,S]所属类别 #创建空字典用于存放[2,S]所属不同类别的概率 resultProb={} for tagvalue in labelProb.keys(): resultProb[tagvalue]=labelProb[tagvalue] for x in features: resultProb[tagvalue]=resultProb[tagvalue]*prob[str(x)+'|'+str(tagvalue)] #max(dict,key=dict.get)表示获取字典中值最大所对应的键 result_feature=max(resultProb,key=resultProb.get) return result_feature if __name__=='__main__': NB=NaiveBeyes() #训练数据 trainData,labels=NB.getTrainSet() features=np.array([2,'S']) result=NB.classify(trainData,labels,features) print("[2,'S']的类别标记为:{}".format(result))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。