传统算法(三)
决策树
一、决策树思想
(一)树模型
决策树,顾名思义可以大概猜到是根本的思想是根据参数条件(节点)来划分类,会有很多的节点,从根节点开始一步步走到叶子节点(决策),最后所有的数据最终都会落到叶子节点。
所以决策树算法既可以做分类也可以做回归
举例:
对一家成员来区分(判断),是否要玩电脑游戏:
- 根节点:age小于15;
2.子节点:是否是男生;
(二)树组成
一个决策树模型中,重要的几个点如下:
- 根节点:第一个选择点
- 非叶子节点与分支:中间过程
- 叶子节点:最终的决策结果
(三)决策树的训练与测试
对新的问题,用决策树模型来处理时,一般会有两个阶段:训练阶段和测试阶段
- 训练阶段:从给定的训练集构造出来一棵树(从跟节点开始选择特征, 如何进行特征切分)
- 测试阶段:根据构造出来的树模型从上到下去走一遍,来验证模型;
那么主要难点在哪?
难点就在于如何构造出来一颗树,根节点的选择该用哪个特征呢?以及如何切分做决策呢?
我们可以想到,根节点的选择非常重要,中间的分支和非叶子节点都是在根节点的基础上,再进一步来划分,那要怎么来衡量来选择重要的根节点呢?——引入“熵”的概念
二、衡量标准-熵
熵的概念:
熵是表示随机变量不确定性的度量 。
说白了就是物体内部的混乱程度;比如杂货市场里面有非常多的品牌、种类,就很混乱,而专卖店里面只卖一个牌子的那就稳定多啦。
计算熵的公式:
H
(
X
)
=
−
∑
p
i
∗
l
o
g
p
i
(
i
=
1
,
2
,
3
⋯
n
)
H(X)=-\sum p_i*logp_i(i=1,2,3\cdots n)
H(X)=−∑pi∗logpi(i=1,2,3⋯n)log一般取2为底数
图像显示如下:
通过图像我们可以知道:
- 当 p = 0 p=0 p=0或 p = 1 p=1 p=1时, H ( p ) = 0 H(p)=0 H(p)=0,随机变量完全没有不确定性
- 当 p = 0.5 p=0.5 p=0.5时, H ( p ) = 1 H(p)=1 H(p)=1,此时随机变量的不确定性最大
所以,不确定性越大,得到的熵值也就越大,我们当然希望熵值越小越好。
但是这样我们也并不能知道如何决策一个节点的选择; 这个时候,我们可以用“信息增益”来做这个决策;
信息增益:表示特征X使得类Y的不确定性减少的程度。
举例进行计算一下:
- 数据:14天打球情况
- 特征:4种环境变化
- 目标:构造决策树
weather | temperature | humidity | windy | play |
---|---|---|---|---|
sunny | hot | high | false | no |
sunny | hot | high | true | no |
overcast | hot | high | false | yes |
rainy | mild | high | false | yes |
rainy | cool | normal | false | yes |
rainy | cool | normal | true | no |
overcast | cool | normal | true | yes |
sunny | mild | high | false | no |
sunny | cool | normal | false | yes |
rainy | mild | normal | false | yes |
sunny | mild | normal | true | yes |
overcast | mild | high | true | yes |
overcast | hot | normal | false | yes |
rainy | mild | high | true | no |
明显我们可以根据4个特征,划分出4种节点:
确定节点:
1、整体的熵值计算:
在历史数据中(14天)有9天打球,5天不打球,所以此时的熵应为:
−
9
14
l
o
g
2
9
14
+
(
−
5
14
l
o
g
2
5
14
)
=
0.94
-\dfrac{9}{14}log_2\dfrac{9}{14}+\left(-\dfrac{5}{14}log_2\dfrac{5}{14}\right)=0.94
−149log2149+(−145log2145)=0.94
2、对4个特征逐一进行熵值的计算,以weather为例:
- weather = sunny时,有5天是sunny的天气,其中有2天是打球,3天不打球;那么,熵值为 − 2 5 l o g 2 2 5 + ( − 3 5 l o g 2 3 5 ) = 0.971 -\dfrac{2}{5}log_2\dfrac{2}{5}+\left(-\dfrac{3}{5}log_2\dfrac{3}{5}\right)=0.971 −52log252+(−53log253)=0.971
- weather = overcast时,有4天是overcast的天气,4天都是打球;那么,熵值为 − 4 4 l o g 2 4 4 = 0 -\dfrac{4}{4}log_2\dfrac{4}{4}=0 −44log244=0
- weather = rainy时,有5天是rainy的天气,其中有3天是打球,2天不打球;那么,熵值为
−
3
5
l
o
g
2
3
5
+
(
−
2
5
l
o
g
2
2
5
)
=
0.971
-\dfrac{3}{5}log_2\dfrac{3}{5}+\left(-\dfrac{2}{5}log_2\dfrac{2}{5}\right)=0.971
−53log253+(−52log252)=0.971
整体的weather中值为sunny,overcast,rainy的概率分别为: 5/14, 4/14, 5/14;所以我们算出来以weather的计算的整体熵值 5 / 14 ∗ 0.971 + 4 / 14 ∗ 0 + 5 / 14 ∗ 0.971 = 0.693 5/14 * 0.971 + 4/14 * 0 + 5/14 * 0.971 = 0.693 5/14∗0.971+4/14∗0+5/14∗0.971=0.693;
3、计算信息增益:
那么此时以weather计算出来的增益值为:
0.940
−
0.693
=
0.247
0.940-0.693=0.247
0.940−0.693=0.247,即系统的熵值从原始的0.940下降到了0.693,增益为0.247;
同理,算出来gain(temperature)=0.029、gain(humidity)=0.152、gain(windy)=0.048;
这样我们就找到了第一个根节点weather;接下来就是按照相同的方法继续来决策非叶子节点以及叶子节点了;
三、决策树算法
这里我们在整体介绍三种算法:
- ID3(信息增益):也就是刚刚已经提到的方法信息增益,用绝对的增加(减少)的值来评估决策;
- C4.5(信息增益率):计算公式为:信息增益/自身的熵值;这个是防止单个特征的绝对增量大而影响决策,用C4.5就可以解决这个问题,同时也考虑到了自身熵的情况;
- 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}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2 Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2
四、决策树剪枝策略
剪枝策略是什么呢?为什么要剪枝呢?
可以试想一下,如果数据量非常大的情况下,如果可以容忍过拟合的风险,会出现非常多的节点,最后的叶子节点选出来的数据,这样结果也是每个叶子节点不就一个数据。
所以我们要进行剪枝的策略;
剪枝策略:
- 预剪枝:边建立决策树边进行剪枝的操作(更实用)
通过设定:限制深度,叶子节点个数,叶子节点样本数,信息增益量等来衡量是否剪枝。 - 后剪枝:建立完决策树后来进行剪枝操作
通过一定的衡量标准:
C α ( T ) = C ( T ) + α ⋅ ∣ T l e a f ∣ C_\alpha(T)=C(T)+\alpha\cdot\mid T_{leaf}\mid Cα(T)=C(T)+α⋅∣Tleaf∣ (叶子节点越多,损失越大)
五、Python代码实例
以下实例为预测加利福尼亚的房产价格
使用sklearn
模块中决策树算法的代码:
#coding=utf-8
# write by sz
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import pydotplus
from sklearn.datasets.california_housing import fetch_california_housing
from sklearn import tree
#实例化
cal = fetch_california_housing()
# print(cal)
first_index = cal.feature_names.index('HouseAge')
end_index = cal.feature_names.index('Longitude')
x = cal.data[:,first_index:end_index]
y = cal.target
# print(x)
# print(y)
#模型训练
TR = tree.DecisionTreeRegressor(max_depth=10,min_samples_leaf=2)
TR.fit(x,y)
dot = tree.export_graphviz(TR, out_file=None,
feature_names = cal.feature_names[1:7],
filled=True,special_characters=True)
#可视化
graph = pydotplus.graph_from_dot_data( dot )
graph.write_pdf('exsample.pdf')
y_predict = TR.predict(x)
print(y_predict)
print(y)
plt.plot(np.arange(len(y)),y,c='r')
plt.plot(np.arange(len(y)),y_predict,c='y')
#
plt.show()
以上,就是本次学习的决策树模型及算法的思想,以及python代码实现的案例;