目录

  • python实现
    • 分步
    • 源代码(全部)
  • 测试集1(波士顿房价数据集)
  • 测试集2(糖尿病数据集)
  • 总结

python实现

分步

  • 划分数据子集(左子树划分比指定值小的样本集合,右子树划分比指定值大的样本集合)

    import numpy as np
    #获取数据子集,分类与回归的做法相同
    #将数据集根据划分特征切分为两类
    def split_dataset(data_x,data_y,fea_axis,fea_value):'''input:data_x(ndarry):特征值data_y(ndarry):标签值fea_axis(int):进行划分的特征编号(列数)fea_value(int):进行划分的特征对应特征值output:data_x[equal_Idx],data_y[equal_Idx](ndarry):特征值等于(大于等于)目标特征值的样本与标签data_x[nequal_Idx],data_y[nequal_Idx](ndarry):特征值不等于(小于)目标特征的样本与标签'''if  isinstance(fea_value,int) or isinstance(fea_value,float): #如果特征值为浮点数(连续特征值),那么进行连续值离散化equal_Idx = np.where(data_x[:,fea_axis]<=fea_value) #找出特征值大于等于fea_alue的样本序号nequal_Idx = np.where(data_x[:,fea_axis]>fea_value) #找出特征值小于fea_alue的样本序号else:equal_Idx = np.where(data_x[:,fea_axis]==fea_value) #找出特征值等于fea_alue的样本序号nequal_Idx = np.where(data_x[:,fea_axis]!=fea_value) #找出特征值不等于fea_alue的样本序号return data_x[equal_Idx],data_y[equal_Idx],data_x[nequal_Idx],data_y[nequal_Idx]
    
  • 叶子结点的均值计算

    import numpy as np
    #叶子结点均值计算
    def reg_leaf(data_y):'''input:data_y(array):标签值output:(float)均值'''return np.mean(data_y)
    
  • 计算数据集总方差

    #计算数据集的总方差
    def reg_err(data_y):'''input:data_y(array):标签值output:(float):总方差'''return np.var(data_y)*len(data_y)
    
  • 选取划分特征以及对应的特征值

    def classify_get_best_fea(data_x,data_y,ops=(1,4)):'''input:data_x(ndarry):特征值data_y(array):标签值ops(tuple):第一个数为决策树停止划分的最小精度,第二个数为决策树停止划分的最小划分数output:best_fea_idx(int):最好划分特征的下标best_fea_val(float):最好划分特征对应的特征值'''m,n = np.shape(data_x)final_s = ops[0] #停止的精度final_n = ops[1] #停止的样本最小划分数#只有一类样本时,输出叶子结点,以及它对应的均值if len(np.unique(data_y))==1:return None,reg_leaf(data_y)#获取最优特征和特征值total_err = reg_err(data_y)  #总的误差best_err = np.infbest_fea_idx = 0best_fea_val = 0for i in range(n):feas = np.unique(data_x[:,i])for fea_val in feas:data_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,i,fea_val)#不满足最小划分集合,不进行计算if data_D1_x.shape[0]<final_n or data_D2_x.shape[0]<final_n:continuecon_err = reg_err(data_D1_y)+reg_err(data_D2_y)if con_err<best_err:best_err = con_errbest_fea_idx = ibest_fea_val = fea_val#预剪枝,求解的误差小于最小误差停止继续划分if total_err-best_err<final_s:return None,reg_leaf(data_y)#一直无法进行划分,在这里进行处理data_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,best_fea_idx,best_fea_val)if data_D1_x.shape[0]<final_n or data_D2_x.shape[0]<final_n:return None,reg_leaf(data_y)return best_fea_idx,best_fea_val
    
  • CART回归树的生成(递归生成)

    def reg_create_tree(data_x,data_y,ops=(1,4)):fea_idx,fea_val = classify_get_best_fea(data_x,data_y,ops)if fea_idx == None:return fea_val#递归建立CART回归决策树my_tree = {}my_tree['fea_idx'] = fea_idxmy_tree['fea_val'] = fea_valdata_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,fea_idx,fea_val)my_tree['left'] = reg_create_tree(data_D1_x,data_D1_y,ops)my_tree['right'] = reg_create_tree(data_D2_x,data_D2_y,ops)return my_tree
    

    字典格式为:{’‘fea_idx’’:’‘当前最好划分特征下标’’,’‘fea_val’’:’‘对应特征值’’,’‘left’’:{…},“right”:{…}}。

  • 预测函数

    #测试操作
    import re
    #预测一条测试数据结果
    def classify(inputTree,testdata):'''input:inputTree(dict):CART分类决策树xlabel(list):特征属性列表testdata(darry):一条测试数据特征值output:classLabel(int):测试数据预测结果'''first_fea_idx = inputTree[list(inputTree.keys())[0]]  #对应的特征下标fea_val = inputTree[list(inputTree.keys())[1]]  #对应特征的分割值classLabel = 0.0 #定义变量classLabel,默认值为0if testdata[first_fea_idx]>=fea_val:  #进入右子树if type(inputTree['right']).__name__ == 'dict':classLabel = classify(inputTree['right'],testdata)else:classLabel = inputTree['right']else:  #进入左子树if type(inputTree['left']).__name__ == 'dict':classLabel = classify(inputTree['left'],testdata)else:classLabel = inputTree['left']return round(classLabel,2)#预测所有测试数据结果
    def classifytest(inputTree, testDataSet):'''input:inputTree(dict):训练好的决策树xlabel(list):特征值标签列表testDataSet(ndarray):测试数据集output:classLabelAll(list):测试集预测结果列表'''    classLabelAll = []#创建空列表for testVec in testDataSet:#遍历每条数据classLabelAll.append(classify(inputTree, testVec))#将每条数据得到的特征标签添加到列表return  np.array(classLabelAll)
    

源代码(全部)

import numpy as np
import re
#获取数据子集,分类与回归的做法相同
#将数据集根据划分特征切分为两类
def split_dataset(data_x,data_y,fea_axis,fea_value):'''input:data_x(ndarry):特征值data_y(ndarry):标签值fea_axis(int):进行划分的特征编号(列数)fea_value(int):进行划分的特征对应特征值output:data_x[equal_Idx],data_y[equal_Idx](ndarry):特征值等于(大于等于)目标特征值的样本与标签data_x[nequal_Idx],data_y[nequal_Idx](ndarry):特征值不等于(小于)目标特征的样本与标签'''if  isinstance(fea_value,int) or isinstance(fea_value,float): #如果特征值为浮点数(连续特征值),那么进行连续值离散化equal_Idx = np.where(data_x[:,fea_axis]<=fea_value) #找出特征值大于等于fea_alue的样本序号nequal_Idx = np.where(data_x[:,fea_axis]>fea_value) #找出特征值小于fea_alue的样本序号else:equal_Idx = np.where(data_x[:,fea_axis]==fea_value) #找出特征值等于fea_alue的样本序号nequal_Idx = np.where(data_x[:,fea_axis]!=fea_value) #找出特征值不等于fea_alue的样本序号return data_x[equal_Idx],data_y[equal_Idx],data_x[nequal_Idx],data_y[nequal_Idx]#叶子结点均值计算
def reg_leaf(data_y):'''input:data_y(array):标签值output:(float)均值'''return np.mean(data_y)#计算数据集的总方差
def reg_err(data_y):'''input:data_y(array):标签值output:(float):总方差'''return np.var(data_y)*len(data_y)def classify_get_best_fea(data_x,data_y,ops=(1,4)):'''input:data_x(ndarry):特征值data_y(array):标签值ops(tuple):第一个数为决策树停止划分的最小精度,第二个数为决策树停止划分的最小划分数output:best_fea_idx(int):最好划分特征的下标best_fea_val(float):最好划分特征对应的特征值'''m,n = np.shape(data_x)final_s = ops[0] #停止的精度final_n = ops[1] #停止的样本最小划分数#只有一类样本时,输出叶子结点,以及它对应的均值if len(np.unique(data_y))==1:return None,reg_leaf(data_y)#获取最优特征和特征值total_err = reg_err(data_y)  #总的误差best_err = np.infbest_fea_idx = 0best_fea_val = 0for i in range(n):feas = np.unique(data_x[:,i])for fea_val in feas:data_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,i,fea_val)#不满足最小划分集合,不进行计算if data_D1_x.shape[0]<final_n or data_D2_x.shape[0]<final_n:continuecon_err = reg_err(data_D1_y)+reg_err(data_D2_y)if con_err<best_err:best_err = con_errbest_fea_idx = ibest_fea_val = fea_val#预剪枝,求解的误差小于最小误差停止继续划分if total_err-best_err<final_s:return None,reg_leaf(data_y)#一直无法进行划分,在这里进行处理data_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,best_fea_idx,best_fea_val)if data_D1_x.shape[0]<final_n or data_D2_x.shape[0]<final_n:return None,reg_leaf(data_y)return best_fea_idx,best_fea_valdef reg_create_tree(data_x,data_y,ops=(1,4)):'''input:data_x(ndarry):特征值data_y(array):标签值ops(tuple):第一个数为决策树停止划分的最小精度,第二个数为决策树停止划分的最小划分数output:my_tree(dict):生成的CART决策树字典'''fea_idx,fea_val = classify_get_best_fea(data_x,data_y,ops)if fea_idx == None:return fea_val#递归建立CART回归决策树my_tree = {}my_tree['fea_idx'] = fea_idxmy_tree['fea_val'] = fea_valdata_D1_x,data_D1_y,data_D2_x,data_D2_y = split_dataset(data_x,data_y,fea_idx,fea_val)my_tree['left'] = reg_create_tree(data_D1_x,data_D1_y,ops)my_tree['right'] = reg_create_tree(data_D2_x,data_D2_y,ops)return my_tree#预测一条测试数据结果
def classify(inputTree,testdata):'''input:inputTree(dict):CART分类决策树xlabel(list):特征属性列表testdata(darry):一条测试数据特征值output:classLabel(int):测试数据预测结果'''first_fea_idx = inputTree[list(inputTree.keys())[0]]  #对应的特征下标fea_val = inputTree[list(inputTree.keys())[1]]  #对应特征的分割值classLabel = 0.0 #定义变量classLabel,默认值为0if testdata[first_fea_idx]>=fea_val:  #进入右子树if type(inputTree['right']).__name__ == 'dict':classLabel = classify(inputTree['right'],testdata)else:classLabel = inputTree['right']else:if type(inputTree['left']).__name__ == 'dict':classLabel = classify(inputTree['left'],testdata)else:classLabel = inputTree['left']return round(classLabel,2)#预测所有测试数据结果
def classifytest(inputTree, testDataSet):'''input:inputTree(dict):训练好的决策树xlabel(list):特征值标签列表testDataSet(ndarray):测试数据集output:classLabelAll(list):测试集预测结果列表'''    classLabelAll = []#创建空列表for testVec in testDataSet:#遍历每条数据classLabelAll.append(classify(inputTree, testVec))#将每条数据得到的特征标签添加到列表return  np.array(classLabelAll)

测试集1(波士顿房价数据集)

一共拥有十三个属性如下图所示:

导入数据集并训练CART回归树:

#波士顿房价数据集
from sklearn.datasets import load_boston
boston = load_boston()data = boston.data
target = boston.target# X = data[:200,:]
# y = target[:200]x_train,x_test,y_train,y_test = train_test_split(X,y,test_size = 0.3,random_state = 666)
#生成CART回归树
cartTree = reg_create_tree(x_train,y_train)
print(cartTree)

训练得到的CART树如下图所示:

进行预测可以得到结果如下图所示:

classlist=classifytest(cartTree,x_test)
print('预测数据',classlist)
print('真实数据'.y_test)
print("平均误差为:",abs(np.sum(classlist)-np.sum(y_test))/len(y_test))


测试集2(糖尿病数据集)

一共拥有十个属性如下图所示:

导入数据集并训练CART回归树:

#糖尿病数据集
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()data = diabetes.data
target = diabetes.targetX = data[:500,:]
y = target[:500]x_train,x_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state = 666)
#生成CART回归树
cartTree = reg_create_tree(x_train,y_train)
print(cartTree)

训练得到的CART树如下图所示(500条数据):

进行预测可以得到结果如下图所示:

classlist=classifytest(cartTree,x_test)
print('预测数据',classlist)
print('真实数据',y_test)
print("平均误差为:",abs(np.sum(classlist)-np.sum(y_test))/len(y_test))


总结

(1)使用CART回归树进行预测的数据集标签值都是连续的,当然也可以使用离散的标签值做分类问题,只不过这样做没有必要。对于各项特征对应的特征值可以是连续的也可以是离散的,不同特征之间的数量级也可以不同,因为划分时各特征之间是相互独立的。(对于神经网络来说则需要进行归一化处理)

(2)可以使用平均误差(误差之和的平均值)、均方误差(误差的平方和的平均值)对模型的精度进行评估。

(3)计算方法与CART分类树的基尼系数不同,CART回归树使用均方差的方法。

实验三:CART回归决策树python实现(两个测试集)(二)|机器学习相关推荐

  1. [Python从零到壹] 十二.机器学习之回归分析万字总结全网首发(线性回归、多项式回归、逻辑回归)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. 实验三:CART分类决策树python实现(两个测试集)(一)|机器学习

    目录 python实现 分步 源代码(全部) 测试集1(鸢尾花集) 测试集2(红酒品类数据集) 总结 python实现 分步 划分数据子集(注意区分离散特征值和连续特征值) #获取数据子集,分类与回归 ...

  3. python鸢尾花分类svm测试集_使用SVM对鸢尾花分类

    使用SVM对鸢尾花分类 百度AI Studio中的一个入门项目,增加了自己在实践时的一些注释,对小白来说阅读更顺畅.源码和数据在github上. 任务描述: 构建一个模型,根据鸢尾花的花萼和花瓣大小将 ...

  4. python划分训练集和测试集_杨涛的Python机器学习3:单特征与多特征、训练集与测试集,杨桃...

    本人CSDN博客专栏:https://blog.csdn.net/yty_7 Github地址:https://github.com/yot777/ 单特征与多特征 在上一节标签和特征的示例中,我们使 ...

  5. Python批量获取VOC测试集的类别

    使用 Python 读取 XML 文件,获取所有类别. # coding=utf-8 # @Author: FSJohn # @Date: 2022.3.21 import xml.etree.Ele ...

  6. 机器学习(三)逻辑回归以及python简单实现

    虽然有回归两个字,但是依然是解决的时分类问题,是最经典的二分类算法. 分类算法有很多,例如支持向量机和神经网络.而逻辑回归算法应用的比较广,往往是优先选择的算法. Sigmod函数 表达式: g(z) ...

  7. R语言ineq算基尼系数_R语言中自编基尼系数的CART回归决策树的实现

    原文链接 本文为了说明回归树的构造(使用CART方法),考虑以下模拟数据集, > set.seed(1) > n=200 > X1=runif(n) > X2=runif(n) ...

  8. 编译原理实验三:对完整程序进行词法分析并输出对应的二元组

    实验要求 [任务介绍]根据给定源语言的构词规则,从任意字符串中识别出该语言所有的合法的单词符号,并以等长的二元组形式输出. [输入]字符串形式的源程序. [输出]单词符号所构成的串(流),单词以等长的 ...

  9. 虚拟创业云|BBC幼儿英语启蒙动画小鸟三号 3rd and Bird 全两季50集3-5岁

    虚拟创业云|非常推荐BBC 幼儿英语的小鸟三号,因为第一次观看,即使作为大人的我,也被他又没的水彩画画风所吸引,就别提小孩子了.而且配音也非常有特点,非常容易给孩子留下深刻的印象,你的孩子一定会追剧看 ...

最新文章

  1. Java并发- 读写锁中的性能之王:StampedLock
  2. 解决Jira和Confluence访问打开越来越缓慢问题
  3. 多媒体流信息提取工具 ffprobe 简介
  4. ORACLE 11G安装全过程
  5. 产品认知:真正厉害的产品经理,都是“本质思维”的高手
  6. linux下后台启动springboot项目
  7. # WordPress 除了主页以外的页面都提示Not Found的问题(Centos)
  8. 思科交换机配置试题_【干货】思科交换机路由器怎么配置密码?
  9. 大数据中心周边辐射大吗_“一部手机读云南”上线 力争建成国家方志大数据中心西南中心...
  10. python用来自动修改pdf_python实现从pdf文件中提取文本,并自动翻译的方法
  11. 解决mysql地区时间错误_mysql time zone时区的错误解决
  12. word2010 同时打开多个文档的解决办法
  13. MacOs终端忽略大小写
  14. android 瀑布流StaggeredGridLayoutManager重新排序后,顶部留白处理
  15. 程序员必备技能之上传代码(Github篇)
  16. this在什么时候为undefined
  17. 平淡人生(一)- 360发展历程及人物杂记
  18. uniapp 动态设置导航栏标题 副标题 背景图片 web-view
  19. 无密码解锁iPhone
  20. 我是如何从流水线工人到程序员?(2008-2018)

热门文章

  1. #Geek Talk# AI and FinTech,投资阿里巴巴的 Benson Tam 也会跟大家一起 Talk
  2. C51——简单的防盗报警器
  3. 关于Linux mint更换中文字体后全局楷体修改办法
  4. ides样式及字体设置
  5. 大类资产配置(三)市场择时能力模型T-M
  6. XSS 一次跨站拆分法的应用
  7. Oracle AWR 阙值影响历史执行计划
  8. 学习Android笔记
  9. 如何提升APP日活(DAU)?
  10. 第一章 神经网络如何工作(附Python神经网络编程.pdf)