本次为学生时期所写的实验报告,代码程序为课堂学习和自学,对网络程序有所参考,如有雷同,望指出出处,谢谢!

基础知识来自教材:李航的《统计学习方法》

本人小白,仍在不断学习中,有错误的地方恳请大佬指出,谢谢!

本次实验采用ID3算法进行决策树的建立

一、代码实现(R语言)

1.前置函数编写

#前置函数:#1.熵值计算函数
my_entropy<-function(X){    #X为n维向量,在决策树模型中,X指其各类取值的频数分布向量     p = prop.table(X)         #prop.table为频率统计函数;p:包含每一个xi所占总体比例的n维向量single_value <- p*log(p)  #single_value储存每一个p对应的熵值,为n维向量single_value[X == 0] <- 0     #如果有0概率,令0log0=0value <- -sum(single_value)   #value存储每个xi的熵值和,得到向量X的总熵value
}#2.信息增益计算函数
my_extra <- function(X,y){  #X,y均为向量,在决策树模型中一般认为X为指定的特征向量,y为因变量       #计算经验熵(未分类时y的总熵)former_entropy = my_entropy(as.vector(table(y))) #使用table求y的频数分布表,再将其向量化,计算总熵table = table(X,y)           #建立X与y的频数分布表格,其中行名为特征变量X的各可能取值,列名为因变量y的可取值;#第(i,j)元的数值即为给定特征变量取值为i时y的种类为j的个数#计算特征的每个取值所占的比例p=prop.table(rowSums(table(X,y)))         #rowSums:表示每一行的数值和,rowSums(table)相当于特征X每个取值的频数分布向量#prop.table为频率统计函数#每个给定特征取值下y的熵;single_entropy = apply(table,1,my_entropy)      #使用apply并行计算,按行的顺序,对每一行向量求熵#每一行向量内容为给定特征的某个取值下y的频数分布#给定X下y的条件熵(即为每个特征取值的比例乘上取该值时y的熵的总和)after_entropy = p%*%single_entropy     #信息增益:经验熵-条件熵extra =former_entropy-after_entropyextra
}

2.ID3决策树函数编写

#本函数采用data.tree程序包来绘制各结点,需先加载data.tree程序包
library(data.tree)  #本函数涉及数据框的数据处理等操作,需先加载dplyr程序包,以便使用函数selectlibrary(dplyr)#决策树函数
my_decision_tree<- function(data,y,root,threshold){    #data数据集包含特征变量和因变量(要求最后一列为因变量);#y为单独输入的因变量向量;#root是Node {data.tree}定义的事先已生成根结点的"Node"类型的值,可自行命名;#threshold为阈值if(length(levels(factor(y)))==1){    #1.如果y值中种类只有一类,则直接生成只有该类名称的叶结点                      #level和factor函数提取y中含有的种类,种类只有一类时,该函数提取出的值的长度为1class = levels(factor(y))            #y的种类        child <- root$AddChild(class)        #生成树的叶结点 (标签为y的种类名)root$feature <-colnames(data)[ncol(data)]  #此时根节点的特征即为因变量y的名称 child$feature <- ""                        #叶结点不需选取任何属性值}else if(ncol(data)==1){                        #2.如果可选特征变量为0,则直接生成叶结点,叶结点中的类别为y值中个数最多对应的类别    index = as.numeric(which.max(table(y)))    #在y的频数分布表中寻找个数最多的类对应的下标 class = names(table(y)[index][1])    #y的个数最多的种类        child <- root$AddChild(class)        #生成树的叶结点 (标签为y的类名)           root$feature <-colnames(data)[ncol(data)]  #此时根节点的特征即为因变量y的名称 child$feature <- ""              #叶结点不需选取任何属性值}else if(ncol(data)==2){
#3.只有一个特征变量时,根据阈值判断:直接根据该特征变量的各取值分类或者直接生成叶结点(不分类)extra = my_extra(data[,1],data[,2]) #信息增益if(extra<threshold){
#(1)若信息增益达不到给定阈值,则直接生成叶结点,叶结点中的类别为y值中个数最多对应的类别index = as.numeric(which.max(table(y)))    #在y的频数分布表中寻找个数最多的类对应的下标class = names(table(y)[index][1])  #y的个数最多的种类child <- root$AddChild(class)      #生成树的叶结点 (标签为y的类名)root$feature <-colnames(data)[ncol(data)]  #此时根节点的特征即为因变量y的名称  child$feature <- ""                #叶结点不需选取任何属性值}else{
#(2)若信息增益达到阈值要求root$feature<- colnames(data)[1]    #①生成树的结点,标签为特征变量的名称         #②下面使用split函数将数据按特征列的各取值进行分割成多个列表,决策树模型中,每一个列表对应原数据集经特征变量各个取值分类后的子集vector=select(data,-1)    #特征集(去除上述最佳特征变量的数据集),实际上此时只有y的数据        rule=factor(data[,1])     #分割规则(按该特征列的取值进行分割)                    dataselected = split(vector,rule,drop = TRUE) nclass=length(dataselected)     #特征变量可能取值的种类数(即可分割成多少个子集)            #③遍历每一个子集for (i in 1:nclass) {        #(i)建立该父结点(bestfeature)下的子结点childname = names(dataselected)[i]   #该子结点的名称(即为给定的特征变量的取值)child <- root$AddChild(childname)    #建立以特征值为名称的子结点#(ii)更新数据datanew = dataselected[[i]]         #datanew为新分类下(给定特征取值下)子集的数据集(实际上此时只有y的数据) ynew = datanew[,ncol(datanew)]      #ynew为新分类下(给定特征取值下)数据集的因变量y所在的向量#(iii)使用更新的数据集递归地使用该函数,再次生成各子结点my_decision_tree(datanew,ynew,child,threshold) #由于datanew列数已经为1,该递归过程实际上是直接生成叶结点的过程,叶结点中                                   的类别为y值中个数最多对应的类别    }}}else{                                      #4.若不是以上三种情况之一,则进行特征选择#(1)对各特征向量进行信息增益的计算:
total_extra = rep(NA,(ncol(data)-1))      #存储各个给定特征变量下的y的信息增益,维数为特征变量的个数for (i in 1:(ncol(data)-1)) {total_extra[i] = my_extra(data[,i],y)}#(2)根据阈值判断:直接生成叶结点,或进行特征选择
if(max(total_extra)<threshold){
#①若最大的信息增益仍达不到给定阈值,则直接生成叶结点:叶结点中的类别为y值中个数最多对应的类别index = as.numeric(which.max(table(y)))   #在y的频数分布表中寻找个数最多的类对应的下标class = names(table(y)[index][1]) #y的个数最多的种类child <- root$AddChild(class)     #生成树的叶结点 (标签为y的类名)    root$feature <-colnames(data)[ncol(data)]  #此时根节点的特征即为因变量y的名称  child$feature <- ""          #叶结点不需选取任何属性值}else{
#②若信息增益达到阈值要求:选取最佳特征(对应信息增益最大的特征变量)#(i)选取最佳特征index = which.max(total_extra)      #最大的信息增益对应的下标bestfeature = colnames(data)[index] #最大的信息增益对应的特征变量的名称#(ii)父结点root$feature<- bestfeature     #根结点处生成一个以最佳特征变量为标签的结点,将以该特征变量的各个取值进行分类#(iii)获得子集数据集:使用split进行数据集字符串的分割,以避免反复使用for循环减慢运算速度vector=data[,-index]          #特征集(去除上述最佳特征变量的数据集)rule=factor(data[,index])     #分割规则(按该特征列的取值进行分割)dataselected = split(vector,rule,drop = TRUE) nclass=length(dataselected)   #特征变量可能取值的种类数(即可分割成多少个子集) #(iv)遍历每一个子集for (i in 1:nclass) {        #建立该父结点(bestfeature)下的子结点childname = names(dataselected)[i] #该子结点的名称(即为给定的特征变量的取值)  child <- root$AddChild(childname)  #建立以特征值为名称的子结点#更新数据datanew = dataselected[[i]]        #datanew为新分类下子集的数据集 ynew = datanew[,ncol(datanew)]     #ynew为新分类下数据集的因变量y所在的向量   #使用更新的数据集递归地使用该函数,再次生成各子结点my_decision_tree(datanew,ynew,child,threshold)}}}
}

三、检验

本次实验使用UCI数据库中Iris数据集

1.数据处理(离散化)

(1)输入

#数据处理:iris离散化
#使用chiM算法对UCI数据库的iris数据集进行离散化
library(discretization)
iris <- read.csv("F:/大三下/数据挖掘/UCI数据集
/Iris/iris.data",header = FALSE)
colnames(iris)=c("Sepal.Length", "Sepal.Width","Petal.Length",
"Petal.Width", "Species")
result<-chiM(iris,alpha=0.05)#离散后的数据为
iris_discrete <- result$Disc.data
y = iris_discrete [,5]#查看离散处理中的各阈值
result$cutp

(2)输出结果与分析

> result$cutp

[[1]]

[1] 5.45 5.75 7.05

[[2]]

[1] 2.95 3.35

[[3]]

[1] 2.45 4.75 5.15

[[4]]

[1] 0.80 1.75

分析:
(1)对于第一个特征:"Sepal.Length":可知离散过程中按照阈值[5.45 ,5.75,7.05]分为四类:由数字1、2、3、4表示;

(2)对于第二个特征:"Sepal.Width":可知离散过程中按照阈值[2.95, 3.35]分为三类:由数字1、2、3表示;

(3)对于第三个特征:"Petal.Length":可知离散过程中按照阈值[2.45, 4.75, 5.15]分为四类:由数字1、2、3、4表示;

(4)对于第四个特征:"Petal.Width":可知离散过程中按照阈值[0.80, 1.75]分为三类:由数字1、2、3表示;

2.使用上述函数建立决策树

(1)输入

#检验
#载入程序包
library(data.tree)
library(dplyr)#1.根结点命名为"iris"
mytree <- Node$new("iris")       #2.建模
my_decision_tree(iris_discrete,y,mytree,threshold=0.2)  #3.绘制决策树
print(mytree, "feature")                  

(2)输出结果与分析:

> print(mytree, "feature")

levelName      feature

1  iris                        Petal.Length

2   |--1                            Species

3   |   °--Iris-setosa

4   |--2                            Species

5   |   °--Iris-versicolor

6   |--3                        Petal.Width

7   |   |--2                        Species

8   |   |   °--Iris-versicolor

9   |   °--3                        Species

10  |       °--Iris-virginica

11  °--4                            Species

12      °--Iris-virginica

分析:

  1. 生成决策树如上所示
  2. 可见该决策树:最优特征是”Petal.Length”:

(1)当Petal.Length=1时,分类为Iris-setosa(山鸢尾)

(2)当Petal.Length=2时,分类为Iris-versicolor(杂色鸢尾)

(3)当Petal.Length=3时,再按照”Petal.Width”进行分类:

①当Petal.Width=2 时,分类为Iris-versicolor(杂色鸢尾)

②当Petal.Width=3 时,分类为Iris-virginica (弗吉尼亚鸢尾)

(4)当Petal.Length=4时,分类为Iris-virginica (弗吉尼亚鸢尾

3.结合输出结果,绘制直观树状图如下:

三、小结

本次实验主要编写ID3算法建立决策树的程序:关键在于对决策树构建原理的理解:1.首先应明确两个判别条件:(1)当y中只有一类时;(2)没有可选属性值时:直接生成叶结点。在算法中为了避免产生严重的过拟合,采用设定阈值的方式:当信息增益达不到所涉阈值,样本点个数过少等情况发生时,可直接生成叶结点。2.对于不能直接判别生成叶结点的情况:进行最优特征值的选择,选取信息增益最大的且超过阈值的特征为最优特征,以最优特征的各个取值进行数据集的划分。3.对划分的每一个子集,递归地使用以上算法,对其进行各节点的判断生成、以及子集中的最优特征值的选择。

本次实验难度较大,主要困难在于递归算法和直观结点的生成;对递归算法是初步了解,学习不深,同时递归算法也难以调试,在报错时难以及时发现解决报错问题;而结点生成一般做法是使用list列表形式进行建立,但由于难以解决报错问题,采用了Node.tree这种较难理解但容易实现的结点生成方法。在查询众多资料后结合所学才产生本次实验所用函数,于是虽然该函数能建立一般的决策树模型,但也存在着函数编写过于冗长、判断语句的嵌套使用过于繁琐的问题。

数据挖掘-决策树算法的R实现相关推荐

  1. 分类算法——决策树算法及其R实现

    决策树定义 以鸢尾花为例子来说明: 观察上图,判决鸢尾花的思考过程可以这么来描述:花瓣的长度小于2.4cm的是setosa(图中绿色的分类),长度大于2.4cm的呢?可以通过宽度来判别,宽度小于1.8 ...

  2. ID3和C4.5分类决策树算法 - 数据挖掘算法(7)

    (2017-05-18 银河统计) 决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来判断其可行性的决策分析方法,是直观运用概率分析的一种图解法.由于这种决策分支画 ...

  3. 【数据挖掘】决策树算法简介 ( 决策树模型 | 模型示例 | 决策树算法性能要求 | 递归创建决策树 | 树根属性选择 )

    文章目录 I . 决策树模型 II . 决策树模型 示例 III . 决策树算法列举 IV . 决策树算法 示例 V . 决策树算法性能要求 VI . 决策树模型创建 ( 递归创建决策树 ) VII ...

  4. 数据挖掘算法之决策树算法总结

    机器学习中,决策树是一个预测模型:它代表的是对象属性值与对象值之间的一种映射关系.树中每个节点表示某个对象,每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应具有上述属性值的子对象.决策树仅有单 ...

  5. 决策树C4.5算法 c语言实现,数据挖掘十大经典算法(1) C4.5_决策树算法

    数据挖掘十大经典算法(1) C4.5_决策树算法 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每 ...

  6. 决策树算法-理清每个细节-附R+Python代码

    2018-12-20更新,新增内容 2019-01-14更新,对信息熵-信息增益章节中部分文字进行修订 一.决策树概念 在计算机科学中,树是一种重要数据结构,比如二叉查找树.红黑树等,通过引入&quo ...

  7. r语言 C4.5 剪枝是用什么算法_决策树算法

    决策树算法,从名字中也可以理解到该算法是以树形结构建立模型的,该算法主要根据分层和分割的方式将预测变量空间划分为一系列简单区域.对某个给定的待预测的观测值,用它所属区域中训练的平均值或众数进行预测.决 ...

  8. 【数据挖掘】-决策树算法+代码实现(七)

    目录 从例子出发 算法原理 算法的优缺点 关于剪枝 代码实现 随机森林.GBDT.XGBOOST 总结 决策树(decision tree):是一种基本的分类与回归方法,此处主要讨论分类的决策树. 在 ...

  9. 数据挖掘之C4.5决策树算法

    1.决策树算法实现的三个过程: 特征选择:选择哪些特征作为分类的标准是决策树算法的关键,因此需要一种衡量标准来进行特征的确定,不同的决策树衡量标准不同.例如C4.5决策树就是以信息增益率来作为衡量标准 ...

最新文章

  1. php和python哪个好-写后端 Python,nodejs和php哪个更好一些?
  2. python四十一:hashlib模块
  3. JDBC之二:DAO模式
  4. java 2d 教程_Java 2D开发技巧之“灯光与阴影”
  5. std::map用法总结
  6. php 非递归调用,php 无限分类(非递归)
  7. Java ArrayList removeRange()方法与示例
  8. linux fpga 开发板,香蕉派BPI-F2S ,四核Linux工业级应用的开源硬件开发板,FPGA教学套装...
  9. 无维护地稳定运行了8 年的 Hyperic HQ
  10. python运维脚本部署jdk_Jenkins 为Jenkins添加Windows Slave远程执行python项目脚本
  11. 【CCCC】L2-011 玩转二叉树 (25分),二叉树建树与遍历(我讨厌树,@L2-006)
  12. HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)
  13. c语言简单图形库,C语言图形库简单对比及EGE库的安装小手册
  14. STKO助力OpenSEES系列:结构模态分析以及动力特性(MDOF与等效SDOF验证)
  15. 深入剖析RGB、CMYK、HSB、LAB
  16. 【Driver Booster 9 PRO】 驱动更新工具 提升游戏性能
  17. ORB、SURF、SIFT特征点提取方法和ICP匹配方法
  18. 实体零售纷纷转型,苏宁、乐语到底能给我们带来哪些启示?
  19. Agilent RF fundamentals (7) Oscillator characterization
  20. 如何使用css实现三角形?

热门文章

  1. buu-[Zer0pts2020]Can you guess it?
  2. 数据库综合查询与视图操作
  3. Unity中使用模板测试模拟Mask组件效果
  4. rss 是什么?有什么用?
  5. redis,Redis Desktop Manger和IDEA Iedis的安装和使用
  6. 服务器干货分享!做APP服务器怎么选择?
  7. 手机锁屏时显示无服务器,手机总显示“请勿遮挡屏幕顶端”?别慌,它其实是一个贴心的功能...
  8. Celery+django+redis异步执行任务
  9. Hbuilder屏幕旋转
  10. sql oracle 退格键,Oraclesqlplus中方向键、退格键的使用是怎样的? 爱问知识人