第一节的内容:机器学习——编程实现从零构造训练集的决策树-CSDN博客
目录
v2:划分验证集,优化预测
1)划分训练集和验证集
1. 从好瓜里面选出3个
2. 从坏瓜里面选出3个
import numpy as np
def show(D):
for i in D:
print(i)
good_index = np.arange(0, 8, 1, dtype=np.int16)
np.random.shuffle(good_index)
print(f"好瓜打乱后的索引={good_index}")
bad_index = np.arange(8,17,1,dtype=np.int16)
np.random.shuffle(bad_index)
print(f"坏瓜打乱后的索引{bad_index}")
train_data = [ D[i] for i in good_index[3:]]+[D[i] for i in bad_index[3:]]
val_data = [D[i] for i in good_index[:3]] + [D[i] for i in bad_index[:3]]
print("训练集的数据为")
show(train_data)
print("验证集的数据为")
show(val_data)
结果如下:
2)完善预测过程
考虑到预测样本中可能存在出现新的属性值的情况:
def predict_v2(data,root):
cur = root
while cur.label != 1:
attr = cur.bestattr
key = data[attr]
# 如果样本出现新的属性值,则这个样本被标记为当前结点数量最多的类别
if key not in cur.subDs:
return cur.max
cur = cur.subDs[key]
return cur.Class
分类精度的计算:
def calAccuracy(pred,data):
n = len(data)
re = 0
for i in range(n):
if pred[i] == data[i]['Class']:
re+=1
return re/n
3)训练模型并验证
# 建树
root_v2 = TreeGenerate(train_data,Attr)
# 画图
drawTree(root_v2)
re = []
for i in range(len(val_data)):
re.append(predict_v2(val_data[i],root_v2))
print(f"精度是:{calAccuracy(re,val_data)}")
结果截图(部分)
最后一行显示分类精度:约为0.8333
v3:k折交叉验证
变更划分方式,选择性能更好的模型
1)理论
2)实践
① 打乱原始数据集的数据
# 打乱顺序
def shuffle(D):
index = np.arange(0,len(D),1,dtype=np.int16)
cpD = copy.deepcopy(D)
np.random.shuffle(cpD)
return cpD
D_v3 = shuffle(D)
② 将数据集划分若干份
def CreateByK(D,k):
# 根据k折将数据集D划分出若干大小为k的子集
n = int(len(D)/k)
re = []
for i in range(n):
re.append(D[k*i:i*k+k])
re.append(D[n*k:])
return re
Ds_K = CreateByK(D_v3,3)
show(Ds_K)
③ 模型评估函数,返回指标精度
# 打包验证过程
def evaluate(val_data,root):
re = []
for i in range(len(val_data)):
re.append(predict_v2(val_data[i],root))
ans = calAccuracy(re,val_data)
print(f"精度是:{ans}")
return ans
④ 组合不同的训练集和验证集,对模型进行训练、评估,记录
def trainByK(Ds_K,Attr):
n = len(Ds_K)
models = []
for i in range(n):
train_data = CreateTrain_data(Ds_K,i)
val_data = Ds_K[i]
print(val_data)
# 生成模型
root = TreeGenerate(train_data,Attr)
# 计算训练集上的精度
acc_train = evaluate(train_data,root)
# 用验证集预测并计算精度
acc_val = evaluate(val_data,root)
models.append({'model':root,'acc':acc_train,'acc_val':acc_val})
return models
⑤ 找出训练集精度和验证集精度之和最高的模型
models = trainByK(Ds_K,Attr)
target = 0
for i in range(len(models)):
if models[i]['acc']+models[i]['acc_val'] > models[target]['acc']+models[target]['acc_val']:
target = i
drawTree(models[target]['model'])
print(f"模型在训练集上的损失:{models[target]['acc']},在验证集上的损失:{models[target]['acc_val']}")