Python 贝叶斯分类
博文类型: 学习向
背景: 本科阶段参见数学建模比赛,运用该技术与KNN算法作比较,从而得出最优算法
目标: 了解贝叶斯的原理并且能够进行简单的运用
1.贝叶斯的基本思想
朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。通俗来说,就好比这么个道理,你在街上看到一个黑人,我问你你猜这哥们哪里来的,你十有八九猜非洲。为什么呢?因为黑人中非洲人的比率最高,当然人家也可能是美洲人或亚洲人,但在没有其它可用信息下,我们会选择条件概率最大的类别,这就是朴素贝叶斯的思想基础。
2.贝叶斯分类定义
1.设x={}为一个待分类项,每个a为x的一个特征属性
2.有类别集合y={}
3.计算
4.如果{} 则
==以上了解一下即可,代码部分和这个只有一点点关系,为什么这样说呢,我们判断两个样本是否相同不是看整个样本,而是化整为稀碎,看这一个样本中每个特征在训练集中占同类特征的比例==
那么现在的关键就是如何计算第3步中的各个条件概率。我们可以这么做:
1.找到一个已知分类的待分类项集合,这个集合叫做训练样本集。
2.统计得到在各类别下各个特征属性的条件概率估计。即
3.如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导: 因为分母对于所有类别为常数,因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的,所以有: ==3里面的两个公式是代码的核心==
3.示例
1.手写体数字识别
现有一个手写体数字
为了识别它,我们先要对图片进行处理
代码1:
#change the type of the picture
from PIL import Image#获取图片每一个点的颜色用的
im=Image.open("E:\\数字2.jpg")
fh=open("E:/数字2.txt",'a')
width=im.size[0]
height=im.size[1]
for i in range(0,width):
for j in range(0,height):
k=im.getpixel((i,j))#获取颜色
clo=k[0]+k[1]+k[2]
if clo==0:#是黑色就把这个点作为1写入文本
fh.write("1")
else:
fh.write("0")
fh.write("\n")
fh.close
图片处理完后会得到一个由0和1组成的矩阵
在识别手写体数字之前我要对已有训练集进行训练
这里训练的意思就是求训练集中每一个类别占总类别的比例
代码2:
import numpy as np
class Bayes:
def __init__(self):
self.length=-1
self.labelcount=dict()#建了一个字典用来存放类别所占比例
self.vectorcount=dict()#建了一个字典用来存放特征
def fit(self,dataSet,labels):#训练的函数
if len(dataSet)!=len(labels):#每一组特征都要对应一个类别
raise ValueError("length is not same")#报错提示
self.length=len(dataSet[0])#获取特征的个数
labelsnum=len(labels)#获取总类别的个数
norlabels=set(labels)#获取不同的类别
for item in norlabels:#算出同类别的个数
thislabel=item
self.labelcount[thislabel]=labels.count(thislabel)/labelsnum#current pr
for vector,label in zip(dataSet,labels):
if(label not in vectorcount):
self.vectorcount[label]=[]
self.vectorcount[label].append(vector)
print("over")
return self
2.贝叶斯算法
代码3:
def btest(self,TestData,labelsSet):
if self.length==-1:#判断是否训练
raise ValueError("please fit first")
ibDict=dict()#用来存放所有类别概率的字典
for thislb in labelsSet:#遍历所有的类别
p=1
alllabel=self.labelcount[thislb]#当前类别所占比例
allvector=self.vectorcount[thislb]#当前类别的所有样本特征
vnum=len(allvector)
allvector=np.array(allvector).T#将训练集看成一个矩阵然后转置
for index in range(0,len(TestData)):#遍历待预测样本所有特征
vector=list(allvector[index])#训练样本该类特征的列表
p*=vector.count(TestData[index])/vnum#求出该类特征的比例即P(a_1|y_i),P(a_2|y_i)...P(a_m|y_i)
ibDict[thislb]=p*alllabel#预测样本是该类别的概率
thislabel=sorted(lbDict,renerse=True)[0]#排序
return thislabel