2018-12-20更新,新增内容
2019-01-14更新,对信息熵-信息增益章节中部分文字进行修订
在计算机科学中,树是一种重要数据结构,比如二叉查找树、红黑树等,通过引入“树”数据结构,可以很快缩小数据规模,实现高效查找。一般情况面对的样本通常具有很多特征,对事务的判断不能只从一个角度出发,决策树的思想是先从一个特征入手,通过这次分类使问题规模缩小,同时分类后的子集相比原来样本集更加易于分类,重复这个过程。理想情况下经过多层决策分类,将得到完全纯净的子集,即每个子集中的样本都属于同一个分类
决策树(二元树、三元树或混和决策树型态)是以实例为基础的归纳学习算法,它从一组无次序、无规则实例中推理出以决策树表示的分类规则。构造决策树目的是找出属性和类别间的关系,用它来预测未知记录类别。决策树算法主要有ID3、C4.5(C5.0)、CART、PUBLIC、SLIQ和SPRINT算法等,它们在选择测试属性采用技术、生成的决策树结构、剪枝方法以及时刻,能否处理大数据集等方面都有不同之处。决策树以一种贪婪(greedy)方式迭代地将数据分成不同子集。其中回归树(regression tree)目的是最小化所有子集中的 MSE(均方误差)或MAE(平均绝对误差);而分类树(classification tree)则是对数据进行分割,以使所得到子集的熵或基尼不纯度(Gini impurity)最小
决策树算法以树形结构建立模型,模型本身包含一系列逻辑决策,带有表明根据某一属性做出决策的决策节点,从决策节点引出的分支表示可以做出的选择,决策树由叶节点终止,叶节点表示遵循决策组合的结果。决策树也可依靠计算条件概率来构造,依靠数学计算方法可以取得更好分类效果
决策树与规则学习通过将数据集划分成较小子集来确定用于预测的方式,这些知识之后将以逻辑结构的形式呈现。代表的是对象属性值与对象值之间的一种逻辑关系,决策树仅仅有单一输出,若需多个输出,可建立独立的决策树以处理不同单元
每个枝节点(包括根节点)有4个参数:1.判定函数及特征取值(x<=***),判定为true则决策路径走左,false决策路径走右;2.impurity节点不纯度;3.覆盖样本个数samples,即参与此节点决策的样本数,覆盖样本数越多说明判定函数越稳定;4.value节点取值数组(长度等于类个数),例value=[12,15]表示该节点共27个样本,有12个属于class1,15个属于class2
ID3和C4.5(C5.0)主要用于分类,ID3使用信息增益进行特征选择,后者使用信息增益率进行特征选择。CART可用于分类+回归,对于回归树(最小二乘回归树生成算法)寻找最优切分变量和最优切分点,对于分类树(CART生成算法)使用基尼系数选择最优特征
决策树算法特点:决策树算法不需要特征归一化;不同的不纯度度量函数对决策树的影响在2%以内;决策树或回归树尽量使用二叉树(不纯度的变化不会太快,避免过拟合)
决策树算法优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可处理不相关的特征变量,适合探索性的数据发现
决策树算法缺点:可能产生过拟合问题
从代表整个数据集的根节点开始,该算法选择最能预测目标类的特征,然后案例被分到该特征不同值的分组中,形成了第一组树枝。继续分而治之其他节点,每次都选择最佳候选特征,直至达到停止标准
根:学习的事例集
枝:分类判定条件
叶:分好的各个类(叶节点一般是某一类别所占比例)
节点停止:
1.叶节点上几乎所有案例都属于同一类
2.没有剩余特征来分辨案例区别
3.决策树已达到预先定义的大小限制,如进一步划分的信息增益小于阈值,或者子集的熵值达到阈值
当c=2时把基尼系数曲线和信息熵(k=1/2时)曲线画在同一二维坐标轴上
纵轴表示信息熵或gini值,横轴表示class1的比例p(class2比例1-p),两个方法区别很小
1.预剪枝:一旦决策树达到一定数量决策,或者决策节点仅含有少量错误案例,就停止树生长
2.后剪枝:决策树生长的过大,就根据节点错误率使用修剪准则将决策树减小到更合适的大小
boosting算法通过将很多学习能力较弱的学习算法组合在一起,可以创建一个团队,这比任何一个单独的学习算法都强的多,每个模型都有一组特定的优点或缺点,而使用优点和缺点互补的多种学习方法组合,可以显著提高分类器准确性
c5.0函数可以将boosting算法添加到决策树中,trials表示模型增强团队使用独立决策树数量。该参数应设置一个上限,如果该算法识别出额外的实验并没有提高模型准确性,那么将停止添加决策树
为防止决策树犯更严重错误,c5.0算法允许将一个惩罚因子分配到不同类型错误上,这个惩罚因子设定在一个代价矩阵中,用来指定每种错误相对于其他任何错误有多少倍的严重性
#正确分类时没有代价
#标准混淆矩阵
errcost<-matrix(c(0,1,4,0),nrow=2)
#需要R3.4版本以上才能使用
install.packages("C50")
library(C50)
#train表示一个包含训练数据的数据框,class包含训练数据每一行分类的因子变量
#trials为可选数值(默认1)用于控制自助法循环的次数;costs为可选矩阵用于给出与各型错误相对应成本
m<-C5.0(train,class,trials=1,costs=NULL);
#将列出C5.0决策树对象的一些基本数据,tree size标识该决策树的决策数量
#查看具体决策
summary(m)
p<-predict(m,test,type="class");
#test为包含测试数据的数据框(与训练数据具有相同的特征)
#type-为class或者prob标识预测是最可能的类别值或是原始预测概率,p为向量
1.rpart包介绍
rpart是Recursive Partitioning and Regression Trees(递归分隔与回归树)简称,实现书籍《Classification and Regression Trees》大多数算法功能
2.决策树模型创建
#对决策树进行一些参数设置
#rpart.contral参数
rpart.control(minsplit=20,minbucket=round(minsplit/3),cp=0.01,maxcompete=4, maxsurrogate=5,usesurrogate=2,xval=10,surrogatestyle=0,maxdepth=30)
#minsplit枝节点中的最小观察数(指大于等于20则该节点会继续分划下去,否则停止)
#minbucket叶节点最小观察数
#cp-complexity parameter指某个点复杂度,对每一步拆分,模型拟合优度R^2必须提高的程度
#xval是10折交叉验证
#maxdepth树深度
ct<-rpart.control(xval=10,minsplit=10,cp=0.1)
#ecoli数据集
url<-'http://www.wekaleamstudios.co.uk/wp-content/uploads/2010/09/ecoli.txt';
ecoli.data<-read.csv(url);
str(ecoli.data);
#保存数据
write.csv(ecoli.data,'ecoli.txt',row.names=FALSE)
#决策回归树模型创建
#na.action:缺失数据处理(默认删除因变量缺失观测而保留自变量缺失观测)
#method:树末端数据类型选择相应的变量分割方法,连续性method='anova',离散型'class',计数型method='poisson',生存分析型method='exp'
#parms用来设置三个参数:先验概率向量(组件先验,正值且总和=1,默认为数据计数比例,向量长度=响应变量类别数)/损失矩阵(组件丢失,默认1须在对角线+正对角线上有0)/分类纯度度量方法(gini默认和information)
#cost非负成本向量(模型中每个变量1个,默认值=1),在拆分枝节点选择特征变量时要考虑缩放(除以cost)
fit<-rpart(class~.,data=ecoli.data[,-1],method="class",control=ct,parms= list(prior=c(0.2,0.2,0.1,0.1,0.1,0.1,0.1,0.1),split="information"))
决策树修剪
建立树模型要权衡两方面问题,一是拟合使分组后变异较小(cp提升的越小越好),另一个要防止过拟合(使模型的误差过大)。前者参数是CP,后者参数是Xerror,故要在Xerror最小情况下也使CP尽量小。利用plotcp函数可视化或者printcp函数选取合适cp值,然后利用prune对决策树进行修剪和优化
#printcp-分裂到哪一层cp是多少,平均相对误差是多少(交叉验证的估计误差xerror,交叉验证估计误差的标准差xstd,平均相对误差xerror(+—)xstd)
printcp(fit)
#两种方法
#一种方法是利用1SE方法寻找xerror+SE的最小点对应的CP值
#绘制CP与Xerror的相关图
plotcp(fit)
或选择具有最小预测误差的决策树
#另一种方法是寻找最小xerror点对应CP值,并由此CP值决定树大小
opt<-which.min(fit$cptable[,"xerror"]);
cp<-fit$cptable[opt,"CP"];
bodyfat_prune<-prune(fit,cp=cp);
print(bodyfat_prune);
决策树结果可视化
library(rpart.plot)
library(rattle)
fancyRpartPlot(fit)
决策树规则解读
asRules(fit)
模型应用
predict(fit,newdata=vdata,type="class")
sklearn中有两类决策树,均采用优化的CART决策树算法
from sklearn.tree import DecisionTreeRegressor
#回归决策树
DecisionTreeRegressor(criterion="mse",
splitter="best",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features=None,
random_state=None,
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
presort=False)
#criterion:string optional,default-mse指定切分质量的评价标准
splitter:string optional,default-best指定节点切分策略,best选择最优切分特征和切分点, random随机切分
max_depth:int or None,optional,default-None,树的最大深度,None表示深度不限直到每个叶 节点都是纯净的,或叶节点包含小于min_samples_split个样本
min_sample_split:int,float,optional,default-2,分裂枝节点需要的最小样本数,float-最 小样本分裂数=ceil(min_sample_split*n_samples)
min_samples_leaf:int,float,optional,default-1,每个叶节点包含的最小样本数,float-叶 节点包含的最小样本数=ceil(min_samples_leaf*n_samples)
max_feature:int,float,string or None, optional(default=None)
(1).如果是整数,则每次节点分裂只考虑max_feature个特征
(2).如果是浮点数(0到1),每次分裂考虑int(max_features * n_features)个特征
(3).如果是字符串'auto',max_features=n_features
(4).如果是字符串'sqrt',max_features=sqrt(n_features)
(5).如果是字符串'log2',max_features=log2(n_features)
(6).如果是None,max_feature=n_feature
random_state:int,RandomState instance or None, optional(default=None)
(1).如果为整数,则指定了随机数生成器种子
(2).如果为RandomState实例,则指定了随机数生成器
(3).如果为None,则使用默认随机数生成器
max_leaf_nodes:int or None,optional(default=None)
(1).如果为None,则叶节点数量不限
(2).如果不为None,则max_depth被忽略
min_impurity_decrease:float,optional(default=0.)如果节点分裂导致不纯度减少,大于或 等于min_impurity_decrease,则分裂该节点.针对分类树不纯度是指信息熵或基尼 指数.回归生成树采用的是平方误差最小化策略,分类生成树采用的是基尼指数或 信息熵最小化策略.加权不纯度的减少量计算公式为:min_impurity_decrease=N_t / N *(impurity - N_t_R / N_t * right_impurity - N_t_L / N_t * left_impurity)其中N是样本总数,N_t是当前节点样本数,N_t_L是分裂后左子节 点样本数,N_t_R是分裂后右子节点样本数.impurity指当前节点基尼指数,
right_impurity指分裂后右子节点基尼指数,left_impurity指分裂后左子节点基 尼指数
#分类决策树
DecisionTreeClassifier(criterion="gini",
splitter="best",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features=None,
random_state=None,
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
class_weight=None,
presort=False)
#criterion:string,optional(default="gini")
(1).criterion='gini',分裂节点时评价准则是Gini指数
(2).criterion='entropy',分裂节点时的评价指标是信息增益
#输出
1.classes_:array of shape = [n_classes] or a list of such arrays
类别标签值
2.feature_importances_ : array of shape = [n_features]
特征重要性,值越高特征越重要
特征重要性为该特征导致的评价准则(标准化的)总减少量
3.max_features_ : int
max_features推断值
4.n_classes_ : int or list
类别数量
5.n_features_ : int
执行fit后,特征数量
6.n_outputs_ : int
执行fit后,输出数量
7.tree_ : Tree object
树对象,即底层决策树
#使用方法
1.fit(X,y):训练模型
2.predict(X):预测
3.predict_log_poba(X):预测X为各个类别的概率对数值
4.predict_proba(X):预测X为各个类别的概率值(分类树与回归树类似,都是叶节点包含样本取值的均值)