决策树的原理介绍及python实现(分析基础)
综述
学生党整理一些关于数据分析的知识:本章为决策树的原理与python实现的代码块。
原理介绍
树模型
- 决策树:从根节点开始一步步走到叶子节点(决策)。
- 所有的数据最终都会落到叶子节点,即可以应用于分类也可以做回归。
树的组成
- 根节点:第一个选择点
- 非叶子节点于分支:中间过程
- 叶子节点:最终的决策结果
决策树的训练与测试
- 训练阶段从给定的训练集构造出一颗树,从根节点开始选择最有价值的特征开始切分节点。
- 测试阶段:根据构造出来的树模型从上到下走一遍。
- 一旦构造好了决策树,那么分类或者预测任务就很简单了,只需要走一遍就可以了,那么难点在于如何构造出一个树。
特征切分
- 存在的问题:根节点的选择该用那个特征呢?接下来我们要如何划分?
- 思考:我们的目标应该使根节点就像老大,根节点下面的节点就像老二,老大应该比老二能更好的切分数据。
- 目标:选择一种衡量标准,来计算通过不同特征进行分支选择后的分类情况,找出来最好的就作为我们的根节点,以此类推确定所有的节点的划分标准。
衡量标准——熵
基本介绍
- 熵:表示随机变量不确定性的度量(就是一个整体中内部元素的混乱程度,元素种类越多混乱程度越高)
- 公式:
H
(
x
)
=
−
∑
i
=
1
n
p
i
×
l
o
g
p
i
H(x) = -\sum_{i=1}^{n}p_i\times logp_i
H(x)=−i=1∑npi×logpi
公式中 p i p_i pi 表示第 i i i 种情况的概率 - 熵值与不确定性一般成正比
下图为熵值与概率的关系图:
可见当概率为 0 或者概率为 1 时,随机变量完全没有不确定关系;当概率为 0.5 时,随机变量的不确定性关系最大。 - 信息增益:表示特征(变量)使得类(因变量)的不确定性关系减少的程度。
我们通常采用信息增益这一指标作为节点决策特征选择的标准。
采用熵构造决策树实例说明
-
样例数据,前outlook、temperature、humidity、windy为特征,play为类。
-
划分方式
当前数据具有4个特征,即根节点有4种划分方式,现在我们根据这4个特征的信息增益大小进行选择。
以第一个种划分方式为例:
在历史数据中14天内有9天打球,5天不打球,所以根节点的熵为: − 9 14 l o g 2 9 14 − 5 14 l o g 2 5 14 = 0.940 -\frac{9}{14}log_2\frac{9}{14}-\frac{5}{14}log_2{\frac{5}{14}}=0.940 −149log2149−145log2145=0.940
然后根据第一种划分方式分类后,分别计算各个节点的熵值:- outlook = sunny时,熵值为 − 2 5 l o g 2 2 5 − 3 5 l o g 2 3 5 = 0.971 -\frac{2}{5}log_2\frac{2}{5}-\frac{3}{5}log_2{\frac{3}{5}}=0.971 −52log252−53log253=0.971。
- outlook = overcast时,熵值为 0 0 0。
- outlook = rainy时,熵值为 − 2 5 l o g 2 2 5 − 3 5 l o g 2 3 5 = 0.971 -\frac{2}{5}log_2\frac{2}{5}-\frac{3}{5}log_2{\frac{3}{5}}=0.971 −52log252−53log253=0.971。
然后根据数据统计,outlook取值分别为sunny、overcast、rainy的概率分别为: 5 14 \frac{5}{14} 145、 4 14 \frac{4}{14} 144和 5 14 \frac{5}{14} 145。
总体熵值计算: 5 14 × 0.971 + 4 14 × 0 + 5 14 × 0.971 = 0.693 \frac{5}{14}\times 0.971+\frac{4}{14}\times 0+\frac{5}{14}\times 0.971=0.693 145×0.971+144×0+145×0.971=0.693
此时,信息增益 g a i n ( o u t l o o k ) = 0.940 − 0.693 = 0.247 gain(outlook)=0.940-0.693=0.247 gain(outlook)=0.940−0.693=0.247, g a i n ( t e m p e r a t u r e ) = 0.029 gain(temperature)=0.029 gain(temperature)=0.029、 g a i n ( h u m i d i t y ) = 0.152 gain(humidity)=0.152 gain(humidity)=0.152、 g a i n ( w i n d y ) = 0.048 gain(windy)=0.048 gain(windy)=0.048。
我们找到了收益最大的特征,我们在对分完类的节点继续做同样操作得到对于节点的分类特征,以此类推完成整个决策树。
决策树算法
- ID3:信息增益(存在的问题:每个数据都有一个ID特征(1,2,3,…,14),根据该特征分类之后的熵值恒为 0 ,但是实际上根据这个特征分类毫无意义)
- C4.5:信息增益率(是ID3的升级,考虑自身熵值)
- CART:使用GINI系数来作为衡量标准
GINI系数: G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p) =\sum_{k = 1}^{K}p_k(1-p_k)=1-\sum_{k = 1}^{K}p_k^2 Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2(和熵的衡量标准类似,只是计算方式不同)
减枝策略
- 针对连续值我们可以采用“离散化”的方式减少决策树计算量过大,叶子节点过多的问题。例如一组特征值为60,70,80,90,95,100,120,125,220。直接采用二分将会出现9个节点。如果我们人为分成A(60-80)、B(90-100)、C(120-220),我们只需要分成3类即可。当然要根据特征含义和特定分析条件下选择是否分割数据。
- 决策树剪枝:为了防止过拟合情况。(决策树过拟合分析很大,理论上可以完全分开数据,使得每个叶子节点只存在一个数据)
- 剪纸策略:
1、预剪枝(实用):边建立决策树边进行剪枝操作。方法:限制树的深度,叶子节点的个数,叶子节点包含的样本树,信息增益量等。
2、后剪枝:当建立完决策树后来进行剪枝操作。方法:通过一定的衡量标准 C α ( T ) = C ( T ) + α × ∣ T l e a f ∣ C_\alpha(T)=C(T)+\alpha\times|T_{leaf}| Cα(T)=C(T)+α×∣Tleaf∣(叶子节点越多,损失越大)
代码模块
加载内部数据集(房价信息)
from sklearn.datasets.california_housing import fetch_california_housing
housing = fetch_california_housing()
print(housing.DESCR)
选择特征
选择longitude和latitude这2个特征研究决策树
from sklearn import tree
dtr = tree.DecisionTreeRegressor(max_depth = 2)#tree模型参数
dtr.fit(housing.data[:,[6,7]],housing.target)
- tree.DecisionTreeRegressor()参数
可视化决策树
要可视化首先要安装graphviz,网站为:www.graphiz.ofg/Download.php。
- 树模型可视化模块(过大的决策树无法显示)
def SeeTree(dtr,feature_name,name_tree):
dot_data = \
tree.export_graphviz(
dtr,#需要自己设置树参数
out_file=None,
feature_names= feature_name,#特征名称传入需要修改
filled = True,
impurity=False,
rounded=True
)
import pydotplus
graph = pydotplus.graph_from_dot_data(dot_data)
graph.get_nodes()[7].set_fillcolor("#FFF2DD")
from IPython.display import Image
img = Image(graph.create_png())
graph.write_png(name_tree)
name_tree = 'dtr_white_background.png'
SeeTree(dtr,housing.feature_names[6:8],name_tree)
结果:
对数据集所有特征分析
分割数据
train:test = 9:1
- 决策树
data_train,data_test,target_train,target_test = \
train_test_split(housing.data,housing.target,test_size=0.1,random_state=42)#随机种子,使每次随机的都是一致的
dtr = tree.DecisionTreeRegressor(random_state=42)
dtr.fit(data_train,target_train)
result = dtr.score(data_test,target_test)
print(result)
运行结果:
0.637355881715626 |
---|
- 随机森林(下一章介绍)
from sklearn.ensemble import RandomForestRegressor
rfr = RandomForestRegressor(random_state=42)
rfr.fit(data_train,target_train)
result = rfr.score(data_test,target_test)
print(result)
运行结果:
0.7910601348350835 |
---|
预剪枝参数选择
可采用参数自动选择方式,通过遍历的方式打印出指定的几个组合的离散情况,选取最优的预剪枝参数
from sklearn.model_selection import GridSearchCV
tree_param_grid = {"min_samples_split":list((3,6,9)),"n_estimators":list((10,50,100))}
grid = GridSearchCV(RandomForestRegressor(),param_grid=tree_param_grid,cv = 5)#cv表示交叉验证中train数据平分个数
grid.fit(data_train,target_train)
print(grid.best_params_,grid.best_score_)
运行过程中一共有 3 × 3 = 9 3\times3=9 3×3=9种参数设置方式,运行结果为:
{‘min_samples_split’: 3, ‘n_estimators’: 100} 0.8074294466986265 |
---|
小结
决策树是一种十分常用的分类方法。可以用于模型预测,他代表的是对象属性与对象值之间的一种映射关系。
决策树的优点及缺点:(from:wikipedia)
- 在决策支持工具中,决策树(和影响图)具有几个优点。决策树:
1、很容易理解和解释。
2、即使只有很少的数据也有价值。可以基于分析得出的情况生成确定不同方案的最差,最佳和预期值。
3、使用可视化模型。
4、可以与其他决策技术结合使用。 - 决策树的缺点:
1、它们是不稳定的,这意味着数据的微小变化可能导致最优决策树结构的巨大变化。
2、它们通常相对不准确。许多其他预测因子使用类似数据表现更好。这可以通过用决策树的随机森林替换单个决策树来解决,但随机森林不像单个决策树那样容易解释。
3、对于包括具有不同级别数的分类变量的数据,决策树中的信息增益偏向于具有更多级别的那些属性。
4、计算可能变得非常复杂,特别是如果许多值不确定和/或许多结果是相关的。