决策树
理解
划分选择
算法分类 | 划分选择 | 公式 | 说明 |
---|---|---|---|
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(预测)
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!