决策树
决策树:是由一个个“决策”所组成得树,放“决策依据”得是非叶节点,“放决策结果”的是叶节点。
一、ID3算法 是一种贪心算法,用来构造决策树
ID3算法起源于概念学习系统(CLS),以信息熵的下降速度为选取测试属性的标准,即在每个节点选取还尚未被用来划分的具有最高信息增益的属性作为划分标准,然后继续这个过程,直到生成的决策树能完美分类训练样例。
熵(信息熵):是描述信息的不确定度的,是随机变量不确定度的度量。熵越大,信息的不确定度就越大,信息越混乱,越不符合决策树分类的需求。
Ent(D)=-
∑
k
=
1
∣
y
∣
p
k
l
o
g
2
p
k
\sum_{k=1}^{|y|}p_{k}log_{2}p_{k}
∑k=1∣y∣pklog2pk
p
k
p_{k}
pk是第k类样本所占的比例;D是样本集合
例如:
- 太阳从东边升起;西边升起
p
0
p_{0}
p0=0 ;东边升起
p
1
p_{1}
p1=1
Ent(D)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk= 1 ∗ l o g 2 1 1*log_{2}1 1∗log21=0 - 投掷硬币;正面
p
0
p_{0}
p0=
1
2
\frac{1}{2}
21 ;反面
p
1
p_{1}
p1=
1
2
\frac{1}{2}
21
Ent(D)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk=- 1 2 ∗ l o g 2 1 2 \frac{1}{2}*log_{2}\frac{1}{2} 21∗log221- 1 2 ∗ l o g 2 1 2 \frac{1}{2}*log_{2}\frac{1}{2} 21∗log221=1
所以投掷硬币的不确定性大于太阳从东边升起的事件来的大。
信息增益:衡量熵的变化,即在选定特征A后,数据不确定度的下降。信息增益越大,意味着这个特征的分类的能力越强,则优选选择这个特征。
G
a
i
n
(
D
,
a
)
=
E
n
t
(
D
)
−
∑
v
=
1
v
∣
D
v
∣
∣
D
∣
E
n
t
(
D
v
)
Gain(D,a)=Ent(D)-\sum_{v=1}^{v}\frac{|D^v|}{|D|}Ent(D^v)
Gain(D,a)=Ent(D)−∑v=1v∣D∣∣Dv∣Ent(Dv)
- 首先粗略的观察,大致好瓜和坏瓜50%和50%
- 通过这一系列属性划分,为了降低这个不确定度(熵)==>这个不确定度降低的程度则为信息增益
- Ent(D)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk=- − 8 17 l o g 2 8 17 − 9 17 l o g 2 9 17 -\frac{8}{17}log_{2}\frac{8}{17}-\frac{9}{17}log_{2}\frac{9}{17} −178log2178−179log2179=0.998
- 按照属性色泽-青绿(1,4,6 | 10,13,17);
E n t ( D 1 ) Ent(D^1) Ent(D1)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk=- − 3 6 l o g 2 3 6 − 3 6 l o g 2 3 6 -\frac{3}{6}log_{2}\frac{3}{6}-\frac{3}{6}log_{2}\frac{3}{6} −63log263−63log263=1.000 - 按照属性色泽-乌黑(2,3,7,8 | 9,15);
E n t ( D 2 ) Ent(D^2) Ent(D2)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk=- − 4 6 l o g 2 4 6 − 4 6 l o g 2 4 6 -\frac{4}{6}log_{2}\frac{4}{6}-\frac{4}{6}log_{2}\frac{4}{6} −64log264−64log264=0.918 - 按照属性色泽-浅白(5 | 11,12,14,16);
E n t ( D 3 ) Ent(D^3) Ent(D3)=- ∑ k = 1 ∣ y ∣ p k l o g 2 p k \sum_{k=1}^{|y|}p_{k}log_{2}p_{k} ∑k=1∣y∣pklog2pk=- − 1 5 l o g 2 1 5 − 4 5 l o g 2 4 5 -\frac{1}{5}log_{2}\frac{1}{5}-\frac{4}{5}log_{2}\frac{4}{5} −51log251−54log254=0.722 - 信息增益:Gain(D,色泽)= E n t ( D ) − ∑ v = 1 v ∣ D v ∣ ∣ D ∣ E n t ( D v ) Ent(D)-\sum_{v=1}^{v}\frac{|D^v|}{|D|}Ent(D^v) Ent(D)−∑v=1v∣D∣∣Dv∣Ent(Dv)=0.998- ( 6 17 ∗ 1.000 + 6 17 ∗ 0.918 + 5 17 ∗ 0.722 ) (\frac{6}{17}*1.000+\frac{6}{17}*0.918+\frac{5}{17}*0.722) (176∗1.000+176∗0.918+175∗0.722)=0.109
- 再依次计算其他属性的信息增益
Gain(D,根蒂)=0.143;Gain(D,敲声)=0.141;Gain(D,纹理)=0.381;Gain(D,脐部)=0.289;Gain(D,触感)=0.006;
纹理的信息增益最大,被选为划分属性;这个特征的分类的能力强
ID3算法的缺陷
(1)不支持连续特征
(2)采用信息增益大的特征优选建立决策树的节点。在相同条件下,取值比较多的特征比取值少的特征信息增益大。对取值数目较多的属性有所偏好。
(3)不支持缺失值处理
(4)没有应对过拟合的策略
上图,树的每一层都要使用计算各个属性的信息增益,选择最优的属性进行划分,缺点不支持连续特征。
二、C4.5算法 是ID3算法的一个扩展
C4.5的目标是通过学习,找到一个从属性值到类别的映射关系,并且这个映射能用于对新的类别未知的实体进行分类。ID3算法选择属性的是子树的信息增益;C4.5用的是信息增益率;
(1)为了减少ID3算法使用信息增益时,取值数目较多的属性有所偏可能带来的不利影响。
连续特征:C4.5的思路是将连续的特征离散化
信息增益率(信息增益比):针对于信息增益偏向取值比较多的特点提出的
Gain_ratio(D,a)= G a i n ( D , a ) I V ( a ) \frac{Gain(D,a)}{IV(a)} IV(a)Gain(D,a)
I
V
(
a
)
=
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
l
o
g
2
∣
D
v
∣
∣
D
∣
IV(a)=-\sum_{v=1}^{V}\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|}
IV(a)=−∑v=1V∣D∣∣Dv∣log2∣D∣∣Dv∣
属性IV(a)成为属性a的固有值;属性取值越多则IV(a)也会越大;然而信息增益比Gain_ratio(D,a)不会随着属性取值越多而增大了
(2)缺失值处理
如何在属性值缺失的情况下进行划分;
ρ
=
∑
x
ϵ
D
~
ω
x
∑
x
ϵ
D
ω
x
\rho = \frac{\sum_{x \epsilon \widetilde D \omega _x}}{\sum_{x \epsilon D \omega _x}}
ρ=∑xϵDωx∑xϵD
ωx
ρ k ~ = ∑ x ϵ D ~ k ω x ∑ x ϵ D ~ ω x \rho_{\widetilde k} = \frac{\sum_{x \epsilon \widetilde D_k \omega _x}}{\sum_{x \epsilon \widetilde D \omega _x}} ρk =∑xϵD ωx∑xϵD kωx
γ k ~ = ∑ x ϵ D ~ v ω x ∑ x ϵ D ~ ω x \gamma_{\widetilde k} = \frac{\sum_{x \epsilon \widetilde D_v \omega _x}}{\sum_{x \epsilon \widetilde D \omega _x}} γk =∑xϵD ωx∑xϵD vωx
改进的信息增益: Gain(D,a)= ρ ∗ G a i n ( D ~ , a ) = ρ ∗ E n t ( D ~ ) − ∑ v = 1 V γ ~ v E n t ( D ~ v ) \rho*Gain(\widetilde D,a) =\rho*Ent(\widetilde D)-\sum_{v=1}^{V}\widetilde \gamma_{v}Ent(\widetilde D_v) ρ∗Gain(D ,a)=ρ∗Ent(D )−∑v=1Vγ vEnt(D v)
其中: E n t ( D ~ ) = − ∑ k = 1 ∣ y ∣ ρ ~ k l o g 2 ρ ~ k Ent(\widetilde D)=-\sum_{k=1}^{|y|}\widetilde \rho_{k} log_2\widetilde\rho_{ k} Ent(D )=−∑k=1∣y∣ρ klog2ρ k
C4.5算法缺陷:
(1)针对于过拟合问题,这个剪枝算法不够优秀
(2)C4.5算法生成的是多叉树,效率不够高;若是采用二叉树可以提高效率
(3)C4.5算法只能用于分类 (而不能用于回归)
(4)C4.5算法使用了熵模型,里面有大量耗时的对数运算,如果是连续值,还有大量的排序运算。
三、强大的CART算法 即分类回归树算法
CART算法是一种二分递归分割技术,把当前样本划分为两个子样本,使得生成的每个非叶子结点都有两个分支,因此CART算法生成的决策树是结构简洁的二叉树。由于CART算法构成的是一个二叉树,它在每一步的决策时只能是“是”或者“否”,即使一个feature有多个取值,也是把数据分为两部分。在CART算法中主要分为两个步骤
(1)将样本递归划分进行建树过程
(2)用验证数据进行剪枝
CART假设决策树是二叉树,并且可以用于分类也可以用于回归,;使用基尼系数代替了熵模型进行特征选择,也提供了优化的剪枝策略。
基尼值:Gini(D)=
∑
k
=
1
∣
y
∣
∑
k
′
!
=
1
p
k
p
k
′
=
1
−
∑
k
=
1
∣
y
∣
p
k
2
\sum_{k=1}^{|y|}\sum_{k^{'}!=1}p_kp_{k^{'}}=1-\sum_{k=1}^{|y|}p_k^2
∑k=1∣y∣∑k′!=1pkpk′=1−∑k=1∣y∣pk2从样本D中随机抽取两个样本,其类别标记不一致的概率
基尼值Gini(D)越小,则数据集D的纯度越高。
基尼指数:Gini_index(D,a)=
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
G
i
n
i
(
D
v
)
\sum_{v=1}^{V}\frac{|D^v|}{|D|}Gini(D^v)
∑v=1V∣D∣∣Dv∣Gini(Dv)
选择基尼指数最小的属性作为划分属性;基尼值较熵更加优秀=>基尼值没有使用log;
(1)解决过拟合问题
过拟合问题:所建立的决策树模型在训练样本中表现得过于优越,导致数据集以及测试数据集中表现不佳。
预剪枝:预剪枝使得决策树的很多分支都未展开;虽然降低了过拟合风险,减少了训练时间开销和测试时间开销;但是预剪枝基于贪心本质禁止分支展开,会带来了欠拟合风险。
后剪枝: 欠拟合风险小,泛化能力强;但是其训练时间开销>未剪枝决策树>预剪枝决策树
# 红酒案例分类
from sklearn import tree
from sklearn.datasets import load_wine #从datasets库里面导入各种知名的数据
from sklearn.model_selection import train_test_split #测试集和训练集的类
wine = load_wine()
print(wine.target) #3分类的
import pandas as pd
print(pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)) #将数据都变成一张表
print(wine.feature_names) #输出特征值的名字
print(wine.target_names) #输出标签的名字
X_train,X_test,y_train,y_test=train_test_split(wine.data,wine.target,test_size=0.3) #表示30%做测试集,70%是训练集 X_train,X_test,y_train,y_test顺序不能变
print(X_train.shape) #(124, 13)表示训练集有124行13列
print(X_test.shape) #(54, 13)表示测试集有54行13列
clf=tree.DecisionTreeClassifier(criterion="entropy")
clf=clf.fit(X_train,y_train)
score = clf.score(X_test,y_test) #返回预测的准确度
print(score) #0.9259259259259259
#画决策树 需要的是graphviz
import graphviz
dot_data=tree.export_graphviz(clf,
out_file="tree.dot",
feature_names=wine.feature_names,
class_names=["琴酒","雪莉","贝尔摩德"],
filled=True,
rounded=True) #(已经训练好的模型clf,特征的名字feature_names,标签名字class_names)
with open("tree.dot",encoding='utf-8') as f:
dot_data = f.read()
graph = graphviz.Source(dot_data.replace("helvetica","FangSong")) #导出树
# graph.view(filename="mypicture", directory="D:\MyTest") # directory:图片保存的路径,默认是在当前路径下保存 自动弹出图
graph.render(filename='MyPicture9', directory="D:\MyTest",view=True) #view=True 自动弹出, view=False 不弹出图
运行结果:
控制决策树的参数
决策树参数 | 含义 |
---|---|
criterion | 不纯度的衡量指标,有基尼系数和信息熵两种选择 |
max_depth | 树的最大深度,超过最大深度的树枝都会被剪掉 |
min_samples_leaf | 一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生 |
min_samples_split | 一个节点必须包含至少min_samples_split |
max_features | max_features限制分支时候考虑的特征个数,超过限制个数特征都会被舍弃,默认值为总特征个数开平方取整 |
min_impurity_decrease | 限制信息增益的大小,信息增益小于设定数值则分枝不会发生 |