贝叶斯算法及其应用案例

贝叶斯分类算法:
贝叶斯分类是统计学的一种分类算法,它是一类利用概率统计知识进行分类的算法。在许多场合,朴素贝叶斯(Naïve Bayes,NB)分类算法可以与决策树和神经网络分类算法相媲美。
缺陷:
与其本身的设定有关,由于贝叶斯假设一个属性值对给定类的影响独立于其它属性的值,但是该假设在实际情况中经常是不成立的,因此其分类准确率可能会下降。升级版:降低独立性假设的贝叶斯分类算法,如TAN(tree augmented Bayes network)算法。
朴素贝叶斯分类的正式定义如下:
1.设 x={a1,a2,…,am}为一个待分类项,而每个 a 为 x 的一个特征属性。
2.有类别集合 C={y1,y2,…,yn}。
3.计算 P( y1|x) ,P( y2|x),…, P( yn|x)。
4.如果 P( yk|x) =max{P( y1|x),P( y2|x),…, P( yn|x)},则 x∈yk。
贝叶斯算法如下:

#贝叶斯算法实现
#建立一个类
import numpy as np
class Bayes:
    def _init_(self):
        self.length=-1
        self.labelcount=dict()
        self.vectorcount=dict()
    def fit(self,dataSet:list,labels:list):
        if(len(dataSet)!=len(labels)):
            raise ValueError("您输入的测试数组跟类别数组长度不一致")
        self.length=len(dataSet[0]) 
        #测试数据特征值的长度
        labelsnum=len(labels)   
        #类别所有的数量
        norlabels=set(labels) 
        #不重复类别的数量
        for item in norlabels:
            thislabel=item
            labelcount[thislabel]=labels.count(thislabel)/labelsnum  
            #当前类别占总类别的比例
        for vector,label in zip(dataSet,labels):   
        #将两变量整合到一起
            if(label not in vectorcount):
                self.vectorcount[label]=[]
            self.vectorcount[label].append(vector)
        print("训练结束")
    def btest(self,TestData,labelsSet):
        if(self.length==-1):
            raise ValueError("您还没有进行训练,请先训练")
        #计算当前testdata分别为各个类别的概率
        IbDict=dict()
        for thisIb in labelsSet:
            p=1
            alllabel=self.labelcount[thisIb]  
            #当前类别占总类别的多少
            allvector=self.vectorcount[thisIb]
            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
            IbDict[thisIb]=p*alllabel
        thislabel=sorted(IbDict,key=lambda x: IbDict[x],reverse=True)[0]
        return thislabel

用贝叶斯算法进行手写体数字的识别:
#加载数据

#加载数据
def datatoarray(fname):
    arr=[]
    fh=open(fname)
    for i in range(0,32):
        thisline=fh.readline()
        for j in range(0,32):
            arr.append(int(thisline[j]))
    return arr
#建立一个函数取文件名前缀
def seplabel(fname):
    filestr=fname.split(".")[0]
    label=int(filestr.split("_")[0])
    return label

 #建立训练数据

#建立训练数据
def traindata():
    labels=[]
    trainfile=listdir("D:/shujufenxi/traindata")
    num=len(trainfile)
    #长度1024(列),每一行存储一个文件
    #用一个数组存储所有训练数据,行:文件总数,列:1024
    trainarr=zeros((num,1024))
    for i in range(0,num):
        thisfname=trainfile[i]
        thislabel=seplabel(thisfname)
        labels.append(thislabel)
        trainarr[i,:]=datatoarray("D:/shujufenxi/traindata/"+thisfname)
    return trainarr,labels
bys=Bayes()
#训练数据
train_data,labels=traindata()
bys.fit(train_data,labels)

#测试数据

#识别多个手写体数字(批量测试)
testfileall=listdir("D:/shujufenxi/testdata")
num=len(testfileall)
x=0
for i in range(0,num):
    thisfilename=testfileall[i]
    
    '''print(thisfilename)'''
    
    thislabel=seplabel(thisfilename)
    #print(thislabel)
    thisdataarray=datatoarray("D:/shujufenxi/testdata/"+thisfilename)
    label=bys.btest(thisdataarray,labelsall)
    
    print("该数字是:"+str(thislabel)+",识别出来的数字是:"+str(label))  #输出识别结果
    
    if(label!=thislabel):
        x+=1
        print("此次出错")
print(x)
print("错误率是:"+str(float(x)/float(num)))

输出结果:错误率是:0.1226215644820296

完整代码如下: 

#贝叶斯算法的应用(手写体字体的识别)
from numpy import *
import operator
from os import listdir
import numpy as npy
import numpy
class Bayes:
    def __init__(self):
        self.length=-1
        self.labelcount=dict()
        self.vectorcount=dict()
    def fit(self,dataSet:list,labels:list):
        if(len(dataSet)!=len(labels)):
            raise ValueError("您输入的测试数组跟类别数组长度不一致")
        self.length=len(dataSet[0])#测试数据特征值的长度
        labelsnum=len(labels)#类别所有的数量
        norlabels=set(labels)#不重复类别的数量
        for item in norlabels:
            thislabel=item
            self.labelcount[thislabel]=labels.count(thislabel)/labelsnum#求的当前类别占类别总数的比例
        for vector,label in zip(dataSet,labels):
            if(label not in self.vectorcount):
                self.vectorcount[label]=[]
            self.vectorcount[label].append(vector)
        print("训练结束")
        return self
    def btest(self,TestData,labelsSet):
        if(self.length==-1):
            raise ValueError("您还没有进行训练,请先训练")
        #计算testdata分别为各个类别的概率
        lbDict=dict()
        for thislb in labelsSet:
            p=1
            alllabel=self.labelcount[thislb]
            allvector=self.vectorcount[thislb]
            vnum=len(allvector)
            allvector=numpy.array(allvector).T
            for index in range(0,len(TestData)):
                vector=list(allvector[index])
                p*=vector.count(TestData[index])/vnum
            lbDict[thislb]=p*alllabel
        thislabel=sorted(lbDict,key=lambda x:lbDict[x],reverse=True)[0]
        return thislabel

#加载数据
def datatoarray(fname):
    arr=[]
    fh=open(fname)
    for i in range(0,32):
        thisline=fh.readline()
        for j in range(0,32):
            arr.append(int(thisline[j]))
    return arr
#建立一个函数取文件名前缀
def seplabel(fname):
    filestr=fname.split(".")[0]
    label=int(filestr.split("_")[0])
    return label
#建立训练数据
def traindata():
    labels=[]
    trainfile=listdir("D:/shujufenxi/traindata")
    num=len(trainfile)
    #长度1024(列),每一行存储一个文件
    #用一个数组存储所有训练数据,行:文件总数,列:1024
    trainarr=zeros((num,1024))
    for i in range(0,num):
        thisfname=trainfile[i]
        thislabel=seplabel(thisfname)
        labels.append(thislabel)
        trainarr[i,:]=datatoarray("D:/shujufenxi/traindata/"+thisfname)
    return trainarr,labels
bys=Bayes()
#训练数据
train_data,labels=traindata()
bys.fit(train_data,labels)
#测试
thisdata=datatoarray("D:/shujufenxi/testdata/8_90.txt")
labelsall=[0,1,2,3,4,5,6,7,8,9]
#识别单个手写体数字
'''
rst=bys.btest(thisdata,labelsall)
print(rst)    #输出训练结果为8
'''    
#识别多个手写体数字(批量测试)
testfileall=listdir("D:/shujufenxi/testdata")
num=len(testfileall)
x=0
for i in range(0,num):
    thisfilename=testfileall[i]
    
    '''print(thisfilename)'''
    
    thislabel=seplabel(thisfilename)
    #print(thislabel)
    thisdataarray=datatoarray("D:/shujufenxi/testdata/"+thisfilename)
    label=bys.btest(thisdataarray,labelsall)
    
    print("该数字是:"+str(thislabel)+",识别出来的数字是:"+str(label))  #输出识别结果
    
    if(label!=thislabel):
        x+=1
        print("此次出错")
print(x)
print("错误率是:"+str(float(x)/float(num)))

猜你喜欢

转载自blog.csdn.net/Analyst128/article/details/81873435
今日推荐