决策树

理解

划分选择

算法分类 划分选择 公式 说明
ID3(Iterative Dichotomiser) 信息增益 Gain(D,a)=Ent(D)-Σ(|D^v|/|D|)*Ent(D^v) 信息增益越大,由属性a划分而来的集合D的纯度越高,则优先将属性a作为该结点的划分依据
C4.5 增益率 Gain_ratio(D,a)=Gain(D,a)/IV(a) 信息增益除以属性a的固有值,找出增益率最高的,属性a可取数目越多,固有值越大。需要注意的是,增益率准则对可取数目较少的属性有所偏好。
CART 基尼指数 Gini(D)=1-Σpk^2 Gini(D)反映了从数据集D种随机挑两个样本,类别不一致的概率。所以基尼值越小,纯度越高。

剪枝处理

预剪枝

基于信息增益准则,选择属性对训练集进行划分,然后再通过验证集进行检验前后划分验证集精度(其实就是预测的正确率),如果提升则进行该次划分。

优点:预剪枝使得决策树的很多分支都没有展开,降低过拟合的风险。

缺点:有些分支的当前划分虽不能提升泛化性能、甚至可能导致泛化性能暂时下降,但在其基础上进行的后续划分却有可能导致性能显著提高,所以预剪枝决策树有欠拟合的风险。

后剪枝

先生成一颗决策树,从最后的节点开始剪枝,如果有利于提高准确度就剪掉。

优点:保留了更多的分支,后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树

缺点:后剪枝过程是在生成完全决策树之后进行的,并且自底向上地对树中所有非叶结点进行逐一考察,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多。

连续与缺失值

连续值处理

确立划分点,划分点是能够使该属性信息增益最大的点。比如一个属性为密度,划分点为0.381,则可以<0.381或者>0.381作为种类的划分。需要注意的是,与离散属性不同,若当前结点划分属性为连续属性,该属性还可作为其后代结点的划分属性(即可以划分区间如<0.381的子结点仍然可以划分出>0.294)

缺失值处理

若某样本属性a缺失,则在进行通过属性a划分时,将该样本同时划分到各个子结点中,只不过要赋予权重,权重为 各个子结点划分得到的样本数/该结点待划分的样本数

多变量决策树

在一个结点里有多个属性参与划分,在多变量决策树的学习过程中,不是为每个非叶结点寻找一个最优属性,而是试图建立一个合适的线性分类器。比如:

​ -8.00×密度 - 0.044×含糖率<=-0.313

​ ↓是 ↓否

​ 好瓜 坏瓜

代码实现

源码实现

调库

sklearn中DecisionTreeClassifier重要参数

sklearn中决策树算法参数共有13个,如下:

class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, splitter=’best’, max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weigh=None, presort=False)

A.重要参数:criterion

划分选择

(1) “entropy”,使用信息熵

(2) “gini”,使用基尼系数(默认)

信息熵对不纯度更加敏感,对不纯度的惩罚最强。

B.重要参数:random_state&splitte

random_state用来设置分枝中的随机模式的参数,在高维度时随机性会表现更明显。

输入任意整数,会一直长出同一颗树,让模型稳定下来

splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best”,决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random”,决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这也是防止过拟合的一种方式。当你预测到你的模型会过拟合,用这两个参数来帮助你降低树建成之后过拟合的可能性。当然,树一旦建成,我们依然是使用剪枝参数来防止过拟合

C.重要参数:剪枝参数

(1)max_depth

限制树的最大深度,超过设定深度的树枝全部剪掉

(2)min_samples_leaf

min_samples_leaf(最少的节点) 每个分支下至少有该参数数量的节点,否则分枝就不会产生,或者朝着min_samples_leaf方向去发生。

一般搭配max_depth使用,在回归树中可以让模型变得更加平滑。太小引起过拟合。

一般来说建议5开始使用。

(3)min_samples_split

min_samples_split限定,一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生。

(4)min_features

max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃

(5)min_impurity_decrease

min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。

D.确认最优的剪枝参数

其实就是运用循环改变参数,确定出准确度最高的参数(也就是最优参数)

from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

wine = load_wine()

xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)

clf=tree.DecisionTreeClassifier(criterion="entropy"
,random_state=30
                                ,splitter="random"
,max_depth=3
                                ,min_samples_leaf=10
                                ,min_samples_split=70
                                )
clf=clf.fit(xtrain,ytrain)  #把训练数据集放入到分类器中,fit来寻找相应标签
score = clf.score(xtest,ytest) #score是针对上面模型评估精确度
print(score)

import graphviz
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚'
,'类黄酮','非黄烷类酚类','花青素','颜 色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
dot_data = tree.export_graphviz(clf
                                , feature_names=feature_name
                                , class_names=["琴酒", "雪莉", "贝尔摩德"]
                                , filled=True
, rounded=True
)

graph = graphviz.Source(dot_data)
graph.view()




import matplotlib.pyplot as plt
test = []f
for i in range(10):
    clf=tree.DecisionTreeClassifier(max_depth=i+1
                                    ,criterion="entropy"
,random_state=30
                                    )
    clf=clf.fit(xtrain,ytrain)
    score_train = clf.score(xtrain, ytrain)
    test.append(score)
plt.plot(range(1,11),test,color='red',label='max_depth')
plt.legend()
plt.show()

E.目标权重参数

(1)class_weight

完成样本标签平衡的参数。比如判断“信用卡持有人是否违约”的比例为(1%:99%)。这种分类状态,即便模型什么也不做,全部结果预测“否”,正确率也能有99%。因此我们要使用class_weight参数对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给与数据集中的所有标签相同的权重。

(2)min_weight_fraction_leaf

有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_ weight_fraction_leaf这个基于权重的剪枝参数来使用。另请注意,基于权重的剪枝参数(例如min_weight_ fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。

F.重要属性和接口

最重要的属性是feature_importances_,能够查看各个特征对模型的重要性

clf=tree.DecisionTreeClassifier()
feature_importances=clf.feature_importances_
# 输出feature就会得到各个特征对模型的重要性
clf.fit(xtrain,ytrain)
clf.score(xtest,ytest)
clf.apply(xtest)  #返回
clf.predict(xtest) #输出预测结果

fit(训练模型) score(准确性) apply(输入测试集返回每个测试样本所在的叶子节点的索引)

predict(预测)


Machine Learning     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!