决策树的核心算法
ID3:特征选择方法:信息增益。
C4.5:特征选择方法:信息增益比。
CART:对于分类树,特征选择方法是基尼指数;对于回归树使用平方误差最小化准则。
决策树学习过程
- 特征选择
- 决策树生成: 递归结构,选择最优特征,对训练数据进行分割, 对应于模型的局部最优
- 决策树剪枝: 缩小树结构规模, 缓解过拟合, 对应于模型的全局选择
决策树的类别
1.分类树 (Classification Tree)
原理:
内部节点表示一个特征或者一个属性,叶子节点表示一个类。
用决策树分类,从根节点开始,对实例的某一个特征进行分类,根据分类结果,将实例分配到子节点,这时,每一个子节点对应着该特征的一个取值;如此递归的分配下去,直到将该实例分配到叶子节点。
以C4.5分类树为例,C4.5分类树在每次分枝时,是穷举每一个feature的每一个阈值,找到使得按照feature<=阈值,和feature>阈值分成的两个分枝的熵最大的阈值(熵最大的概念可理解成尽可能每个分枝的男女比例都远离1:1),按照该标准分枝得到两个新节点,用同样方法继续分枝直到所有人都被分入性别唯一的叶子节点,或达到预设的终止条件,若最终叶子节点中的性别不唯一,则以多数人的性别作为该叶子节点的类别[1]。根据离散特征分支划分数据集时,子数据集中不再包含该特征(因为每个分支下的子数据集该特征的取值就会是一样的,信息增益或者Gini Gain将不再变化,这也是C4.5等决策树离散型特征不会被重复选择为节点分裂的属性)。而根据连续特征分支时,各分支下的子数据集必须依旧包含该特征(当然,左右分支各包含的分别是取值小于、大于等于分裂值的子数据集),因为该连续特征再接下来的树分支过程中可能依旧起着决定性作用。
CART分类树在节点分裂时使用GINI指数,GINI指数是度量数据划分或训练数据集D的不纯度为主。GINI值越小,表明样本的纯净度越高(即该样本只属于同一类的概率越高)。CART不适用于离散特征有多个取值的场景。原因:不考虑剪枝情况下,分类决策树递归创建过程中就是每次选择GiniGain最小的节点做分叉点,直至子数据集都属于同一类或者所有特征用光了。对于离散属性,可能会出现属性取值数N>=3的情况,因为CART是二叉树,此时需要考虑将N>=3个取值的离散特征的处理时也只能有两个分支,这就要通过组合人为的创建二取值序列并取GiniGain最小者作为树分叉决策点。如某特征值具有[‘young’,’middle’,’old’]三个取值,那么二分序列会有如下3种可能性:[((‘young’,), (‘middle’, ‘old’)), ((‘middle’,), (‘young’, ‘old’)), ((‘old’,), (‘young’, ‘middle’))]。 采用CART算法,就需要分别计算按照上述List中的二分序列做分叉时的Gini指数,然后选取产生最小的GINIGain的二分序列做该特征的分叉二值序列参与树构建的递归。
需要补充:熵,信息增益,基尼指数[4]。
熵:是随机变量不确定性的度量,熵越大,随机变量的不确定性越大,换句话说,预测具有该变量的样本为正例的概率为0.5,等同随机猜。
信息增益:越大,该特征具备更强的分类能力。
基尼指数:越大,样本集合的不确定越大。
总结:分类树使用信息增益或增益比率来划分节点;每个节点样本的类别情况投票决定测试样本的类别。
code:
http://sklearn.apachecn.org/#/docs/11
#简单例子训练模型
from sklearn import tree
x = [[0,0],[1,1]]
y = [0,1]
clf = tree.DecisionTreeClassifier()
clf = clf.fit(x,y)
#预测例子
z = [[2,2]]
#预测标签
clf.predict(z) #out:array([1])
#预测属于每个类的概率
# clf.predict_proba(z) #out:array([[0., 1.]])
c = [[0,1]]
clf.predict_proba(c)# 出现这样一个现象:array([[0., 1.]]) 再运行一次array([[1., 0.]]),说明我们训练的模型,预测能力正负例子的能力50%,跟掷硬币似的。
# iris 数据集上训练模型
from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)
import graphviz #用来绘制树形状的模块
dot_data = tree.export_graphviz(clf,out_file=None)
graph = graphviz.Source(dot_data)
graph.render("iris")
graph # 打印出数的形状,分裂的特征的gini指数
输出的树结果:对输出结果,做一些说明:
X[3]<=0.8 :X[3]表示样本中的第四个特征,0.8表示该特征的切分点;
gini=0.667:这是X[3]<=0.8时候的gini指数;
samples=150:这是总体的样本个数;
values=[50,50,50]:我的理解是每一个元素表示三类样本的数量。
[4]中说,gini指数最小的特征,以及其对应的切分点作为最优特征和切分点。这里跟代码跑出来的结果不同啊,甚是不理解为啥。。
2.回归树(Regression Tree)
回归树总体流程也是类似,区别在于,回归树的每个节点(不一定是叶子节点)都会得一个预测值,以年龄为例,该预测值等于属于这个节点的所有人年龄的平均值。分枝时穷举每一个feature的每个阈值找最好的分割点,但衡量最好的标准不再是最大熵,而是最小化均方差即(每个人的年龄-预测年龄)^2 的总和 / N。也就是被预测出错的人数越多,错的越离谱,均方差就越大,通过最小化均方差能够找到最可靠的分枝依据。分枝直到每个叶子节点上人的年龄都唯一或者达到预设的终止条件(如叶子个数上限),若最终叶子节点上人的年龄不唯一,则以该节点上所有人的平均年龄做为该叶子节点的预测年龄。
总结:回归树使用最大均方差划分节点;每个节点样本的均值作为测试样本的回归预测值[1]。
节点的预测值是该节点下所有点的均值,这点在李航老师的《统计及旗下学习》中有体现:
code:
#https://scikit-learn.org/stable/auto_examples/tree/plot_tree_regression.html#sphx-glr-auto-examples-tree-plot-tree-regression-py
#随机生成数据,拟合曲线,并绘制数据的散点图
print(__doc__)
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
rng = np.random.RandomState(1)
X = np.sort(5*rng.rand(80,1),axis = 0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))
# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)
# Predict
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
# Plot the results
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",
c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",
label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
输出结果:
附件:
sklearn中iris介绍:
1.可以参考[6]绘制样本分布图:
部分树参数说明:
> * 使用 max_depth=3
作为初始树深度,让决策树知道如何适应您的数据,然后再增加树的深度。
> * 请记住,填充树的样本数量会增加树的每个附加级别。使用 max_depth
来控制输的大小防止过拟合。
> * 通过使用 min_samples_split
和 min_samples_leaf
来控制叶节点上的样本数量。当这个值很小时意味着生成的决策树将会过拟合,然而当这个值很大时将会不利于决策树的对样本的学习。所以尝试 min_samples_leaf=5
作为初始值。如果样本的变化量很大,可以使用浮点数作为这两个参数中的百分比。两者之间的主要区别在于 min_samples_leaf
保证叶结点中最少的采样数,而 min_samples_split
可以创建任意小的叶子,尽管在文献中 min_samples_split
更常见。
> * 在训练之前平衡您的数据集,以防止决策树偏向于主导类.可以通过从每个类中抽取相等数量的样本来进行类平衡,或者优选地通过将每个类的样本权重 (sample_weight
) 的和归一化为相同的值。还要注意的是,基于权重的预修剪标准 (min_weight_fraction_leaf
) 对于显性类别的偏倚偏小,而不是不了解样本权重的标准,如 min_samples_leaf
。
决策树优缺点
优点:
(1)速度快: 计算量相对较小, 且容易转化成分类规则. 只要沿着树根向下一直走到叶, 沿途的分裂条件就能够唯一确定一条分类的谓词.
(2)准确性高: 挖掘出来的分类规则准确性高, 便于理解, 决策树可以清晰的显示哪些字段比较重要, 即可以生成可以理解的规则.
(3)可以处理连续和种类字段
(4)不需要任何领域知识和参数假设
(5)适合高维数据
缺点:
(1)对于各类别样本数量不一致的数据, 信息增益偏向于那些更多数值的特征
(2)容易过拟合
(3)忽略属性之间的相关性
参考:
2.https://www.jianshu.com/p/005a4e6ac775
4.《统计机器学习》,李航。
6.数据集合介绍
7.cart树介绍的别有一番风韵