决策树算法
算法介绍
决策树是一种梳妆结构,它的每一个叶节点对应着一个分类,非叶节点对应着在某个属性上的划分,根据样本在该属性上的不同取值将其划分成若干个子集。对于非纯的叶节点,多数类的标号给出到达这个节点的样本所属的类。构造决策树的核心问题是在每一步如何选择适当的属性对样本做拆分。对一个分类问题,从已知类标记的训练样本中学习并构造出决策书是一个自上而下,分而治之的过程。而实现决策树最经典的算法就属ID3算法了,除此之外还有C4.5、CARTD等等。
ID3算法
ID3算法的核心是在决策树各级节点上选择属性时,用信息增益(information gain)作为属性的选择标准,以使得在每一个非叶结点进行测试时,能获得关于被测试记录最大的类别信息(即来帮助确定每个节点应采用的合适属性)。
算法思想
自根至叶的递归过程,在每个中间结点寻找一个“划分”(split or test)属性。
递归的三种停止条件(对应流程图中各个标记):
(1) 当前结点包含的样本全属于同一类别,无需划分;
(2) 当前属性集为空, 或是所有样本在所有属性上取值相同,无法划分;
(3) 当前结点包含的样本集合为空,不能划分.
算法步骤
1.对当前样本集合,计算所有属性的信息增益;
2.选择信息增益最大的属性作为测试属性,把测试属性取值相同的样本划为同一个子样本集;
3.若子样本集的类别属性只含有单个属性,则分支为叶子节点,判断其属性值并标上相应的符号之后返回调用处;否则对子样本集递归调用本算法。
注:图中的标号对应着下图三个递归返回情形,也就是对应三个递归停止条件。
算法特点
- 决策树是一种构建分类模型的非参数方法
- 不需要昂贵的的计算代价
- 决策树相对容易解释
- 决策树是学习离散值函数的典型代表
- 决策数对于噪声的干扰具有相当好的鲁棒性
- 冗余属性不会对决策树的准确率造成不利影响
- 数据碎片问题。随着数的生长,可能导致叶结点记录数太少,对于叶结点代表的类,不能做出具有统计意义的判决
- 子树可能在决策树中重复多次。使决策树过于复杂
算法优劣
优点
1.决策树易于理解和实现. 人们在通过解释后都有能力去理解决策树所表达的意义。
2. 对于决策树,数据的准备往往是简单或者是不必要的 . 其他的技术往往要求先把数据一般化,比如去掉多余的或者空白的属性。
3. 能够同时处理数据型和常规型属性。其他的技术往往要求数据属性的单一。
4.在相对短的时间内能够对大型数据源做出可行且效果良好的结果。
5.对缺失值不敏感
6.可以处理不相关特征数据
7.效率高,决策树只需要一次构建,反复使用,每一次预测的最大计算次数不超过决策树的深度。
缺点
1.对连续性的字段比较难预测。
2.对有时间顺序的数据,需要很多预处理的工作。
3.当类别太多时,错误可能就会增加的比较快。
4.一般的算法分类的时候,只是根据一个字段来分类。
5.在处理特征关联性比较强的数据时表现得不是太好
ID3算法核心
决策树的核心问题是在每一步如何选择适当的属性对样本做拆分,而ID3算法中选取信息增益作为判别属性优劣的标准。
信息熵
信息熵 (entropy) 是度量样本集合“纯度”最常用的一种指标。假定当前样本集合 D 中第 k 类样本所占的比例为p_k则 D 的信息熵定义为
Ent(D)的值越小,则D的纯度越高。
信息增益直接以信息熵为基础,计算当前划分对信息熵所造成的变化。
信息增益
离散属性a的取值:{a1,a2,a3,…,av}
Dv:D中在 a上取值 = av 的样本集合
以属性a对 数据集D进行划分所获得的信息增益为:
ID3算法演算实例
在下列数据中实现ID3算法
该数据集包含17个训练样例,|y| = 2(标签或者说分类值有两个),其中正例占p_1=8/17,反例占p_2=9/17,根节点的信息熵
总结: 整个算法主要是在做一件事,计算当前节点的信息熵和下一个节点所有属性的加权平均信息熵的差值(信息增益),选择信息增益最大的属性作为最优划分属性,以此类推,不断递归,直至满足递归的三种停止条件的其中一个停止。
C4.5算法
C4.5决策树生成算法相对于ID3算法算法的重要改进是使用信息增益率来选择节点属性。C4.5算法既能够处理离散的描述属性,也可以处理连续的描述属性。
增益率:
其中
属性 a 的可能取值数目越多 (即 V 越大),则 IV(a) 的值通常就越大
总结: C4.5算法规避了ID3算法只能处理离散型属性,并且对倾向于选择取值较多的属性,因为信息增益反映的给定一个条件以后不确定性减少的程度,必然是分得越细的数据集确定性更高,也就是条件熵越小,信息增益越大,C4.5算法流程与ID3相类似,只不过将信息增益改为信息增益比,以解决偏向取值较多的属性的问题,另外它可以处理连续型属性。
CART算法
CART决策树是一种十分有效的非参数分类和回归方法,通过构建树、修建树、评估树来构建一个二叉树。当终结点是连续变量时,该树伟回归树;当终结点是分类变量,该树为分类树。相对于ID3使用的信息增益,CART中用于选择变量的不纯性度量是Gini指数,总体内包含的类别越杂乱,GINI指数就越大(跟熵的概念很相似)
GINI指数:
1、是一种不等性度量;
2、通常用来度量收入不平衡,可以用来度量任何不均匀分布;
3、是介于0~1之间的数,0-完全相等,1-完全不相等;
4、总体内包含的类别越杂乱,GINI指数就越大(跟熵的概念很相似)
三种算法总结
- 信息增益Gain(D,a)——ID3算法
属性必须离散属性
倾向于选择取值更多的属性 - 增益率Gain_ration(D,a)——C4.5算法
二分法处理连续变量
使用增益率选择属性 - 基尼指数Gini_index(D,a)——CART算法
二叉树(每个结点分裂成两个子集)
可以处理分类问题,也可以处理回归问题
关于剪枝
生成决策树时为了尽可能正确分类训练样本,有可能造成分支过多。这样就会导致过拟合。为了避免过拟合现象,特此提出剪枝操作。
基本策略:
- 预剪枝 (pre-pruning): 提前终止某些分支的生长
- 后剪枝 (post-pruning): 生成一棵完全树,再“回头”剪枝
两种策略核心都为比较划分前后的验证集精度判断是否进行划分。
两种策略的总结:
基于sklearn的决策树Python 实现
参数 | 意义 |
---|---|
criterion : string,optional(entropy, gini) | 衡量分裂质量的功能。支持的标准是基尼杂质的“gini”和信息增益的“熵”。 |
splitter : string,optional(best, random) | best在特征的所有划分点中找出最优的划分点,random随机的在部分划分点中找局部最优的划分点。默认的‘best’适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐‘random’。 |
max_depth : int或None,可选(默认=无) | 树的最大深度。如果为None,则扩展节点直到所有叶子都是纯的或直到所有叶子包含少于min_samples_split样本。 |
min_samples_split : int,float,optional(default = 2) | 内部节点再划分所需最小样本数。默认值为2。如果是int,则取传入值本身作为最小样本数;如果是float,则取ceil(min_samples_split*样本数量)作为最小样本数。(向上取整) |
min_samples_leaf : int,float,optional(default = 1) | 叶节点所需的最小样本数。如果是int,则取传入值本身作为最小样本数;如果是float,则取ceil(min_samples_leaf*样本数量)的值作为最小样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 |
max_features : int,float,string或None,可选(默认=无) | 寻找最佳分割时要考虑的特征值数量:• 如果是int,则考虑max_features每次拆分时的功能。• 如果是浮点数,那么它max_features是一个分数,并且 每次拆分时都会考虑特征。注意:在找到节点样本的至少一个有效分区之前,搜索分割不会停止,即使它需要有效地检查多个max_features功能。 |
具体代码:
import pandas as pd
import numpy as np
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier as DTC
inputfile = "./sales_data.xls"
data = pd.read_excel(inputfile, index_col=u'序号')
data[data == u'是'] = 1
data[data == u'高'] = 1
data[data == u'好'] = 1
data[data != 1] = -1
x = data.iloc[:, :3].as_matrix().astype(int)
y = data.iloc[:, 3].as_matrix().astype(int)
from sklearn.model_selection import train_test_split
#切分训练数据和测试数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
#初始化模型,基于信息熵
dtc = DTC(criterion = 'entropy')
#训练模型
dtc.fit(x_train, y_train)
#计算决策树测试得分
y_pred = dtc.predict(x_test)
dtc.score(x_test, y_pred )
#sklearn自带决策树结果可视化工具包
tree.plot_tree(dtc.fit(x_train, y_train))
运行结果:
scikit-learn (sklearn) 官方文档中文版:https://sklearn.apachecn.org/#/
sklearn.tree.DecisionTreeClassifier (决策树API): https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn-tree-decisiontreeclassifier