决策树的实现和调优(sklearn,GridSearchCV)

前言

上一篇讲了决策树的详细的原理。并手写了ID3的实现。
desision-tree详细原理介绍
本篇就从利用现有sklearn的包,实现决策树

决策树实现

决策树模型简单描述

sklearn提供了两种决策树模型
DecisionTreeClassifier --分类决策树,用于分类任务
DecisionTreeRegressor --回归决策树,用于回归任务

参数介绍

DecisionTreeClassifier 参数

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, class_weight=None, ccp_alpha=0.0)[source]
  1. criterion
    前一篇讲了决策树其实就是在节点分裂上选择最优特征的最优值,进而让划分后的数据集的混乱程度降低,讲了三种分裂节点的标准,分别是信息增益信息增益比gini系数
    criterion有两个可选值:
参数 解释
entropy 表示最终节点分裂标准用的是信息增益或者信息增益比,因为他们在公式计算上都是基于entropy交叉熵的
gini 表示最终节点分裂标准用的是gini系数

通常情况下,信息增益和信息增益比对混乱程度的惩罚很大,也就是对数据更敏感,所以如果数据是高维或者数据噪声比较大时,如果使用entropy 就更容易过拟合,所以通常情况下都喜欢用gini系数

  1. splitter
    决策树是通过在每个节点上寻找最优,进而让整棵树达到最优,但是往往并不是节点最优就代表整棵树最优,所以随之想到就是一次性生成很多棵树,在生成的所有树中找到最优的。

这种生成多棵树的模式下,在树的节点分裂的时候,并不会让所有的特征都参与,而是随机的抽取部分特征来进行选择分裂点,然后,这时候就用到了spllitter,默认为best

best 表示对这部分的特征进行分裂的时候,依旧是选择让纯度最低的进行划分(gini指标或者是entropy )
random 表示对这部分的特征进行分裂的时候,并不考虑什么纯度指标,而是真的随机划分
  1. random_state
    默认为None,表示树分裂时是随机的,具体我还不太明白

通过以上的参数我们其实已经可以通过模型来生成树模型了

from sklearn import tree
clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")

-------------插播----------------
现在问题在于,树已经生成了,树可能存在过拟合和欠拟合等情况,所以就需要考虑剪枝等操作了,也就是需要一些参数来限制我生成的这棵树合适才能停止生长

  1. max_depth
    限制树的最大深度,大于这个深度的,全部剪掉

  2. min_samples_leaf
    在节点分支时,表示分支后的节点至少要含有至少min_samples_leaf 个样本,否则这个节点就不分

  3. min_samples_split
    在节点分支时,表示这个节点本身必须含有至少min_samples_split个样本,否则这个节点就不分,注意和上面一个参数区分,上面是讲这个节点分支后的节点的含有样本最小个数,而这个参数是将这个节点还没分之前自己本身所含有的样本最小个数

  4. max_features
    在节点分裂时,考虑的最大的特征数量,也就是在每一个节点分支划分时,并不是所有的都特征都考虑,而是考虑一部分,大于max_features 的特征都将被舍弃。

  5. min_impurity_decrease
    在节点分支划分时,如果你的criterion用的是entropy ,也就是信息增益或者信息增益比,这个参数就表示信息增益或者信息增益比小于min_impurity_decrease时,节点将不进行划分。

  6. class_weight & min_weight_fraction_leaf
    这两个主要是考虑到样本不平衡,比如正负样本是1:99的时候,这时候就需要将正样本的权重设置得很大,也就说将正样本的影响长度设置大一些。就用到这两个参数。

基于以上,我们就可以建立一颗剪枝后的最优树了

clf = tree.DecisionTreeClassifier(criterion="gini"
                                  ,random_state=10
                                  ,max_depth=30
                                  ,splitter="random"
                                  ,min_samples_leaf=10
                                  ,min_samples_split=10
                                 )
clf = clf.fit(Xtrain,Ytrain)

以上已经介绍清楚了每个参数的意义,这些参数都是超参数,我们是可以自己调节的,那到底该这些参数该选多大呢。自然暴力的办法肯定是把逐个参数都设置一遍,然后比较每个模型的的score情况,高的就是最优模型,那组参数就是我们想要的,但是这样很累。
sklearn提供了一种方法,来帮我们来找出这组参数,那就是GridSearch

网格搜索GridSearch

网格搜索是用于选取模型最优参数组合的一种方法,他由sklearn提供。在使用过程中,我们只需要把我们使用的模型的实例,以及模型待待调试的参数给他,他就可以给我得出一组最优的参数组合。

sklearn.model_selection.GridSearchCV(
estimator, 
param_grid, 
scoring=None,
 n_jobs=None,
 iid=’warn’, 
refit=True, 
cv=’warn’, 
verbose=0, 
pre_dispatch=2*n_jobs’, 
error_score=raise-deprecating’, 
return_train_score=False)

参数介绍

  1. estimator,
    模型的分类器,我们如果是要找决策树的最优参数,则输入的就是我们创建的决策树实例。
  2. param_grid
    一组需要优化的参数取值,必须是字典类型传入,比如
param = [{'criterion':['gini'],'max_depth':[30,50,60,100],'min_samples_leaf':[2,3,5,10],'min_impurity_decrease':[0.1,0.2,0.5]},
         {'criterion':['gini','entropy']},
         {'max_depth': [30,60,100], 'min_impurity_decrease':[0.1,0.2,0.5]}]

模型就会在这些可取的值中,找到一组最优的给我们。

  1. scoring=None
    模型评价标准所选模型不同,评价准则不同。比如scoring=”accuracy”。
    如果不写,或者为None,则默认使用estimator的误差估计函数
  2. n_jobs
    所用到的进程数
  3. refit
    默认为True,表示模型将采用交叉验证的模式来找到最优参数
  4. cv
    交叉验证参数,默认None,使用三折交叉验证。
  5. verbose
    是否打印日志,0打印,1偶尔打印,大于1则实时打印。

介绍完了决策树和网格搜索只有,下面举个例子,来完整演示调优过程。

决策实例

  1. 导入头文件
    有时间再写吧。

你可能感兴趣的:(机器学习,决策树,sklearn,机器学习)