模式识别第一个作业,我虽然有师兄师姐们的答案,但是我不想继承了,想自己写,调动自己的学习热情!
对自己的学习负责!
作业如下:
十字交叉验证的原理是将数据集分为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)
下面是运行结果:
花费一天时间,终于把程序编写完成了!结果很理想!有不足之处,还请社友、大神们多多指导!感谢!