决策树算法的两个阶段
决策树基本术语(根节点、叶子节点、内部节点)
信息熵概念和直观理解
信息熵和基尼系数
熵:纯度\不纯度;不确定性
熵是用来度量不确定性,当熵越大,概率说X=xi的不确定性越大,反之越小;在机器学期中分类中说,熵越大即这个类别的不确定性更大,反之越小
基尼不纯度表示一个随机选中的样本在子集中被分错的可能性。
基尼不纯度为这个样本被选中的概率乘以它被分错的概率。
当一个节点中所有样本都是一个类时,基尼不纯度为零。
决策树要考虑的问题(1):
ID3
ID3是基本的决策树构建算法,作为决策树经典的构建算法,其具有结构简单、清晰易懂的特点。
虽然ID3比较灵活方便,但是有以下几个缺点:
(1)采用信息增益进行分裂,分裂的精确度可能没有采用信息增益率进行分裂高
(2)不能处理连续型数据,只能通过离散化将连续性数据转化为离散型数据
(3)不能处理缺省值
(4)没有对决策树进行剪枝处理,很可能会出现过拟合的问题
C4.5和CART算法
1.连续值属性处理
将属性取值进行排序,按大于t和小于t分为两个子集,划分点t由最大化信息增益来确定,需要注意的是,对于连续属性,该属性可在决策树中多次使用。
2.缺省值属性处理
判断属性优劣(如计算信息增益)只考虑没有缺省值的样本,且相应地乘以除去缺省值所占的比例做权重,以保证缺省值不要过多;
对于含缺省值样本对于该属性的划分,则根据该属性各种取值的分布情况,以不同的概率划分到不同的结点(划分后样本带权)。
3. 三种划分属性选择指标:
(1) 信息增益Gain(D,a):
信息增益越大,纯度提升越高,可以用最高信息增益选择属性。
缺点:属性可取值越多,得到的信息熵越大,用其划分后信息增益越高,故此方法对属性可取值更多的属性有所偏好
(2) 增益率Gain_ratio(D,a):
信息增益除以属性的固有值(以属性a做随机变量,由集合中a属性各个取值所占的比例计算的信息熵),a可取数值越多,固定值越大,在一定程度上抑制了上述偏好
缺点:对可取数值较小的属性有偏好。故实际上,采用先找信息增益高于平均水平的属性,再从中找增益率高的
(3) 基尼指数Gini(D):
基尼指数表示一个随机选中的样本在子集中被分错的可能性。当一个节点中所有样本都是一个类时,基尼不纯度为零。
划分属性标准:
- 信息增益:ID3
- 信息增益率:C4.5
Gainratio(D,a)=Gain(D,a)/Ha(D)
Ha(D)= - 基尼系数:CART
决策树要考虑的问题(2)
预防过拟合的方法:剪枝
(1) 预剪枝:在构造决策树的同时进行剪枝。所有决策树的构建方法,都是在无法进一步降低熵的情况下才会停止创建分支的过程,为了避免过拟合,可以设定一个阈值,熵减小的数量小于这个阈值,即使还可以继续降低熵,也停止继续创建分支。
优点:分支较少,减小过拟合风险,也减少了训练时间开销和测试时间开销
缺点:带来了欠拟合的风险(当前划分虽不能提升泛化能力,但继续划分呢?)
(2) 后剪枝:生成完整的决策树后自底向上对非叶结点考察,若替换为叶结点能带来泛化性能提升,则替换。
优点:比预剪枝分支多,欠拟合风险小,泛化性能往往优于预剪枝
缺点:训练时间开销大得多
决策树常用算法比较
集成学习:通过随机森林提高准确率
决策树是建立在已知的历史数据及概率上的,一课决策树的预测可能会不太准确,提高准确率最好的方法是构建随机森林(Random Forest)。
所谓随机森林就是通过随机抽样的方式从历史数据表中生成多张抽样的历史表,对每个抽样的历史表生成一棵决策树。由于每次生成抽样表后数据都会放回到总表中,因此每一棵决策树之间都是独立的没有关联。将多颗决策树组成一个随机森林。当有一条新的数据产生时,让森林里的每一颗决策树分别进行判断,以投票最多的结果作为最终的判断结果。以此来提高正确的概率。
决策树的优缺点
决策树算法的优点:
1)简单直观,生成的决策树很直观。
2)既可以处理离散值也可以处理连续值。很多算法只是专注于离散值或者连续值。
3)可以处理多维度输出的分类问题。
4)相比于神经网络之类的黑盒分类模型,决策树在逻辑上可以得到很好的解释
5)可以交叉验证的剪枝来选择模型,从而提高泛化能力。
6)对于异常点的容错能力好,健壮性高。
决策树算法的缺点:
1)决策树算法容易过拟合:通过设置节点最少样本数量、不纯度/熵阈值、限制决策树深度来改进。
2)决策树会因为样本发生一点点的改动,就会导致树结构的剧烈改变:通过随机森林等算法。
3)寻找最优的决策树是一个NP难题,通过启发式方法,容易陷入局部最优:通过随机森林算法等方法改善。
4)有些比较复杂的关系,决策树很难学习,比如异或:通过神经网络等方法解决。
5)如果某些特征的样本比例过大,生成决策树容易偏向于这些特征:可通过调节样本权重来改善。
决策树算法python库实现:
import numpy as np # 导入numpy库
import matplotlib.pyplot as plt # 导入matplotlib.pylab库
from sklearn.tree import DecisionTreeRegressor #导入决策树库
1.数据预处理(初始化)
rng = np.random.RandomState(1) #随机数产生器
X = np.sort(5 * rng.rand(400, 1), axis=0) #随机产生400个数的数据集X,并排序
y = np.sin(X).ravel()
dtr= DecisionTreeRegressor(max_depth=5) #决策树回归器(均方差mse/mae)
dtr= DecisionTreeClassifier(max_depth=5) #决策树分类器(基尼系数或熵)
主要参数:
max_depth: 树最大深度,可选,缺省None,
min_samples_split : 分割内部节点所需最少样本数,可选,缺省2
min_samples_leaf : 成为叶子节点所需最少样本, 可选, 缺省1
max_features : 寻找最佳分割时考虑的特征数目, 可选, 缺省None: float/比例, ‘sqrt’/sqrt(n_features), ‘log2’/log2(n_features)
min_impurity_decrease : 如果节点分割导致不纯度减少超过此值,将进行分割,可选, 缺省0.0
presort : 预排序,加速寻找最佳分割,可选,缺省False, 大数据集降低训练过程, 小训练集或受限深度,可加快训练
random_state: 缺省None; 若int, 随机数产生器seed, 若RandomStates实例, 随机数产生器, 若None, np.random
2. 调用库函数计算:建立模型并计算
dtr.fit(X,y) # 调用库函数决策树算法: 分类器y是整数或string;回归器y是浮点数
dtr.predict(X) # 预测样本类别或回归值,返回shape(n_samples)或(n_samples,n_outputs)
dtr.decision_path(X) #返回决策路径,返回shape = [n_samples, n_nodes]
dtr.score(X, y) #返回预测结果的R^2(1-u/v). u=((y_true - y_pred) ** 2).sum()
v=((y_true - y_true.mean()) ** 2).sum()
dtr.apply(X) # 返回每个样本预测为叶子的索引
dtr.n_features_ # 执行’fit’时的特征数
dtr.n_outputs_ # 执行’fit’时的输出数
dtr.tree_ # 树对象
3.计算并展示结果(分类结果)
# 计算据测模型,深度=5
dtr_2 = DecisionTreeRegressor(max_depth=5)
dtr_2.fit(X, y)
# 预测结果
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_2 = dtr_2.predict(X_test)
# 画出图形
plt.figure('决策树回归深度=5')
plt.scatter(X, y, s=20, c="blue", label="原数据")
plt.plot(X_test, y_2, color="red", label="深度=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("深度=5,准确率%.2f"%(dtr_2.score(X,y)*100)+'%')
plt.legend()
plt.show()