机器学习——编程从零实现决策树【二】

本文介绍了如何使用Python和numpy实现从零开始构建决策树,包括划分训练集和验证集、优化预测过程(处理新属性值),以及使用k折交叉验证来选择性能更好的模型。最终通过计算训练集和验证集的精度,确定最佳模型。
摘要由CSDN通过智能技术生成

第一节的内容:机器学习——编程实现从零构造训练集的决策树-CSDN博客

目录

v2:划分验证集,优化预测

1)划分训练集和验证集

2)完善预测过程

3)训练模型并验证

v3:k折交叉验证

1)理论

2)实践


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']}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值