Python机器学习(二):决策树(Decision Tree-DTs)

Python机器学习(二):决策树(Decision Tree-DTs)

目录:

  • Python机器学习(二):决策树(Decision Tree-DTs)
  • 一、什么是决策树
    • 1.基本概念
    • 2.决策树算法的核心问题
    • 3.决策树的优缺点
  • 二、决策树的原理
    • 1.ID3 算法
      • 1.1 ID3 算法步骤
      • 1.2 信息熵、条件熵和信息增益
    • 2.C4.5 算法
      • 2.1 信息增益率
      • 2.2 C4.5 剪枝
      • 2.3 C4.5 算法的缺点
    • 3.CART 算法
      • 3.1 CART 算法介绍
      • 3.2 分类问题——基尼指数(Gini)
      • 3.3 回归问题——均方差
      • 3.4 CART 剪枝步骤
    • 4.决策树算法差异总结
  • 三、决策树的sklearn实现
    • 1.sklearn中的决策树类
    • 2.分类决策树
      • 2.1 构建一棵分类决策树
      • 2.2 可视化
      • 2.3 剪枝参数
      • 2.4 确定最优的剪枝参数
    • 3.回归决策树
      • 3.1 构建一棵回归决策树
      • 3.2 交叉验证
  • 四、案例:泰坦尼克号幸存者预测


一、什么是决策树

1.基本概念

决策树是一种用于分类和回归的非参数有监督学习方法,其目标是创建一个模型,通过学习从数据特性中推断出的简单决策规则来预测目标变量的值,决策树算法,简单来说,就是一系列的 if...then...else 组合

如表所示:

名称 体温 表皮 胎生 水生生物 飞行生物 标签
人类 恒温 毛发 哺乳类
鲸鱼 恒温 毛发 哺乳类
鸽子 恒温 羽毛 鸟类
海龟 冷血 鳞片 爬行类
蝾螈 冷血 两栖类
蜘蛛

如果目标是对哺乳类和非哺乳类进行分类,则根据上表建立的决策树模型:

Python机器学习(二):决策树(Decision Tree-DTs)_第1张图片
决策树的决策过程就是从根节点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子节点,将叶子节点的存放的类别作为决策结果

建立决策树模型的一般步骤: (一)特征选择、(二)决策树的生成、(三)决策树的修剪

2.决策树算法的核心问题

  1. 如何从数据表中找出最佳节点和最佳分枝
    数据表中有很多属性/特征,如何选择特征和特征的顺序来构建性能最佳的决策树?
  2. 如何让决策树停止生长,防止过拟合
    为了尽可能正确地分类训练集,决策数会为所有属性都建立节点,这样就可能对训练样本学习得“太好”了,把训练样本的一些特点当做所有数据都具有的一般性质,从而导致过拟合
    解决过拟合问题,我们需要对决策树进行剪枝处理

3.决策树的优缺点

  • 优点:
    1.易于理解和解释,决策树可以被可视化
    2.几乎不需要数据准备,其他算法通常需要数据标准化,需要创建虚拟变量并删除缺失值
    3.可自动忽略目标变量没有贡献的属性变量,也为判断属性变量的重要性,减少变量的数目提供参考
  • 缺点:
    1.容易造成过拟合,需要采用剪枝操作
    2.忽略了数据之间的相关性
    3.对于各类别样本数量不一致的数据,信息增益会偏向于那些更多数值的特征

二、决策树的原理

建立决策树的关键,即在当前状态下选择哪个属性作为分类依据,根据不同的目标函数,建立决策树主要有以下三种算法:

  • ID3(Iterative Dichotomiser)
  • C4.5、C5.0
  • CART(Classification And Regression Tree)
算法 支持场景 树结构 特征选择 连续值处理 缺失值处理 剪枝 特征属性多次使用
ID3 分类 多叉树 信息增益 不支持 不支持 不支持 不支持
C4.5 分类 多叉树 信息增益率 支持 支持 支持 不支持
CART 分类、回归 二叉树 基尼指数均方差 支持 支持 支持 支持

1.ID3 算法

  • ID3 算法的核心是信息熵期望信息越小,信息熵越大,样本纯度越低,决策树对训练集的拟合度越差;期望信息越多,信息熵越小,样本纯度越高,决策树对训练集的拟合度越差。而熵越小,信息增益越大
  • ID3 算法计算每个属性的信息增益,并利用信息增益作为决策树每级节点属性的选择标准

1.1 ID3 算法步骤

  1. 准备好训练集特征和训练集数据
  2. 计算数据集合的信息熵所有特征的条件熵,选择信息增益最大的特征作为决策树当前最优决策节点
  3. 删除上一步已使用的特征/属性,并按照已构建的决策树节点,将训练集数据分类
  4. 分析分类效果,决定是否重复 2,3 两步;若最后子集值包含单一特征,则为分支叶子节点

1.2 信息熵、条件熵和信息增益

信息熵的表示式为:
H ( D ) = − ∑ i = 1 n p i ( log ⁡ 2 p i ) H(D)=-\sum_{i=1}^n{p_i(\log_2{p_i})} H(D)=i=1npi(log2pi)

其中, D D D 表示一个数据集, n n n 表示这是 n n n分类问题, i i i 表示某一标签,样本点属于标签 i i i 的概率为 p i p_i pi

如果数据集根据某个属性 A A A 被划分为 m m m 类,条件熵的表示式为:

H ( D ∣ A ) = ∑ j = 1 m D j D H ( D j ) H(D|A)=\sum_{j=1}^m{ {D_j \over D}H(D_j)} H(DA)=j=1mDDjH(Dj)

其中, D D D 表示数据集的样本数, A A A 是某一特征/属性, m m m 表示该属性有多少种不同类别, j j j 表示该属性的某一类, D j D_j Dj 表示属于 j j j 类的样本数目, H ( D j ) H(D_j) H(Dj) 表示属于 j j j 类的样本的信息熵

信息增益的表示式为:
G a i n ( D , A ) = H ( D ) − H ( D ∣ A ) Gain(D,A)=H(D)−H(D|A) Gain(D,A)=H(D)H(DA)

其中, G a i n ( D , A ) Gain(D,A) Gain(D,A) 表示数据集 D D D 中,属性 A A A 的信息增益

例如: 下面训练集中,样本总数: 15 15 15,类别数: n = 2 n=2 n=2,显然这是二分类问题,计算 A = 年 龄 A=年龄 A= 时划分的信息增益

Python机器学习(二):决策树(Decision Tree-DTs)_第2张图片
其中标签为 的样本有6个,标签为 的样本有9个,因此训练集的信息熵为:
H = − ∑ i = 1 2 p i ( log ⁡ 2 p i ) = − 6 15 ( log ⁡ 2 6 15 ) − 9 15 ( log ⁡ 2 9 15 ) ≈ 0.971 H=-\sum_{i=1}^2{p_i(\log_2p_i)}=-{6 \over 15}(\log_2{6 \over 15})-{9 \over 15}(\log_2{9 \over 15})≈0.971 H=i=12pi(log2pi)=156(log2156)159(log2159)0.971

如果按年龄划分,则此时

序号 年龄 数目 类别:是 类别:否
1 青年 5 2 3
2 中年 5 3 2
3 老年 5 4 1

首先分别计算 H ( D j = 1 ) H(D_{j=1}) H(Dj=1) H ( D j = 2 ) H(D_{j=2}) H(Dj=2) H ( D j = 3 ) H(D_{j=3}) H(Dj=3) 的大小:
H ( D j = 1 ) = − 2 5 ( log ⁡ 2 2 5 ) − 3 5 ( log ⁡ 2 3 5 ) ≈ 0.971 H(D_{j=1})=-{2 \over 5}(\log_2{2 \over 5})-{3 \over 5}(\log_2{3 \over 5})≈0.971 H(Dj=1)=52(log252)53(log253)0.971

H ( D j = 2 ) = − 3 5 ( log ⁡ 2 3 5 ) − 2 5 ( log ⁡ 2 2 5 ) ≈ 0.971 H(D_{j=2})=-{3 \over 5}(\log_2{3 \over 5})-{2 \over 5}(\log_2{2 \over 5})≈0.971 H(Dj=2)=53(log253)52(log252)0.971

H ( D j = 3 ) = − 4 5 ( log ⁡ 2 4 5 ) − 1 5 ( log ⁡ 2 1 5 ) ≈ 0.7219 H(D_{j=3})=-{4 \over 5}(\log_2{4 \over 5})-{1 \over 5}(\log_2{1 \over 5})≈0.7219 H(Dj=3)=54(log254)51(log251)0.7219

此时,分别计算条件熵为:
H ( D ∣ 年 龄 ) = ∑ j = 1 3 D j D H ( D j ) = 5 15 × 0.971 + 5 15 × 0.971 + 5 15 × 0.7219 ≈ 0.8897 H(D|年龄)=\sum_{j=1}^3{ {D_j \over D}H(D_j)}={ {5 \over 15}\times0.971}+{ {5 \over 15}\times0.971}+{ {5 \over 15}\times0.7219}≈0.8897 H(D)=j=13DDjH(Dj)=155×0.971+155×0.971+155×0.72190.8897

计算信息增益为:
G a i n ( D , 年 龄 ) = H ( D ) − H ( D ∣ 年 龄 ) = 0.971 − 0.8897 = 0.2491 Gain(D,年龄)=H(D)−H(D|年龄)=0.971-0.8897=0.2491 Gain(D,)=H(D)H(D)=0.9710.8897=0.2491

同理,我们可以计算出 A A A 分别为 {有工作, 有房子, 信用} 时的信息增益,最后比较 A A A 取不同属性时信息增益的大小,最终我们将选取信息增益最大的属性作为决策树的节点

2.C4.5 算法

C4.5 算法是对 ID3 算法的改进,其使用的是信息增益率而非信息增益来选择属性,并且加入了剪枝操作

2.1 信息增益率

信息增益的表示式为:
I G R = G a i n ( D , A ) H ( D ) , 其 中 G a i n ( D , A ) = H ( D ) − H ( D ∣ A ) IGR={Gain(D,A) \over H(D)},其中Gain(D,A)=H(D)−H(D|A) IGR=H(D)Gain(D,A)Gain(D,A)=H(D)H(DA)

其中, H ( D ) H(D) H(D) 为训练集的信息熵,其实求信息增益率就是比求信息增益多一个除法运算的步骤

2.2 C4.5 剪枝

由于决策树容易过拟合,因此我们需要对决策树进行剪枝,以提高其泛化性能

剪枝的基本策略有“预剪枝”(prepruning)和“后剪枝”(post-pruning)

  • 预剪枝策略:
    预剪枝在划分节点前,就要先确定决策树是否继续增长,及时停止增长

    停止增长的主要判断依据:
    节点内数据样本已低于某一阈值
    所有节点特征都已划分
    节点划分前准确率比划分后准确率高

    预剪枝的特点:
    预剪枝不仅可以降低过拟合的风险而且还可以减少训练时间,但另一方面它是基于“贪心”策略,会带来欠拟合风险

  • 后剪枝策略:
    在已经生成的决策树上进行剪枝,从而得到简化版的剪枝决策树
    后剪枝决策树通常比预剪枝决策树保留了更多的分支

    后剪枝主要方法:
    采用的悲观剪枝方法,用递归的方式从低往上针对每一个非叶子节点,评估用一个最佳叶子节点去代替这课子树是否有益,如果剪枝后与剪枝前相比其错误率是保持或者下降,则这棵子树就可以被替换掉
    通过训练数据集上的错误分类数量来估算未知样本上的错误率

    后剪枝的特点:
    一般情况下,后剪枝的欠拟合风险更小,泛化性能往往优于预剪枝决策树

2.3 C4.5 算法的缺点

  1. 剪枝策略可以再优化,且其使用的是多叉树,而使用二叉树效率更高
  2. C4.5 算法只能用于分类
  3. C4.5 使用的熵模型拥有大量耗时的对数运算,连续值还有排序运算
  4. C4.5 在构造树的过程中,对数值属性值需要按照其大小进行排序,从中选择一个分割点,所以只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时,程序无法运行

3.CART 算法

3.1 CART 算法介绍

基尼指数来选择属性(分类),或用均方差来选择属性(回归),基尼指数表示集合的不确定性

显然,CART 算法既可以用于创建分类树,也可以用于创建回归树,两者的构建过程稍有差异,如果目标变量是离散的,称为分类树,如果目标变量是连续的,称为回归树

3.2 分类问题——基尼指数(Gini)

在多分类问题中,概率分布的基尼指数为:
G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) Gini(p)=\sum_{k=1}^K{p_k(1-p_k)} Gini(p)=k=1Kpk(1pk)

其中, K K K 表示这是 K K K分类问题, k k k 表示某一标签,样本点属于标签 k k k 的概率为 p k p_k pk

在二分类问题中,概率分布的基尼指数为:
G i n i ( p ) = 2 p ( 1 − p ) = 1 − p 2 − ( 1 − p ) 2 Gini(p)=2p(1-p)=1-p^2-(1-p)^2 Gini(p)=2p(1p)=1p2(1p)2

其中, p p p 表示样本标签属于任一标签的概率, ( 1 − p ) (1-p) (1p) 则与 p p p 互补

由于 CART 需要构建二叉树,因此应根据某一属性将数据集划分为两类,假如数据集根据属性 A A A 划分为 D 1 D_1 D1 D 2 D_2 D2 两部分,则基尼指数表示式为:
G i n i ( D , A ) = D 1 D G i n i ( D 1 ) + D 2 D G i n i ( D 2 ) Gini(D,A)={D_1 \over D}Gini(D_1)+{D_2 \over D}Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)

其中, D D D 表示数据集的样本数,且满足 D = D 1 + D 2 D=D_1+D_2 D=D1+D2 G i n i ( D 1 ) Gini(D_1) Gini(D1) G i n i ( D 2 ) Gini(D_2) Gini(D2) p k p_k pk 分别是 D 1 D_1 D1 D 2 D_2 D2 中样本点属于标签 k k k 的概率

例如: 分别计算按:{ D 1 = 青 年 D_1=青年 D1= D 2 = 其 他 D_2=其他 D2= }、{ D 1 = 中 年 D_1=中年 D1= D 2 = 其 他 D_2=其他 D2= }、{ D 1 = 老 年 D_1=老年 D1= D 2 = 其 他 D_2=其他 D2= } 来划分数据集时的基尼指数
Python机器学习(二):决策树(Decision Tree-DTs)_第3张图片
①按 { D 1 = 青 年 D_1=青年 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
G i n i ( D , A 1 = 青 年 ) = 5 15 [ 2 × 2 5 × ( 1 − 2 5 ) ] ⏟ G i n i ( D 1 ) + 10 15 [ 2 × 7 10 × ( 1 − 7 10 ) ] ⏟ G i n i ( D 2 ) = 0.44 Gini(D,A_1=青年)={5 \over 15}\underbrace{[2 \times{2 \over 5}\times(1-{2 \over 5})]}_{Gini(D_1)}+{10 \over 15}\underbrace{[2 \times{7 \over 10}\times(1-{7 \over 10})]}_{Gini(D_2)}=0.44 Gini(D,A1=)=155Gini(D1) [2×52×(152)]+1510Gini(D2) [2×107×(1107)]=0.44

②按 { D 1 = 中 年 D_1=中年 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
G i n i ( D , A 2 = 中 年 ) = 5 15 [ 2 × 3 5 × ( 1 − 3 5 ) ] ⏟ G i n i ( D 1 ) + 10 15 [ 2 × 6 10 × ( 1 − 6 10 ) ] ⏟ G i n i ( D 2 ) = 0.48 Gini(D,A_2=中年)={5 \over 15}\underbrace{[2 \times{3 \over 5}\times(1-{3 \over 5})]}_{Gini(D_1)}+{10 \over 15}\underbrace{[2 \times{6 \over 10}\times(1-{6 \over 10})]}_{Gini(D_2)}=0.48 Gini(D,A2=)=155Gini(D1) [2×53×(153)]+1510Gini(D2) [2×106×(1106)]=0.48

③按 { D 1 = 老 年 D_1=老年 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
G i n i ( D , A 3 = 老 年 ) = 5 15 [ 2 × 4 5 × ( 1 − 4 5 ) ] ⏟ G i n i ( D 1 ) + 10 15 [ 2 × 5 10 × ( 1 − 5 10 ) ] ⏟ G i n i ( D 2 ) = 0.44 Gini(D,A_3=老年)={5 \over 15}\underbrace{[2 \times{4 \over 5}\times(1-{4 \over 5})]}_{Gini(D_1)}+{10 \over 15}\underbrace{[2 \times{5 \over 10}\times(1-{5 \over 10})]}_{Gini(D_2)}=0.44 Gini(D,A3=)=155Gini(D1) [2×54×(154)]+1510Gini(D2) [2×105×(1105)]=0.44

3.3 回归问题——均方差

根据某一属性 = a =a A=a 进行划分,选择任一划分点 s 将数据集划分成 D 1 D_1 D1 D 2 D_2 D2 两个集合,求出使 D 1 D_1 D1 D 2 D_2 D2 各自集合的均方差最小,同时求出使 D 1 D_1 D1 D 2 D_2 D2 的均方差值的最小值之和具有最小值:
m = m i n a , s [ m i n c 1 ∑ x i ∈ D 1 ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ D 2 ( y i − c 2 ) 2 ] m=min_{a,s}[min_{c_1}\sum_{x_i\in D_1}(y_i-c_1)^2+min_{c_2}\sum_{x_i\in D_2}(y_i-c_2)^2] m=mina,s[minc1xiD1(yic1)2+minc2xiD2(yic2)2]

其中, x i x_i xi 表示输入值, y i y_i yi 表示对应的输出值, c 1 c_1 c1 D 1 D_1 D1 数据集的所有样本输出值的均值, c 2 c_2 c2 D 2 D_2 D2 数据集的所有样本输出值的均值

使上式成立时的属性 a a a 和划分点 s s s 就是最佳输入值划分属性和最佳输入值划分点;此时的 c 1 c_1 c1 c 2 c_2 c2 分别就是划分出两类的输出预测值

例如: 看下表,计算按属性 A = 职 业 A=职业 A= 划分时, { “ 学 生 ” , “ 上 班 族 ” , “ 老 师 ” } \{“学生”,“上班族”,“老师”\} { ,,} 的最佳输入值划分点 s s s 和输出预测值

Python机器学习(二):决策树(Decision Tree-DTs)_第4张图片
①按 { D 1 = 学 生 D_1=学生 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
c 1 = 12 + 18 + 21 3 = 17 , c 2 = 26 + 47 + 36 + 29 4 = 34.5 c_1={12+18+21 \over 3}=17,c_2={26+47+36+29 \over 4}=34.5 c1=312+18+21=17c2=426+47+36+29=34.5

m = ∑ x i ∈ D 1 ( y i − c 1 ) 2 + ∑ x i ∈ D 2 ( y i − c 2 ) 2 = 303 , 其 中 y i ∈ { ( 12 , 18 , 21 ) , ( 26 , 47 , 36 , 29 ) } m=\sum_{x_i\in D_1}(y_i-c_1)^2+\sum_{x_i\in D_2}(y_i-c_2)^2=303,其中y_i\in\{(12,18,21),(26,47,36,29)\} m=xiD1(yic1)2+xiD2(yic2)2=303yi{ (12,18,21),(26,47,36,29)}

②按 { D 1 = 老 师 D_1=老师 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
c 1 = 26 + 29 2 = 27.5 , c 2 = 12 + 18 + 47 + 36 + 21 5 = 26.5 c_1={26+29 \over 2}=27.5,c_2={12+18+47+36+21 \over 5}=26.5 c1=226+29=27.5c2=512+18+47+36+21=26.5

m = ∑ x i ∈ D 1 ( y i − c 1 ) 2 + ∑ x i ∈ D 2 ( y i − c 2 ) 2 = 742.66 , 其 中 y i ∈ { ( 26 , 29 ) , ( 12 , 18 , 47 , 36 , 21 ) } m=\sum_{x_i\in D_1}(y_i-c_1)^2+\sum_{x_i\in D_2}(y_i-c_2)^2=742.66,其中y_i\in\{(26,29),(12,18,47,36,21)\} m=xiD1(yic1)2+xiD2(yic2)2=742.66yi{ (26,29),(12,18,47,36,21)}

③按 { D 1 = 上 班 族 D_1=上班族 D1= D 2 = 其 他 D_2=其他 D2= } 划分时:
c 1 = 47 + 36 2 = 41.5 , c 2 = 12 + 18 + 26 + 29 + 21 5 = 21.2 c_1={47+36 \over 2}=41.5,c_2={12+18+26+29+21 \over 5}=21.2 c1=247+36=41.5c2=512+18+26+29+21=21.2

m = ∑ x i ∈ D 1 ( y i − c 1 ) 2 + ∑ x i ∈ D 2 ( y i − c 2 ) 2 = 238.8 , 其 中 y i ∈ { ( 47 , 36 ) , ( 12 , 18 , 26 , 29 , 21 ) } m=\sum_{x_i\in D_1}(y_i-c_1)^2+\sum_{x_i\in D_2}(y_i-c_2)^2=238.8,其中y_i\in\{(47,36),(12,18,26,29,21)\} m=xiD1(yic1)2+xiD2(yic2)2=238.8yi{ (47,36),(12,18,26,29,21)}

比较知: 238.8 < 303 < 742.66 238.8<303<742.66 238.8<303<742.66,因此,当按 a = 职 业 a=职业 a= 划分时,有:
m i n 职 业 [ m i n c 1 ∑ x i ∈ D 1 ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ D 2 ( y i − c 2 ) 2 ] min_{职业}[min_{c_1}\sum_{x_i\in D_1}(y_i-c_1)^2+min_{c_2}\sum_{x_i\in D_2}(y_i-c_2)^2] min[minc1xiD1(yic1)2+minc2xiD2(yic2)2]

此时,按 { D 1 = 上 班 族 D_1=上班族 D1= D 2 = 其 他 D_2=其他 D2= } 作为输入划分,而 c 1 = 41.5 , c 2 = 21.2 c_1=41.5,c_2=21.2 c1=41.5c2=21.2 则为输出预测值最佳
f ( x ) = { 41.5 , x ∈ { 上 班 族 } 21.2 , x ∈ { “ 老 师 ” , “ 学 生 ” } f(x)=\left\{ \begin{aligned} 41.5&,x\in\{上班族\} \\ 21.2&,x\in\{“老师”,“学生”\} \end{aligned} \right. f(x)={ 41.521.2x{ }x{ ,}

实际上,我们只计算了 A = 职 业 A=职业 A= 的情况,还需要计算 A = { “ 看 电 视 时 长 ” , “ 婚 姻 状 况 ” } A=\{“看电视时长”,“婚姻状况”\} A={ ,} 的情况,才能计算出均方差的最小值 m i n a , s [ m i n c 1 ∑ x i ∈ D 1 ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ D 2 ( y i − c 2 ) 2 ] min_{a,s}[min_{c_1}\sum_{x_i\in D_1}(y_i-c_1)^2+min_{c_2}\sum_{x_i\in D_2}(y_i-c_2)^2] mina,s[minc1xiD1(yic1)2+minc2xiD2(yic2)2] 才能筛选出最佳的划分属性及其划分点和输出值

3.4 CART 剪枝步骤

  1. 计算每一个节点的条件熵
  2. 递归地从叶子节点开始往上遍历,减掉叶子节点,然后判断损失函数的值是否减少,若减少,则将父节点作为新的叶子节点
  3. 重复2,直到完全不能剪枝为止
  • CART 剪枝的特点:
    CART 算法采用一种“基于代价复杂度的剪枝”方法进行后剪枝,这种方法会生成一系列树,每棵树都是通过将前面的树的某个或某些子树替换成一个叶节点而得到的,这一系列树中的最后一棵树仅含一个用来预测类别的叶节点。然后用一种成本复杂度的度量准则来判断哪棵子树应该被一个预测类别值的叶节点所代替
    这种方法需要使用一个单独的测试数据集来评估所有的树,根据它们在测试数据集熵的分类性能选出最佳的树

4.决策树算法差异总结

  • 划分标准的差异:
    ID3 使用的信息增益偏向于特征值多的特征
    C4.5 使用的信息增益率克服了信息增益的缺点,偏向于特征值少的特征
    CART 使用基尼指数克服了 C4.5 对 log 的巨大计算量,偏向于特征值较多的特征
  • 使用场景的差异:
    ID3 和 C4.5 均只能用于分类问题
    CART 可以用于分类和回归问题
    ID3 和 C4.5 是多叉树,速度较慢,CART 是二叉树,计算速度很快
  • 样本数据的差异:
    ID3 只能处理离散数据,且该算法对缺失值敏感
    C4.5 和 CART 可以处理连续性数据且有多种方式处理缺失值
    如果从样本量来考虑,小样本建议使用 C4.5、大样本建议使用 CART
    C4.5 处理过程中需对数据集进行多次扫描排序,处理成本耗时较高,而 CART 本身是一种大样本的统计方法,小样本处理下泛化误差较大
  • 样本特征的差异:
    ID3 和 C4.5 层级之间只使用一次特征,CART 可多次重复使用特征
  • 剪枝策略的差异:
    ID3 没有剪枝策略,C4.5 是通过悲观剪枝策略来修正树的准确性,而 CART 是通过代价复杂度剪枝

三、决策树的sklearn实现

本文仅展示常用参数,若想了解更详细的参数,请参考:sklearn中文社区

1.sklearn中的决策树类

# 导入决策树模块
from sklearn import tree
类方法 解释
tree.DecisionTreeClassifier 分类树
tree.DecisionTreeRegressor 回归树
tree.export_graphviz 将生成的决策树导出为DOT格式,实现决策树可视化
tree.ExtraTreeClassifier 高随机版本的分类树
tree.ExtraTreeRegressor 高随机版本的回归树

2.分类决策树

2.1 构建一棵分类决策树

clf = tree.DecisionTreeClassifier(…)

初始化分类树

criterion 切分依据:{“gini”:基尼指数, “entropy”:信息增益}, default=”gini”
splitter 拆分策略选择:{“best”:最佳拆分策略, “random”:最佳随机拆分策略}, default=”best”
max_depth 树的最大深度:int, default=None,int 类型:树的最大深度,None:将所有节点展开
min_samples_split 一个节点必须要包含至少 min_samples_split 个训练样本,这个节点才允许被分枝,否则分枝就不会发生:int or float, default=2,int 类型:样本数,float 类型:占样本总数的比例,向下取整
min_samples_leaf 节点在分枝后的每个子节点必须包含至少 min_samples_leaf 个训练样本,否则不会分枝:int or float, default=1,int 类型:样本数,float 类型:占样本总数的比例,向下取整
(即该参数规定了叶子节点处所需的最小样本数)
max_features 寻找最佳划分属性时要考虑的属性数量:int, float or {“auto”, “sqrt”, “log2”}, default=None
min_impurity_decrease 如果节点分枝会导致不纯度的减少大于或等于该值,则该节点将被分裂分枝:float, default=0.0
返回值 分类决策树对象

clf.fit(X, y[, sample_weight, check_input, …])

根据训练集数据和标签 (X,y)建立决策树分类器
X 必须是二维及以上的数组
y 必须是一维数组,注:shape=(1,80) 仍然是二维数组,shape=(80, ) 才是一维数组


clf.score(X, y[, sample_weight])

使用测试集数据和标签 (X,y) 测试决策树,并返回给定测试数据和标签上的平均准确度

clf.feature_importances_

查看各属性在决策树中的贡献度

clf.apply(X_test)

返回每个测试样本所在的叶子节点的索引

clf.predict(X_test)

返回每个测试样本的分类/回归预测结果

例如: 导入葡萄酒数据集,对决策树进行训练、测试,并输出准确度

# 导入相关库
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn import tree

# 加载并返回葡萄酒数据集
wine = load_wine()

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3)

# 初始化决策树
clf = tree.DecisionTreeClassifier()
# 训练决策树
clf = clf.fit(X_train, y_train)
# 测试决策树
score = clf.score(X_test, y_test)
predict = clf.predict(X_test)
score, predict

打印准确度和分类情况:
Python机器学习(二):决策树(Decision Tree-DTs)_第5张图片

2.2 可视化

# 导入相关库
import graphviz

dot_data = tree.export_graphviz(…)

绘图,把决策树可视化

decision_tree 用来做可视化的决策树对象
out_file 输出文件的名称,如果为 None,则结果以字符串形式返回
max_depth 描绘的最大深度,如果为 None,则这树完全生长
feature_names 每个特征的名字:list of strings, optional, default=None
class_names 每个目标类别/标签的名称(按升序排列):list of strings, bool or None, default=None
label 是否显示不纯度的信息性标签等:{‘all’:显示在每个节点上, ‘root’:显示在根节点上, ‘none’:显示任何节点上}, default=’all’
filled bool, default=False,设置为True时,绘制节点以表示多数类用于分类问题,值的极值用于回归问题,或表示节点的纯度用于多输出问题,简单来说,就是给方框填充颜色,而颜色的深浅代表节点的纯度
rounded 设置为True时,绘制带有圆角的节点框,并使用赫维提卡字体 (Helvetica) 代替新罗马字体 (Times-Roman)
返回值 string,树模型 GraphViz dot 格式的字符串

graphviz.Source(dot_data)

将树模型的 GraphViz dot 格式字符串转化为可视化图片

例如: 将葡萄酒决策树可视化

# 导入相关库
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn import tree
import graphviz

# 加载并返回葡萄酒数据集
wine = load_wine()

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3)

# 初始化决策树
clf = tree.DecisionTreeClassifier()
# 训练决策树
clf = clf.fit(X_train, y_train)
# 测试决策树
score = clf.score(X_test, y_test)

# 根据数据集,定义一个中文的属性名列表和分类标签列表
feature_names = ['酒精', '苹果酸', '灰', '灰的碱性', '镁',
                '总酚', '类黄酮', '非黄烷类酚类', '花青素',
                '颜色强度', '色调', 'od280/od315稀释葡萄酒', '脯氨酸']
class_names = ["琴酒", "雪莉", "贝尔摩德"]

# 将决策树可视化
dot_data = tree.export_graphviz(clf,
                                feature_names = feature_names,
                                class_names = class_names,
                                filled = True,
                                rounded = True)
graph = graphviz.Source(dot_data)
graph

输出结果如图所示,当然每次运作出来的结果可能不一样:(因为我们在调用 train_test_split() 方法时并没有设置随机数种子,因此它每次分配训练集和数据集都是随机的,因此我们可以设置 random_state=?,使得每次构建的决策树是一样的,而我们可以通过调整 random_state 的值,来决定选择精度最高的决策树模型)

Python机器学习(二):决策树(Decision Tree-DTs)_第6张图片
我们发现,所构建的决策树并没有使用全部属性:(其中输出的数是各属性对构建决策树的贡献度,根节点对决策树的贡献一般是最高的)
Python机器学习(二):决策树(Decision Tree-DTs)_第7张图片

2.3 剪枝参数

为了避免决策树过拟合,我们可以对决策树进行剪枝

DecisionTreeClassifier(…) 的剪枝相关参数:
max_depth 树的最大深度:int, default=None,int 类型:树的最大深度,None:将所有节点展开
min_samples_split 一个节点必须要包含至少 min_samples_split 个训练样本,这个节点才允许被分枝,否则分枝就不会发生:int or float, default=2,int 类型:样本数,float 类型:占样本总数的比例,向下取整
min_samples_leaf 节点在分枝后的每个子节点必须包含至少 min_samples_leaf 个训练样本,否则不会分枝:int or float, default=1,int 类型:样本数,float 类型:占样本总数的比例,向下取整

  • max_depth 一般越小越好,因为树的深度越低,泛化性能越好,树的深度越深,意味着对样本的数量需求翻倍,建议从 3 开始寻找
  • min_samples_leaf 该参数太小会引起过拟合,太大会阻止模型学习数据,一般建议从 5 开始使用;对于类别不多的分类问题,1 通常就是最佳选择
  • 调节这些参数,使得测试集精度越高越好

DecisionTreeClassifier(…) 的剪枝相关参数:(搭配 max_depth 使用,这些参数用于树的“精修”)
max_features 寻找最佳划分属性时要考虑的属性数量:int, float or {“auto”, “sqrt”, “log2”}, default=None
min_impurity_decrease 如果节点分枝会导致不纯度的减少大于或等于该值,则该节点将被分裂分枝:float, default=0.0

  • max_features 用来限制高维度数据的过拟合的剪枝参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足,如果希望通过降维的方式防止过拟合,建议使用 PCA、ICA 或特征选择模块中的降维算法
  • min_impurity_decrease 限制信息增益的大小,信息增益小于设定数值的分枝不会发生,该值通常在 0~0.5 之间

DecisionTreeClassifier(…) 中较少使用,但也比较重要的剪枝参数:
class_weight{class_label: weight} 的形式表示与类别/标签的权重,如果取值None,则所有分类的权重为1,对于多输出问题,可以按照 y 列的顺序提供一个字典列表:dict, list of dict or “balanced”, default=None
min_weight_fraction_leaf float, default=0.0,在所有叶节点处(所有输入样本)的权重总和中的最小加权分数,如果未提供 sample_weight,则样本的权重相等

  • class_weight 有时候,有些数据的标签天生所占的比例较大,比如:航天公司想预测某一天的航班是否会发生事故,但我们知道,飞机发生事故的概率是极低的,在这种分类状况下,模型在训练的时候会更多地关注不发生事故的样本,而对发生事故的样本的捕捉度很低,即使模型什么也不做,全把结果预测成“不会发生事故”,其模型的正确率也会非常高
    因此我们需要使用 class_weight 这个参数给样本数小的标签给予更高的权重,让模型更偏向于样本数小的标签
  • 有了权重之后,训练就会受权重的影响,因此这时候剪枝,就需要搭配 min_weight_fraction_leaf 这个基于权重的剪枝参数来使用

2.4 确定最优的剪枝参数

可以通过绘制超参数曲线来确定最优的剪枝参数

例如:max_depth 循环调参,并绘制超参数曲线

# 导入相关库
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn import tree
import matplotlib.pyplot as plt

# 加载并返回葡萄酒数据集
wine = load_wine()
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3, random_state=20)

# 创建空列表,作为绘图的纵坐标
test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i+1,  		# 每次循环 max_depth + 1
                                      criterion="entropy",	# 使用信息增益率
                                      random_state=30,
                                      splitter="random",)	# 最优随机拆分策略
    clf = clf.fit(X_train, y_train)  						# 对设置的参数进行测试
    score = clf.score(X_test, y_test)
    test.append(score)  									# 将新的测试精度结果合并到 test 列表中


plt.figure()  												# 创建画布
plt.plot(range(1,11), test, color="b", label="max_depth")  	# 绘制折线图
plt.legend()  												# 显示图例
plt.show()

发现 max_depth 取值为 4、5 时 score 最高,此时模型最佳
Python机器学习(二):决策树(Decision Tree-DTs)_第8张图片

3.回归决策树

3.1 构建一棵回归决策树

clf = tree.DecisionTreeRegressor(…)

初始化回归树
几乎所有参数,属性和接口都和分类决策树树一样,需要注意的是,在回归树决策树中,没有标签分布是否均衡的问题(因为回归树是连续的),因此没有 class_weight 这样的参数

criterion 计算分枝好坏的依据:{“mse”:均方误差, “friedman_mse”:弗里德曼均方误差, “mae”:平均绝对误差}, default=”mse”
虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算”负均方误差“(neg_mean_squared_error),这是sklearn开发者为了区分而将误差归为负数,而均方误差本身也是一种损失量(Loss),因此实际上均方误差就是 neg_mean_squared_error 的负值
splitter 拆分策略选择:{“best”:最佳拆分策略, “random”:最佳随机拆分策略}, default=”best”
max_depth 树的最大深度:int, default=None,int 类型:树的最大深度,None:将所有节点展开
min_samples_split 一个节点必须要包含至少 min_samples_split 个训练样本,这个节点才允许被分枝,否则分枝就不会发生:int or float, default=2,int 类型:样本数,float 类型:占样本总数的比例,向下取整
min_samples_leaf 节点在分枝后的每个子节点必须包含至少 min_samples_leaf 个训练样本,否则不会分枝:int or float, default=1,int 类型:样本数,float 类型:占样本总数的比例,向下取整
(即该参数规定了叶子节点处所需的最小样本数)
max_features 寻找最佳划分属性时要考虑的属性数量:int, float or {“auto”, “sqrt”, “log2”}, default=None
min_impurity_decrease 如果节点分枝会导致不纯度的减少大于或等于该值,则该节点将被分裂分枝:float, default=0.0
返回值 回归决策树对象

clf.fit(X, y[, sample_weight, check_input, …])

根据训练集数据和标签 (X,y)建立决策树分类器
X 必须是二维及以上的数组
y 必须是一维数组,注:shape=(1,80) 仍然是二维数组,shape=(80, ) 才是一维数组


clf.score(X, y[, sample_weight])

使用测试集数据和标签 (X,y) 测试决策树,并返回返回预测的确定系数 R 2 R^2 R2 R 2 → 1 R^2\rightarrow1 R21 越好

clf.feature_importances_

查看各属性在决策树中的贡献度

clf.apply(X_test)

返回 X_test 中每个测试样本所在的叶子节点的索引

clf.predict(X_test)

预测 X_test 的类或回归值

例如: 一维回归图像的绘制(涉及numpy的使用、降维和升维、matplotlib绘图,不熟悉可以参考我的数据挖掘

(一)数据准备:

# 导入相关库
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt


rng = np.random.RandomState(1)  		# 设置随机数种子,返回随机数种子对象
X_train = np.sort(5 * rng.rand(80,1), axis=0) # 使用随机数种子,生成均匀分布在[0,5],shape=(80,1)的数组,并进行排序
y_train = np.sin(X_train).ravel()  					# 将X代入正弦函数,得到对应的[-1,1]的y值,并将多维数组转换为一维数组

y[::5] += 3 * (0.5 - rng.rand(16))		# 为y添加噪声
  • 这里涉及到几个比较陌生的函数
    np.random.RandomState() 用于设置随机数种子,并返回随机数种子对象 rng
    通过固定的随机数种子调用 rng.rand(),可以使每次编译都生成相同的随机数;
    np.random.rand(d1, d2, ..., dn) 用于生成随机分布在 [0,1] 的浮点形数组,其中数组的形状由 shape=(d0, d1, …, dn) 决定;
    np.sort(5 * rng.rand(80,1), axis=0) 表示用随机数种子,生成随机布在[0,5],的 80×1 的数组,并按竖直列进行排序;
    ravel() 是降维函数,可以将 n 维数组变为 n-1 维数组,这里将 shape=(80, 1) 的二维数组降至一维;
    之所以不直接生成一维的数组,是因为后续需要调用 fit() 方法来训练模型,其传入的X必须是二维及以上的数组;
  • 此时,我们得到了 80×1 的 X,和 80 个标签的 y,它们按正弦函数一一对应,X作为数据 (data),而y作为回归标签 (target),但这个数据的分布是很准确的正弦函数,因此后续我们增加了噪声;
    y[::5] += 3 * (0.5 - rng.rand(16)) 表示,y按步长 step=5 进行范围在 [-1.5, 1.5] 的随机数赋值破坏,以增加噪声;
  • 数据准备完以后,数据的效果大概是下图所示这样(该图通过 matplotlib 散点图绘制出来,不再赘述)
    Python机器学习(二):决策树(Decision Tree-DTs)_第9张图片

(二)构建回归决策树: 为了便于比较,我们构建了两棵最大深度不同的回归树

regr1 = DecisionTreeRegressor(max_depth=2)  		# 构建最大深度为2的回归树
regr2 = DecisionTreeRegressor(max_depth=5)  		# 构建最大深度为5的回归树
regr1.fit(X_train, y_train)  						# 训练回归树1
regr2.fit(X_train, y_train)  						# 训练回归树2

X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]  	# 生成[0,5),step=0.01的测试集,并升维为
y1 = regr1.predict(X_test)  						# 预测回归树1每个回归样本点得到的结果
y2 = regr2.predict(X_test)  						# 预测回归树2每个回归样本点得到的结果
  • [:, np.newaxis] 是一个升维切片,假设 array 是一个4元素数组 shape=(4, ),那么 array[:, np.newaxis] 可以把 array 转为 shape=(4, 1) 的二维数组;而 array[np.newaxis, :] 可以把 array 转为 shape=(1,4 ) 的二维数组
    升维切片[:, np.newaxis] 和 降维函数ravel() 的功能相反
    因为测试集需要二维数组,因此我们需要升维,当然也可以使用 reshape() 方法升维

(三)绘制回归预测结果:

plt.figure()

# 绘制原数据集散点图,s散点的大小,edgecolor设置散点边框颜色,c设置散点颜色
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
# 分别绘制测试集对回归树1和回归树2的测试结果
plt.plot(X_test, y1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y2, color="yellowgreen", label="max_depth=5", linewidth=2)

# 添加标题
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")

# 显示图例,显示图像
plt.legend()
plt.show()

最终结果如图:(显然,max_depth=5 的回归树出现了过拟合)
Python机器学习(二):决策树(Decision Tree-DTs)_第10张图片

3.2 交叉验证

交叉验证是用来观察模型的稳定性的一种方法,我们将数据划分为 n 份,依次使用其中一份作为测试集,剩下的 n-1 份作为训练集对模型进行训练,并计算模型的精确性来评估模型的平均准确程度

训练集和测试集的划分会干扰模型的结果,因此用交叉验证 n 次的结果求出的平均值,是评价模型的效果和泛化性的一个更好的指标
Python机器学习(二):决策树(Decision Tree-DTs)_第11张图片

# 导入相关方法
from sklearn.model_selection import cross_val_score

cross_val_score(estimator, X, y=None…)

执行交叉验证

estimator 要进行交叉验证的对象,可以是 sklearn 中的各类机器学习算法模型
X 进行验证的数据集 (data)
y 在监督学习的情况下要尝试预测的目标变量 (target),default=None,对于连续数据,其标签为数字
cv 确定交叉验证切分数,即交叉验证的次数,default=5
scoring string,如果为None,则使用估计器的默认评分器(如果可用),即指定使用 scoring=? 来评估算法模型
返回值 scores 数组,分别表示每一次验证的结果

  • 在回归决策树中,我们使用 scoring = "neg_mean_squared_error",即负的均方误差值

例如: 导入波士顿房价数据集 load_boston,建立回归决策树,并对回归树模型进行交叉验证

# 导入相关库
from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor

# 导入波士顿房价数据集
boston = load_boston()
# 建立回归决策树
regressor = DecisionTreeRegressor(random_state=0)
# 10倍交叉验证
scores = cross_val_score(regressor, boston.data, boston.target, cv=10,
				scoring="neg_mean_squared_error")
scores

在这里插入图片描述


四、案例:泰坦尼克号幸存者预测

(一)数据预处理: 包含 data.csvtest.csv,可以在 Kaggle泰坦尼克号 的 Data 中下载(不怎么容易),Github 上应该也能下载到

# 导入相关库
import numpy as 
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

# 读取data.csv文件
data = pd.read_csv("./data.csv", index_col = [])

发现数据中含有 NaN 的数据,并且姓名、船票等可能是对预测无益的数据,而 Cabin 有大量的数据缺失值,需要进行数据清洗
Python机器学习(二):决策树(Decision Tree-DTs)_第12张图片
Python机器学习(二):决策树(Decision Tree-DTs)_第13张图片

# 删除缺失值过多的列,和对预测无益数据,inplace=True决定覆盖原表
data.drop(["Cabin","Name","Ticket"], inplace=True, axis=1)

data["Age"] = data["Age"].fillna(data["Age"].mean())  	# 处理缺失值,采用平均值填补
data = data.dropna()  									# 删除含Nan的行,默认axis=0

其次,我们需要为 data["Sex"]["male", "female"]data["Embarked"]['S', "C", "Q"] 编码成 {0, 1, 2} 的形式
Python机器学习(二):决策树(Decision Tree-DTs)_第14张图片

# 将二分类变量转换为数值型变量
data["Sex"] = (data["Sex"]== "male").astype("int")  # 性别 0,1 编码,转为int类型

# 将三分类变量转换为数值型变量
labels = list(data["Embarked"].unique())  # 先将data["Embarked"]所有可能值
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
  • data["Sex"]== "male" 可以得到一个布尔数组 [True, False, …, True],然后使用 astype("int")True 变成 1,将 False 变成 0
  • labels = list(data["Embarked"].unique()) 先将 data["Embarked"] 里的所有可能值变成一个列表并获取,即 ['S', 'C', 'Q'],在列表中,它们在 labels 中的索引分别是 0,1,2
    利用的 labels 的索引,我们就可以通过 data["Embarked"].apply(lambda x: labels.index(x)) 实现编码
  • 这里暂不讨论更深入的如:one-hot 热码

当然,到这里我们所使用的数据预处理手段很粗糙,以后在 “特征工程” 里会详细介绍数据集的预处理

接着,提取数据集

# 从data中取出数据集
X = data.iloc[:,data.columns != "Survived"]
y = data.iloc[:,data.columns == "Survived"]

# 数据集分组
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

因为 train_test_split() 会随机分组,因此 X_train, X_test, Y_train, Y_test 的行索引是乱序的,因此我们需要修正行索引
Python机器学习(二):决策树(Decision Tree-DTs)_第15张图片

#修正测试集和训练集的索引
for i in [X_train, X_test, y_train, y_test]:
    i.index = range(i.shape[0])

(二)建模:

老规矩,我们利用循环来寻找最佳的 max_depth

train_scores = []
test_scores = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state=25,
                                 max_depth=i+1,
                                 criterion="entropy")
    clf = clf.fit(X_train, y_train)
    train_score = clf.score(X_train, y_train)  				# 模型在训练集上的效果
    test_score = cross_val_score(clf, X, y, cv=10).mean()  	# 模型在测试集上面的效果
    train_scores.append(train_score)  			# 合并数据
    test_scores.append(test_score)  			# 合并数据

# 画图
plt.plot(range(1,11), train_scores, color="r", label="train_scores")
plt.plot(range(1,11), test_scores, color="b", label="test_scores")
plt.xticks(range(1,11))
plt.legend()
plt.show()

发现模型效果并不理想,max_depth 大概取 3 这样子,最大深度太深了,模型就过拟合了
Python机器学习(二):决策树(Decision Tree-DTs)_第16张图片
(三)自动化调参:网格搜索: 网格搜索可以同时调整多个参数,可以实现模型的多维度优化

GS = GridSearchCV(estimator, param_grid, …)

详尽搜索估计器的指定参数值,网格搜索
通过在参数网格上进行交叉验证的网格搜索,优化用于应用这些方法的估计器的参数
同时实现 score、cross_val_score 两个功能


estimator 算法模型对象,可以是 sklearn 里的各种算法模型
param_grid 以需要调参的参数名称作为键,以参数想要尝试的值组成的列表作为值的字典,如:{"max_depth": [1, 2, 3, 4, 5]}
scoring 评分器,即评分依据
cv 执行交叉验证策略的次数

GS.fit(X, y)

必须对 GridSearchCV() 返回的 GS 对象进行训练,它的运行时间会比较长
因为是枚举,因此运行的时间会比较长,因此在 param_grid 中尽量缩小参数的可选范围;
此外,该方法还有一个缺点,就是被指定了的参数,它就一定会使用那个范围里的参数,而不会选择默认值是否最优


GS.best_score_

best_estimator 的平均交叉验证得分:float

GS.best_params_

最优结果情况下的参数选择

# 参数预值字典
parameters = {
     "splitter": ["best", "random"],  						# 最优策略,随机最优策略
			  "criterion": ["gini", "entropy"],  					# 基尼指数,信息增益
			  "max_depth": [*range(1, 8)],  						# [1,8)
			  "min_samples_leaf": [*range(1, 50, 5)],  				# 在[1,50), step=5中顺序取数
			  "min_impurity_decrease": [*np.linspace(0, 0.5, 20)]}  # 在0~0.5中,等步长地取20个数(等差数列)

clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf, parameters, cv=10)
GS.fit(X_train, y_train)
GS.best_params_
GS.best_score_

不过似乎模型的效果还是很一般,Kaggle 上这个训练集的预测难度确实比较大
Python机器学习(二):决策树(Decision Tree-DTs)_第17张图片


参考资料:
[1]机器学习-第七章:决策树.pdf,黄海广
[2]机器学习导论
[3]bilibili-2020机器学习全集,菜菜
[4]sklearn中文社区
[5]CART算法的原理以及实现

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