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