潇洒郎:Ten-fold-cross validation- Naïve Bayes Classifier 十字交叉验证-贝叶斯分类器 Python实现

模式识别第一个作业,我虽然有师兄师姐们的答案,但是我不想继承了,想自己写,调动自己的学习热情!
对自己的学习负责!
作业如下:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
十字交叉验证的原理是将数据集分为10组,轮流选择其中一组作为测试组,其余作为训练组,然后利用贝叶斯分类器计算决策正确的概率
贝叶斯公式
在这里插入图片描述
贝叶斯优化分类器
1在这里插入图片描述
其中A为条件/状态,di为决策也可表示为:
在这里插入图片描述
如1-14条数据,选择第一组{1,11}作为测试组,其余作为训练组,
在这里插入图片描述
注:其中的di为决策Yes/No,A为状态如Sunny,Hot等,看如下例子,计算出决策dmp=“No”
在这里插入图片描述
现在我们明白了原理,那么就进行解决问题了:
一,准备数据traindata.txt 如图:
在这里插入图片描述
二,编写程序:

def getdata():
    '''获取所有事件信息'''
    data = []
    f = open('traindata.txt', 'r')
    lines = f.readlines()
    for line in lines:
        li = line.split(' ')
        data.append(li)
        f.close()
    return data

def get_tests_info_save_traindata(testlabel):
    '''
    testlabel为测试标签,[1]/[1,11]
    获取测试标签信息和除测试外的剩余训练集:testlabel_s,data
    '''
    testlabel_s=[]
    data = getdata()
    if testlabel!=None:
        for tst in testlabel:
            for d in data:
                # 条件
                if str(tst) == d[0]:                     #判断是否为测试标签
                    labb= (d[1], d[2], d[3], d[4],d[5])  #记录测试标签的状态
                    testlabel_s.append(labb)
                    data.remove(d)                       #将测试项信息从总数据集中删除
                else:
                    pass
        return data,testlabel_s
    else:
        pass

def get_number(testlabel=None):
    '''
    testlabel为测试标签,[1]/[1,11]
    获取测试项的结果(No,Yes):resulist; 统计除测试项外剩余事件的No,Yes数量:noyes
    以及统计在No,Yes条件下的各状态的数量:nolist,yeslist
    '''
    if testlabel==None:
        print('')
    else:
        data, telabels = get_tests_info_save_traindata(testlabel)
        nolist, yeslist,resulist,nolabel, yeslabel=[],[],[],[],[]
        for tel in telabels:
            a1, a2, a3, a4,a5= tel[0], tel[1], tel[2], tel[3], tel[4]   # 测试标签的天气情况标签
            no,yes,a1nonum,a2nonum,a3nonum,a4nonum,a1yesnum,a2yesnum,a3yesnum,a4yesnum =0,0, 0, 0, 0, 0,0, 0, 0, 0
            for d in data:
                # 获取No,Yes的数量
                dd = d[-1].replace('\n', '')
                if dd == 'No':
                    no += 1
                    if d[1]==a1:
                        a1nonum+=1
                    if d[2]==a2:
                        a2nonum += 1
                    if d[3]==a3:
                        a3nonum+=1
                    if d[4]==a4:
                        a4nonum += 1
                    #No条件下的各状态的数量
                    nolabel=(a1nonum, a2nonum, a3nonum, a4nonum)
                if dd == 'Yes':
                    yes += 1
                    if d[1]==a1:
                        a1yesnum+=1
                    if d[2]==a2:
                        a2yesnum += 1
                    if d[3]==a3:
                        a3yesnum+=1
                    if d[4]==a4:
                        a4yesnum += 1
                    #Yes条件下的各状态的数量
                    yeslabel=(a1yesnum, a2yesnum, a3yesnum, a4yesnum)
            resulist.append(a5)                #记录测试标签的决策
            noyes=(no,yes)                     #No/Yes的数量
            noo=(nolabel)                      #No条件下的各状态的数量
            yess=(yeslabel)                    #Yes条件下的各状态的数量
            nolist.append(noo)
            yeslist.append(yess)
        return resulist,noyes,nolist,yeslist

def getresult(teslabe):
    '''根据参数计算决策正确的概率'''
    result=''     #初设决策
    i=0           #初设决策正确的概率
    res4, noyes4, no4, yes4 = get_number(teslabe)
    #res4, noyes4, no4, yes4=['No\n', 'Yes\n'] (4, 8) [(2, 1, 3, 1), (2, 2, 1, 3)] [(1, 2, 3, 6), (1, 3, 5, 2)]
    no_num = noyes4[0]
    yes_num = noyes4[1]
    p_no = no_num / (no_num + yes_num)             #若为两个测试项,P(No)与P(Yes)概率也不变
    p_yes = yes_num/(no_num + yes_num)
    for t in range(len(no4)):                      #根据测试项数目循环计算概率
        print('结果:',res4[t].replace('\n',''))
        #计算Bel(No),Bel(Yes)的概率
        belno = p_no * (no4[t][0]/no_num)*(no4[t][1]/no_num)*(no4[t][2]/no_num)*(no4[t][3]/no_num)
        belyes = p_yes * (yes4[t][0]/yes_num)*(yes4[t][1]/yes_num)*(yes4[t][2]/yes_num)*(yes4[t][3]/yes_num)
        print('No概率:',belno)
        print('Yes概率:', belyes)
        #根据Bel(No),Bel(Yes)做出决策
        if belno > belyes:
            result='No'
        else:
            result='Yes'
        print('决策:',result)
        #判断决策是否正确
        if res4[t].replace('\n','')==result:   #若本身决策和计算所得决策一样,计算概率
            if len(no4)==2:  #若该组内有两个测试项,则各占50%比率,每次决策正确则概率增加50%
                i += 0.5
            else:            #若该组内有一个测试项,则占100%比率,决策正确则概率增加100%
                i += 1.0
        else:                #若决策错误,则概率增加为0
            i+=0
        print('正确率:',i)
        print('\n')
    return i                 #返回决策的正确率

def get_possiblities(gro):
    '''获取概率集'''
    possibilities = []
    for i in gro: #每一组轮流作为测试标签
        #将分组转化为列表[5]/[2,12]
        tests = []
        tests.append(i[0])
        tests.append(i[-1])
        tests = list(set(tests))
        r = getresult(tests)    #获取概率集
        possibilities.append(r)
    return possibilities
gro = [(5,), (1, 11), (2, 12), (3, 13), (4, 14), (6,), (7,), (8,), (9,), (10,)]
posbs=get_possiblities(gro)
print('各组作为测试项,决策正确的概率分别为:',posbs)
k=0
for h in posbs:
    k=k+h
#计算平均概率
avepos=k/len(posbs)
print('平均概率为:',avepos)

下面是运行结果:
在这里插入图片描述
花费一天时间,终于把程序编写完成了!结果很理想!有不足之处,还请社友、大神们多多指导!感谢!

猜你喜欢

转载自blog.csdn.net/qq_32711799/article/details/88379194