决策树是一种非参数学习算法,既可以哟用于分类,也可以用于回归,具有较好的可解释性
(一)决策树构建过程
1.1熵值
这里的信息熵可以用化学中的熵来理解,化学系统中,一个系统的能量越高,系统越不稳定,熵越高;在一个离散的数组中,数据的不确定性越高,熵越大,反之,不确定性越低,熵越小。
对于一个事件,如果有k种可能,每一种情况的概率为Pi,那么这组数的熵值为(一)式,如果一个系统只有两种信息,那么信息熵的值与一件事的概率的关系如图1-1,可见,两种信息所占的比例相差越小,不确定性越大,信息熵越大。
(一)式 图1-1
1.2根节点的选取
用于分类时,决策树用树状结构表示数据的分类结果。每个决策点实现一个具有离散输出的测试函数,即分支。
下图中根节点相当于第一个决策的节点。叶子节点是最终具有准确输出值的节点。
图1
图二
图三 图四
根节点选取原则:如表中所示为源数据,首先计算,不作为时的熵,最后一列中Y占9/14,N占5/14,熵为
-(5/14ln(5/14)+9/14ln(9/14))=0.94
之后判断单独基于以上四个因素划分时的熵,比如,基于天气划分有三种,sunny、overcast、rainy,三者对应的熵分别为0.971,0,,0971,而三种天气情况出现的概率分别是5/14,4/14,5/14,因此,基于天气情况的信息熵为5/140.971+4/140+5/14*0.971=0.693。则如果以天气为根节点,熵值下降0.247。同样的计算以另外三种座位根节点时的熵值下降量均比天气小。基于此,我们选择outlook为根节点。
选定outlook作为根节点之后,下一个节点的选取基于同样的原理。经过上一步分析可知,outlook为overcast时,结果是确定的Y,与另外三个因素无关。因此在对另外两种天气做进一步的划分时,不考虑overcast,如图2,此时计算天气为sunny和rainy时不作为的情况下的熵值为-(0.5ln0.5+0.5ln0.5)。在计算分别以其他三个因素作为下一个节点时的熵值。选择其中最小的作为下一个节点。之后依次类推。
1.3基尼系数
基尼系数(gini),同样是阿虎局的不确定性却大,基尼系数越大。
1.4代码模拟
-----------------------------------------------------信息熵--------------------------------------------------------
======================信息熵函数======================
from collections import Counter
from math import log
def entropy(y):
counter=Counter(y)
res=0.0
for num in counter.values():
p=num/len(y)
res+=-p*log(p)
return res
======================分割函数=======================
def split(x,y,dimension,value):
index_a=[x[:,dimension]<=value]
index_b=[x[:,dimension]>value]
return x[index_a],x[index_b],y[index_b],y[index_b]
===================最优维度和阈值搜索函数==================
def try_split(x,y):
best_value,best_dimension=-1,-1
best_entropy=float('inf')
for d in range(x.shape[1]):
sorted_index=np.argsort(x[:,d])
for i in range(1,len(x)):
if x[i,d]!=x[i=1,d]:
v=(x[i,d]+x[i-1,d])/2.0
x_l,x_r,y_l,y_r=split(x,y,d,v)
entro=entropy(y_l)+entropy(y_r)
if entro<best_entropy:
best_entropy,best_dimension,best_value=entro,d,v
return best_entropy,best_dimension,best_value
----------------------------------------------基尼系数----------------------------------------------------------
from collections import Counter
from math import log
def split(X, y, d, value):
index_a = (X[:,d] <= value)
index_b = (X[:,d] > value)
return X[index_a], X[index_b], y[index_a], y[index_b]
def gini(y):
counter = Counter(y)
res = 1.0
for num in counter.values():
p = num / len(y)
res -= p**2
return res
def try_split(X, y):
best_g = float('inf')
best_d, best_v = -1, -1
for d in range(X.shape[1]):
sorted_index = np.argsort(X[:,d])
for i in range(1, len(X)):
if X[sorted_index[i], d] != X[sorted_index[i-1], d]:
v = (X[sorted_index[i], d] + X[sorted_index[i-1], d])/2
X_l, X_r, y_l, y_r = split(X, y, d, v)
g = gini(y_l) + gini(y_r)
if g < best_g:
best_g, best_d, best_v = g, d, v
return best_g, best_d, best_v
1.5sklearn中代码实现
sklearn中生成决策树的过程中,有一定的随机因素。有个参数random_state
from sklearn.decision import DecisionTreeClassifier
dt=DecisionTreeClassifier(max_depth=??,criterion='entropy')#信息熵
dt=DecisionTreeClassifier(max_depth=??,criterion='gini')# 基尼系数
(二)CART与决策树中的超参数
以上所用到的决策树是一种基 在某个维度的某个阈值处将数据分成两块的,每一层都是分成两部分,这样的树是二叉树,叫做CART(Classification And Regression Tree)
决策树的复杂度:(1)用于预测时的复杂度为O(logm),(2)构建决策树时的复杂度,n·m·O(logm),这是因为在训练时,依据第(一)中用代码模拟决策树的创建过程中,需要对每一个维度以及当前维度的每一个数值都进行遍历搜索,因此是预测时的n·m倍。
构建决策树时,默认的参数如下,其中,常用的用于防止过拟合的超参数有max_depth、max_leaf_nodes、min_sample_leaf、min_sample_split等,
===============默认参数如下=================
class_weight=None,
criterion='gini',
max_depth=None,
max_features=None,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
min_impurity_split=None,
min_samples_leaf=1,
min_samples_split=2,
min_weight_fraction_leaf=0.0,
presort=False,
random_state=None,
splitter='best'
作为非参数学习,决策树具有非参数学习的共有的缺点——容易过拟合。防止决策树过拟合的一个有效途径是剪枝。以上所列参数中,控制max_depth、max_leaf_nodes(最大的叶子节点数)、min_sample_leaf(一个叶子节点最少需要几个样本)、min_sample_split(一个节点至少有几个样本才进行下一步的划分)的大小,都能够防止过拟合,比如,减小max_depth、增加min_sample_leaf、增加min_sample_split,降低max_leaf_nodes。
如下图中所示为max_depth不同时的,决策边界,显然第一幅图多拟合。
深度不限 深度为2
(三)决策树用于回归
用于回归时,其输出值是相应的叶子节点的所有数值的平均值。
sklearn中代码
from sklearn.tree import DecisionTreeRegressor
dt_reg=DecisionTreeRegressor()
dt_reg.fit(x_train,y_train)
dt_reg.predict(x_test,y_test)
默认情况下,回归器与分类器的参数几乎相同。
(四)决策树的局限性
一、在分类时,决策树所产生的决策边界是横平竖直的(图4-1所示),不适用于偏斜的数据,如图4-2,根据决策树分类的数学原理,经过几次横向和竖向的分割之后,形成如图所示的决策边界,显然对于新的样本的泛化能力较差。
二、对于个别样本点过于敏感。图4-3是剔除掉其中一个样本之后的决策边界,与3-1形成鲜明对比。
图4-1 图4-2 图4-3