题目:与使用单个合取式来进行假设表示相比,使用“析合范式”将使得假设空间具有更强的表示能力。若使用最多包含k个合取式的析合范式来表达1.1的西瓜分类问题的假设空间,试估算有多少种可能的假设。
表1.1包含4个样例,3种属性,假设空间中有3∗4∗4+1=493∗4∗4+1=49种假设。最多包含k个合取式来表达假设空间,显然k的最大值是49。
不考虑空集的话,剩下48种可能:
全部不泛化 2∗3∗3=182∗3∗3=18种假设
一个属性泛化:2∗3+3∗3+2∗3=212∗3+3∗3+2∗3=21种假设
两个属性泛化:2+3+3=82+3+3=8种假设
三属性泛化:1种假设
用这48种假设的排列组合来组成析合范式,展开序列为(也就是杨辉三角的一排):
1, 48, 1128, 17296,...... 17296, 1128, 48, 1 共49个数, 左边的1代表‘空’,一个都不选,右边的1代表全部选。
如果k=48,就是说最多采用48种合取式来组成析合范式,排除一种都不选的情况,就是2^48 - 1种。(2^48是根据二项式定理得的)
如果0<k<48,那就把展开序列的前k+1(因为展开序列从0开始数)项全部加起来再减1
如果指定了k的个数,那就是展开序列的第k+1(因为展开序列从0开始数)项的数
但是,这个结果得去重才行,因为泛化是对若干种假设的包含(包容),它本身不是某种假设。把泛化的 * 展开后,
就是若干种具体的假设。如果此题采取48,那么把 * 展开后,假设集合中一定有重复,而且一种具体假设还不止重复一次。
此题应该采用18种具体假设来计算, 就是: 2^18 - 1
以下python代码没有考虑全部为空的情况(-1),且没有考虑去重。
# -*- coding: utf-8 -*-
def strige(max):#杨辉三角
S = [1]
while max:
N = S[:]
N.append(0)
S = [N[i-1]+N[i] for i in range(len(N))]
max -= 1
return S
def cal_Permutations(total_num =0,select_num= 0,most_num = 0):
re_total_num = 0
re_select_num = 0
re_most_num = 0
if total_num == 0:
raise ValueError,'pls indicate total numbers'
return
if select_num>total_num or most_num>total_num:
raise ValueError,'select_num or most_num can not bigger than total_num'
return
s = strige(total_num)
for x in s:
re_total_num += x
re_select_num = s[select_num]
for y in range(0,most_num+1):
re_most_num += s[y]
return {'input_parameter':{'total_num':total_num,'most_num':most_num,'select_num':select_num},'output_permutations':s,'output_usual_count':{'total_num':re_total_num,'most_num':re_most_num,'select_num':re_select_num}}
result = cal_Permutations(48,40,48)
print (result)