def predict(train_samples,X): #描述属性分别用数字代替 #年龄: <=30:0, 30~40:1, <40:2 #收入:‘低’:0,'中':1,'高':2 #是否学生:‘是’:1,'否':1 #信誉: '中':0,'优':1 #购买属性用数字代替 #购买电脑 :‘是’:0,‘否’:1 MAP = [{'<=30': 0,'31~40' : 1, '>40': 2}, {'低': 0,'中': 1,'高':2}, {'是':0, '否':1}, {'中':0, '优':1}, {'是':0,'否':1}] #下面步骤将文字转化为对应的数字 train_samples = [sample.split(' ') for sample in train_samples] train_samples = [[MAP[i][attr] for i,attr in enumerate(sample)]for sample in train_samples] X = [MAP[i][attr] for i , attr in enumerate(X.split(' '))] #训练样本数量 n_sample = len(train_samples) #单个样本的维度,描述属性和类型属性个数 dim_sample = len(train_samples[0]) #计算每个属性的取值 attr = [] for i in range(0,dim_sample): attr.append([]) for sample in train_samples: for i in range(0,dim_sample): if sample[i] not in attr[i]: attr[i].append(sample[i]) #每个属性取值的个数 n_attr = [len(attr) for atttr in attr] #记录不同类别的样本个数 n_c = [] for i in range(0,n_attr[dim_sample-1]): n_c.append(0) #计算不同类别的样本个数 for sample in train_samples: n_c[sample[dim_sample-1]] += 1 #计算不同类别样本所占比例 p_c = [n_cx / sum(n_c) for n_cx in n_c] #将用户按类别分类 samples_at_c = {} for c in attr[dim_sample-1]: samples_at_c[c] = [] for sample in train_samples: samples_at_c[sample[dim_sample-1]].append(sample) #记录每个类别的训练样本中,待取分类样本的某个属性值的样本个数 n_attr_X = {} for c in attr[dim_sample-1]: n_attr_X[c] = [] for j in range(0,dim_sample-1): n_attr_X[c].append(0) #计算每个类别的训练样本中待取分类样本的某个属性值的样本个数 for c, samples_at_cx in zip(samples_at_c.keys(), samples_at_c.values()): for sample in samples_at_cx: for i in range(0,dim_sample-1): if X[i] == sample[i]: n_attr_X[c][i] = n_attr_X[c][i]+1 #字典转化为list n_attr_X = list(n_attr_X.values()) n_attr_X[0],n_attr_X[1] = n_attr_X[1],n_attr_X[0] #储存最后的概率 result_p =[] for i in range(0,n_attr[dim_sample-1]): result_p.append(p_c[i]) #计算概率 for i in range(0,n_attr[dim_sample-1]): n_attr_X[i] = [x/n_c[i] for x in n_attr_X[i]] for x in n_attr_X[i]: result_p[i] *= x #找到概率对应最大的类别,便是样本的分类情况 predict_class = result_p.index(max(result_p)) predict_list.append(predict_class) return predict_class if __name__=='__main__': #训练样本 train_samples = ["<=30 高 否 中 否", "<=30 高 否 优 否", "31~40 高 否 中 是", ">40 中 否 中 是", ">40 低 是 中 是", ">40 低 是 优 否", "31~40 低 是 优 是", "<=30 中 否 中 否", "<=30 低 是 中 是", ">40 中 是 中 是", "<=30 中 是 优 是", "31~40 中 否 优 是", "31~40 高 是 中 是", ">40 中 否 优 否" ] #待分类样本 X = '<=30 中 是 中' #实现待分类样本的预测 print(predict(train_samples,X)) #实现评价指标 truth=false=0 new_train_samples = ["<=30 高 否 中 否", "<=30 高 否 优 否", "31~40 高 否 中 是", ">40 中 否 中 是", ">40 低 是 中 是", ">40 低 是 优 否", "31~40 低 是 优 是", "<=30 中 否 中 否", "<=30 低 是 中 是", ">40 中 是 中 是", "<=30 中 是 优 是", "31~40 中 否 优 是", "31~40 高 是 中 是", ">40 中 否 优 否" ] for index,train_sample in enumerate(train_samples): X=train_sample[:-2] print(X) res=train_sample[-1] #将原训练集每次拿出一个训练样本作为测试样本,其余为新的训练集 new_train_samples.pop(index) predict_res=predict(new_train_samples,X)[0] print (predict_res) if (res=='是')&(predict_res==0): truth+=1 elif(res=='否')&(predict_res==1): truth+=1 else: false+=1 new_train_samples = ["<=30 高 否 中 否", "<=30 高 否 优 否", "31~40 高 否 中 是", ">40 中 否 中 是", ">40 低 是 中 是", ">40 低 是 优 否", "31~40 低 是 优 是", "<=30 中 否 中 否", "<=30 低 是 中 是", ">40 中 是 中 是", "<=30 中 是 优 是", "31~40 中 否 优 是", "31~40 高 是 中 是", ">40 中 否 优 否" ] truth_per= truth/(truth+false) print(truth,false) print(truth_per)
2020-05-27·