第四章 决策树
4.1 基本流程
基本概念
决策树是基于树结构来进行决策的
决策树的目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树,其基本流程遵循简单且直观的“分而治之”(divide-and-conquer)策略
西瓜例子
构建流程
- 决策过程的最终结论对应了我们所希望的判定结果
- 决策过程中提出的每个判定问题都是对某个属性的“测试”
- 每个测试的结果或是导出最终结论,或是导出进一步的判定问题,其考虑范围是上次决策结果的下定范围之内
树的组成
- 一个根结点
- 若干个内部结点
- 若干个叶结点
叶子节点对应于决策结果,其他每个节点则对应于一个属性测试
每个结点包含的样本集合根据属性测试的结果被划分到子结点中,而根结点包含了样本全集 从根结点到每个叶结点的路径对应了一个判定测试序列
算法示例
决策树的生成是一个递归过程
三种会导致递归返回的情形
-
当前结点包含的样本全属于同一类别,无需划分
-
当前属性集为空,或是所有样本在所有属性上取值相同,无法划分
- 把当前结点标记为叶结点,并将其类别设定为该结点所含样本最多的类别
- 利用当前结点的后验分布
-
当前结点包含的样本集合为空,不能划分
- 把当前结点标记为叶结点,但将其类别设定为父结点所含样本做多的类别
- 把父结点的样本分布作为当前结点的先验分布
决策树各类算法的核心就就在于:如何解决“从A中选择最优划分属性”?
4.2 划分选择
核心问题:如何解决“从A中选择最优划分属性”?
划分目的:决策树分支结点所包含的样本尽可能属于同一类别,即结点的“纯度”(purity)越来越高
信息熵(information entropy)
在决策树种,信息熵通常是用来度量样本集合纯度最常用的一种指标
Ent ( D ) = − ∑ k = 1 ∣ Y ∣ p k log 2 p k \text{Ent}(D)=-\sum_{k=1}^{|\mathcal{Y}|}p_k\log_2p_k Ent(D)=−∑k=1∣Y∣pklog2pk
- Ent ( D ) \text{Ent}(D) Ent(D) 的值越小,则 D D D 的纯度越高
- Ent ( D ) \text{Ent}(D) Ent(D) 的最小值为0,最大值为 log 2 ∣ Y ∣ \log_2|\mathcal{Y}| log2∣Y∣
PS: 更加具体的内容参见前一个上一篇博文(决策树 铺垫)中的内容
西瓜例子
接下来就是围绕这个数据集进行展开
常见方法
参数设置
- 假定离散属性 a a a 有 V V V 个可能的取值 { a 1 , a 2 , . . . , a V } \{a^1,a^2,...,a^V\} {a1,a2,...,aV}
- 其中第 v v v 个分支结点包含了 D D D 中所有在属性 a a a 上取值为 a v a^v av 的样本,记为 D v D^v Dv
- 根据信息熵公式计算出 D v D^v Dv 的信息熵
- 再根据不同的分支结点所包含的样本数不同,给分支结点赋予不同的权重 ∣ D v ∣ ∣ D ∣ \frac{|D^v|}{|D|} ∣D∣∣Dv∣
信息增益(information gain)
关键公式:
Gain ( D , a ) = Ent ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ Ent ( D v ) \text{Gain}(D,a)=\text{Ent}(D)-\sum_{v=1}^V\frac{|D^v|}{|D|}\text{Ent}(D^v) Gain(D,a)=Ent(D)−∑v=1V∣D∣∣Dv∣Ent(Dv)
- 信息增益越大,则意味着使用属性a来进行划分所获得的“纯度提升”越大
- 经典的ID3决策树算法就是以信息增益来为准则进行属性选择的
西瓜例子:
计算过程:
根结点的信息熵为:
Ent ( D ) = − ∑ k = 1 2 p k log 2 p k = − ( 8 17 log 2 8 17 + 9 17 log 2 9 17 ) = 0.998 \text{Ent}(D)=-\sum_{k=1}^2p_k\log_2p_k=-(\frac{8}{17}\log_2\frac{8}{17}+\frac{9}{17}\log_2\frac{9}{17})=0.998 Ent(D)=−∑k=12pklog2pk=−(178log2178+179log2179)=0.998
例如以“色泽”作为划分依据,则可以建立三个分支其对应的信息熵为
Ent
(
D
1
)
=
−
(
3
6
log
2
3
6
+
3
6
log
2
3
6
)
=
1.000
\text{Ent}(D^1)=-(\frac{3}{6}\log_2\frac{3}{6}+\frac{3}{6}\log_2\frac{3}{6})=1.000
Ent(D1)=−(63log263+63log263)=1.000
Ent
(
D
2
)
=
−
(
4
6
log
2
4
6
+
2
6
log
2
2
6
)
=
0.918
\text{Ent}(D^2)=-(\frac{4}{6}\log_2\frac{4}{6}+\frac{2}{6}\log_2\frac{2}{6})=0.918
Ent(D2)=−(64log264+62log262)=0.918
Ent
(
D
3
)
=
−
(
1
5
log
2
1
5
+
4
5
log
2
4
5
)
=
0.722
\text{Ent}(D^3)=-(\frac{1}{5}\log_2\frac{1}{5}+\frac{4}{5}\log_2\frac{4}{5})=0.722
Ent(D3)=−(51log251+54log254)=0.722
则“色泽”对应的信息增益为
Gain ( D , 色 泽 ) = Ent ( D ) − ∑ v = 1 3 ∣ D v ∣ ∣ D ∣ Ent ( D v ) = 0.998 − ( 6 17 × 1.000 + 6 17 × 0.918 + 5 17 × 0.722 ) = 0.109 \begin{aligned}\text{Gain}(D,色泽)&=\text{Ent}(D) - \sum_{v=1}^3\frac{|D^v|}{|D|}\text{Ent}(D^v)\\\\&= 0.998 - (\frac{6}{17} \times {1.000} + \frac{6}{17} \times {0.918} + \frac{5}{17} \times {0.722}) \\\\&= 0.109 \end{aligned} Gain(D,色泽)=Ent(D)−v=1∑3∣D∣∣Dv∣Ent(Dv)=0.998−(176×1.000+176×0.918+175×0.722)=0.109
其他属性对应的信息增益
Gain ( D , 根 蒂 ) = 0.143 \text{Gain}(D,根蒂) = 0.143 Gain(D,根蒂)=0.143
Gain ( D , 敲 声 ) = 0.141 \text{Gain}(D,敲声) = 0.141 Gain(D,敲声)=0.141
Gain ( D , 纹 理 ) = 0.381 \text{Gain}(D,纹理) = 0.381 Gain(D,纹理)=0.381
Gain ( D , 脐 部 ) = 0.289 \text{Gain}(D,脐部) = 0.289 Gain(D,脐部)=0.289
Gain ( D , 触 感 ) = 0.006 \text{Gain}(D,触感) = 0.006 Gain(D,触感)=0.006
ID*3 算法就是使用的信息增益算法
算法特点:
信息增益准则对可取值数目较多的属性有所偏好,因此其在选择分类属性的时候倾向混乱程度更大的属性
增益率(gain ratio)
关键公式:
Gain_ratio ( D , a ) = Gain ( D , a ) IV ( a ) IV ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ log 2 ∣ D v ∣ ∣ D ∣ \begin{aligned}&\text{Gain\_ratio}(D,a)=\frac{\text{Gain}(D,a)}{\text{IV}(a)}\\\\&\text{IV}(a)=-\sum_{v=1}^V\frac{|D^v|}{|D|}\log_2\frac{|D^v|}{|D|}\end{aligned} Gain_ratio(D,a)=IV(a)Gain(D,a)IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
Gain ( D , 色 泽 ) = Ent ( D ) − ∑ v = 1 3 ∣ D v ∣ ∣ D ∣ Ent ( D v ) = 0.998 − ( 6 17 × 1.000 + 6 17 × 0.918 + 5 17 × 0.722 ) = 0.109 \begin{aligned}\text{Gain}(D,色泽)&=\text{Ent}(D) - \sum_{v=1}^3\frac{|D^v|}{|D|}\text{Ent}(D^v)\\\\&= 0.998 - (\frac{6}{17} \times {1.000} + \frac{6}{17} \times {0.918} + \frac{5}{17} \times {0.722}) \\\\&= 0.109 \end{aligned} Gain(D,色泽)=Ent(D)−v=1∑3∣D∣∣Dv∣Ent(Dv)=0.998−(176×1.000+176×0.918+175×0.722)=0.109
其中 IV ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ log 2 ∣ D v ∣ ∣ D ∣ \text{IV}(a)=-\sum_{v=1}^V\frac{|D^v|}{|D|}\log_2\frac{|D^v|}{|D|} IV(a)=−∑v=1V∣D∣∣Dv∣log2∣D∣∣Dv∣ 称为属性 a a a 的固有值(intrinsic value)
属性a的可能取值数目越多(即V越大),则IV(a)得值通常会越大 著名的C4.5决策算法则是使用“增益率”来选择最优划分属性
西瓜例子:
略
算法特点
增益率准则对可取数值数目较少的属性有所偏好,因此其在选择分类属性的时候倾向混乱程度更小的属性
基尼指数(Gini index)
关键公式:
Gini_index ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ Gini(D v ˆ ) Gini ( D ) = ∑ k = 1 ∣ Y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ Y ∣ p k 2 \begin{aligned}\text{Gini\_index}(D,a) & = \sum_{v=1}^V\frac{|D^v|}{|D|}\text{Gini(D\^v)} \\\\ \text{Gini}(D) & = \sum_{k=1}^{|\mathcal{Y}|}\sum_{k'\neq k}p_kp_{k'} \\\\ & = 1 - \sum_{k=1}^{|\mathcal{Y}|}p_{k}^2 \end{aligned} Gini_index(D,a)Gini(D)=v=1∑V∣D∣∣Dv∣Gini(Dvˆ)=k=1∑∣Y∣k′=k∑pkpk′=1−k=1∑∣Y∣pk2
直观来说基尼指数反省了从数据集D中随机抽取两个样本,期类别标记不一致的概率
基尼指数越小,数据集D的纯度越高
在候选属性集合A中,选择那个使得划分后基尼指数最小的属性作为最优划分属性,即
a ∗ = arg min a ∈ A Gini_index ( D , a ) a_* = \underset{a \in A}{\arg\min} \text{Gini\_index}(D,a) a∗=a∈AargminGini_index(D,a)
CART决策树使用基尼指数来选择划分属性
算法特点
基尼系数是一种衡量信息不确定性的方法,与信息熵计算出来的结果差距很小,基本可以忽略,但是基尼系数要计算快得多,因为没有对数
在特征选取中,会优先选择基尼指数最小的属性作为优先划分属性
4.3 剪枝处理
在决策树算法中对付“过拟合”的主要手段
如何理解决策树过拟合?
决策树分支结点过多,把训练集本生学得太好了,以致于把训练集自身的一些特点当作是所有数据集都具有的一般性质而导致过拟合
基本策略
预剪枝(prepruning)
预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点
后减枝(postpruning)
后剪枝则是先从训练集生成一颗完整的决策树,然后自底向上地对非叶子结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点
西瓜例子
数据集
生成树
预剪枝
假设以 “脐部” 属性来对训练集进行划分
不进行划分与使用脐部进行划分验证集精度前后变化
特点
- 预剪枝使得决策树的分支都没有展开,这不仅降低了过拟合的风险,还显著减少了决策树的训练时间开销和测试时间开销
- 有些分支的当前划分虽然不能提升泛化性能、甚至可能导致泛化性能暂时下降,但在其基础上进行的后续划分却有可能导致性能的显著提高
PS: 使用的是贪心算法,因此会有欠拟合的风险
后减枝
假设以 “脐部” 属性来对训练集进行划分
自下而上观察子树替换为叶结点后的验证集精度
特点
- 一般情况下,后剪枝决策树的欠拟合风险很小,繁华性能往往优于预剪枝决策树
- 后剪枝过程是在生成完全决策树之后进行的,并且要自底向上地对树中的所有非叶结点进行逐一考察,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多
PS:后剪枝决策树通常比预剪枝决策树保留了更多的分支
4.4 连续与缺失值
连续值处理
二分法(bi-partition)
概念
- 给定样本集 D D D 合连续属性 a a a,假定 a a a 在 D D D 上出现了 n n n 个不同的取值,将这些值从小到大进行排序,记为 { a 1 , a 2 , . . . , a n } \{a^1,a^2,...,a^n\} {a1,a2,...,an}
- 基于划分点 t t t 可将 D D D 分为子集 D t − D_{t^-} Dt− 和 D t + D_{t^+} Dt+ ,其中 D t − D_{t^-} Dt− 中包含那些在属性 a a a 上取值不大于 t t t 的样本,而 D t + D_{t^+} Dt+ 则包含那些在属性 a a a 上取值大于 t t t 的样本
步骤
- 对相邻的属性取值 a i a^i ai 和 a i + 1 a^{i+1} ai+1 来说, t t t 在区间 [ a i , a i + 1 ) [a^i,a^{i+1}) [ai,ai+1) 中取任意值所产生的划分结果相同
属性在实际情况中取值是连续的,但是样本集中也是呈现离散的装态,这里的取值不影响划分是指样本集中的离散状态
- 对连续属性 a a a,可考察包含 n − 1 n-1 n−1 个元素的候选划分点集合
$T_a={\frac{ai+a{i+1}}{2}|1 \le i \le n-1} \$
即将每个区间的中位点作为候选划分点
- 通过离散属性值一样里考察这些划分点,选择最优划分点进行样本集合的划分
Gain ( D , a ) = max t ∈ T a Gain ( D , a , t ) = max t ∈ T a Ent ( D ) − ∑ λ ∈ { − , + } ∣ D t λ ∣ ∣ D ∣ Ent ( D t λ ) \begin{aligned} \text {Gain} (D,a) &= \underset{t\in T_a}{\max } \text {Gain} (D,a,t) \\\\ &= \underset{t\in T_a}{\max} \text{Ent}(D) - \sum_{\lambda \in \{ -,+ \}} \frac{|D_t^{\lambda}|}{|D|}\text{Ent}(D_t^{\lambda}) \end{aligned} Gain(D,a)=t∈TamaxGain(D,a,t)=t∈TamaxEnt(D)−λ∈{−,+}∑∣D∣∣Dtλ∣Ent(Dtλ)
与离散属性不同,若当前结点划分属性为连续属性,该属性还可作为其后代结点的划分属性
缺失值处理
问题描述
现实任务中常会遇到不完整的样本,即样本的某些属性值缺失
(1)如何在属性值缺失的情况下进行划分属性选择?
(2)给定划分属性,若样本在该属性上的值缺失,如何对样本进行划分?
权重法
符号定义
- 令 D ~ \tilde{D} D~ 表示 D D D 在属性 a a a 上没有缺失值得样本子集
- 令 D v ~ \tilde{D^v} Dv~ 表示 D ~ \tilde{D} D~ 中在属性 a a a 上取值为 a v a^v av 的样本子集
- 令 D k ~ \tilde{D_k} Dk~ 表示 D ~ \tilde{D} D~ 中属于第 k k k 类的样本子集
为每个样本 x \boldsymbol{x} x 赋予一个权重 w x w_{\boldsymbol{x}} wx
- 无缺失值的比例
ρ = ∑ x ∈ D ~ w x ∑ x ∈ D w x \rho=\frac{\sum_{\boldsymbol{x} \in \tilde{D}}w_{\boldsymbol{x}}}{\sum_{\boldsymbol{x} \in D}w_{\boldsymbol{x}}} ρ=∑x∈Dwx∑x∈D~wx
- 无缺失样本中第 k k k 类所占的比例
p k ~ = ∑ x ∈ D k ~ w x ∑ x ∈ D w x , ( 1 ≤ k ≤ ∣ Y ∣ ) \tilde{p_k}=\frac{\sum_{\boldsymbol{x} \in \tilde{D_k}}w_{\boldsymbol{x}}}{\sum_{\boldsymbol{x} \in D}w_{\boldsymbol{x}}}, (1 \le k \le |\mathcal{Y}|) pk~=∑x∈Dwx∑x∈Dk~wx,(1≤k≤∣Y∣)
- 无缺失样本中属性 a a a 上取值的样本所占的比例
r v ~ = ∑ x ∈ D v ~ w x ∑ x ∈ D w x , ( 1 ≤ v ≤ V ) \tilde{r_v}=\frac{\sum_{\boldsymbol{x} \in \tilde{D^v}}w_{\boldsymbol{x}}}{\sum_{\boldsymbol{x} \in D}w_{\boldsymbol{x}}}, (1 \le v \le V) rv~=∑x∈Dwx∑x∈Dv~wx,(1≤v≤V)
公式
- 解决问题(1)
Gain ( D , a ) = ρ × Gain ( D ~ , a ) = ρ × ( Ent ( D ~ − ∑ v = 1 V r v ~ Ent ( D v ~ ) ) ) \begin{aligned} \text{Gain}(D,a) & = \rho \times \text{Gain}(\tilde{D}, a) \\\\ & = \rho \times \left ( \text{Ent}(\tilde{D} - \sum_{v=1}^V\tilde{r_v} \text{Ent}(\tilde{D^v})) \right ) \end{aligned} Gain(D,a)=ρ×Gain(D~,a)=ρ×(Ent(D~−v=1∑Vrv~Ent(Dv~)))
- 让同一个样本以不同的概率划分到不同的子结点中去:解决的问题(2)
若样本 x \boldsymbol{x} x 在划分属性 a a a 上的取值未知,则将 x \boldsymbol{x} x 同时划入所有子结点,且样本权值在于属性值 a v a^v av 对应的子结点中调整为 r v ~ ⋅ w x \tilde{r_v}·w_{\boldsymbol{x}} rv~⋅wx
4.5 多变量决策树
单变量决策树(univariate decision tree)
特点:轴平行(axis-parallel):即它的分类边界由若干个与坐标轴平行的分段组成
多变量决策树(multivariate decision tree)
特点:非叶结点不再是仅对某个属性进行测试,而是对属性的线性组合进行测试
每一个非叶结点是一个形如 ∑ i = 1 d w i a i = t \sum_{i=1}^dw_ia_i=t ∑i=1dwiai=t 的线性分类器,其中 w i w_i wi 是属性 a i a_i ai 的权重
编码实现——基于信息增益准则的决策树
采用Python作为实现工具,以书籍中的西瓜数据为例,构造一棵“watermelon tree”。这里,我们构建的是一棵基于信息增益准则的决策树,比较简单,适合初学。
1. 算法
2. Python代码实现
代码框架参考了部分网络资源,然后就是闷头去写了。本质上都是大同小异,重要的还是抱着学习的心态,去自主实现一下,才能对决策树有更多的思考。
2.1 数据样本说明
本案例基于教材《机器学习》P76表4.1 西瓜数据集2.0,尝试用Python实现决策树构建。一共17条样本数据。理论上,建立的树应该和P78图4.4一致。
样本数据截图如下:
2.2 实现代码
(一)导入模块部分
#导入模块
import pandas as pd
import numpy as np
from collections import Counter
from math import log2
用pandas模块的read_excel()函数读取数据文本;用numpy模块将dataframe转换为list(列表);用Counter来完成计数;用math模块的log2函数计算对数。后边代码中会有对应体现。
(二)数据获取与处理函数
#数据获取与处理
def getData(filePath):
data = pd.read_excel(filePath)
return data
def dataDeal(data):
dataList = np.array(data).tolist()
dataSet = [element[1:] for element in dataList]
return dataSet
getData()通过pandas模块中的read_excel()函数读取样本数据。尝试过将数据文件保存为csv格式,但是对于中文的处理不是很好,所以选择了使用xls格式文件。
dataDeal()函数将dataframe转换为list,并且去掉了编号列。编号列并不是西瓜的属性,事实上,如果把它当做属性,会获得最大的信息增益。
这两个函数是完全可以合并为同一个函数的,但是因为我想分别使用data(dataframe结构,带属性标签)和dataSet(list)数据样本,所以分开写了两个函数。
(三)获取属性名称
#获取属性名称
def getLabels(data):
labels = list(data.columns)[1:-1]
return labels
很简单,获取属性名称:纹理,色泽,根蒂,敲声,脐部,触感。
(四)获取类别标记
#获取类别标记
def targetClass(dataSet):
classification = set([element[-1] for element in dataSet])
return classification
获取一个样本是否好瓜的标记(是与否)。
(五)叶结点标记
#将分支结点标记为叶结点,选择样本数最多的类作为类标记
def majorityRule(dataSet):
mostKind = Counter([element[-1] for element in dataSet]).most_common(1)
majorityKind = mostKind[0][0]
return majorityKind
(六)计算信息熵
#计算信息熵
def infoEntropy(dataSet):
classColumnCnt = Counter([element[-1] for element in dataSet])
Ent = 0
for symbol in classColumnCnt:
p_k = classColumnCnt[symbol]/len(dataSet)
Ent = Ent-p_k*log2(p_k)
return Ent
(七)子数据集构建
#子数据集构建
def makeAttributeData(dataSet,value,iColumn):
attributeData = []
for element in dataSet:
if element[iColumn]==value:
row = element[:iColumn]
row.extend(element[iColumn+1:])
attributeData.append(row)
return attributeData
在某一个属性值下的数据,比如纹理为清晰的数据集。
(八)计算信息增益
#计算信息增益
def infoGain(dataSet,iColumn):
Ent = infoEntropy(dataSet)
tempGain = 0.0
attribute = set([element[iColumn] for element in dataSet])
for value in attribute:
attributeData = makeAttributeData(dataSet,value,iColumn)
tempGain = tempGain+len(attributeData)/len(dataSet)*infoEntropy(attributeData)
Gain = Ent-tempGain
return Gain
(九)选择最优属性
#选择最优属性
def selectOptimalAttribute(dataSet,labels):
bestGain = 0
sequence = 0
for iColumn in range(0,len(labels)):#不计最后的类别列
Gain = infoGain(dataSet,iColumn)
if Gain>bestGain:
bestGain = Gain
sequence = iColumn
print(labels[iColumn],Gain)
return sequence
(十)建立决策树
#建立决策树
def createTree(dataSet,labels):
classification = targetClass(dataSet) #获取类别种类(集合去重)
if len(classification) == 1:
return list(classification)[0]
if len(labels) == 1:
return majorityRule(dataSet)#返回样本种类较多的类别
sequence = selectOptimalAttribute(dataSet,labels)
print(labels)
optimalAttribute = labels[sequence]
del(labels[sequence])
myTree = {optimalAttribute:{}}
attribute = set([element[sequence] for element in dataSet])
for value in attribute:
print(myTree)
print(value)
subLabels = labels[:]
myTree[optimalAttribute][value] = \
createTree(makeAttributeData(dataSet,value,sequence),subLabels)
return myTree
树本身并不复杂,采用递归的方式实现。
(十一)定义主函数
def main():
filePath = 'watermelonData.xls'
data = getData(filePath)
dataSet = dataDeal(data)
labels = getLabels(data)
myTree = createTree(dataSet,labels)
return myTree
主函数随便写写了,主要是实现功能。
(十二)生成树
要想运行还需要引入库:
import pandas as pd
import numpy as np
from numpy import *
from collections import Counter
if __name__ == '__main__':
myTree = main()
3.几点说明
Python实现并没有很复杂的东西,只要能很好的理解递归在这里是如何体现的就足够了。
在构造树的时候,这里的树定义为一个嵌套的字典(dict)结构,树根对应的属性是字典最外层的关键字,其值是仍一个字典。递归就是这样用下一层返回的树作为上一层树某个分支(字典的关键字)的值,一层层往下(一棵倒树)填充,直至遇到叶结点。在定义的构造树函数中,终止条件(两个if)是很重要的,决定了递归在什么时候停止,也就是树在什么时候停止生长。
生成的树(字典结构)如下:
一个字典结构的树是极其不友好的,暂时没有将其可视化,后续会学习一下。
从结果看,根节点的属性是纹理。纹理为稍糊的,下一个结点的属性是触感,触感为软粘的瓜,判断为好瓜(纹理为稍糊且触感为软粘的瓜),触感为硬滑的瓜,判定为坏瓜(纹理为稍糊且触感为硬滑的瓜)。纹理为模糊的,直接判定为坏瓜(买瓜的要注意了);纹理为清晰的情形较为复杂。纹理为清晰的,下一个结点属性为根蒂,对于根蒂为硬挺的,判断为坏瓜(纹理为清晰且根蒂为硬挺的瓜),根蒂为蜷缩的,判断为好瓜(纹理为清晰且根蒂为蜷缩的瓜)。根蒂为稍蜷的,下一个结点的属性是色泽,对于色泽为青绿的,判断为好瓜(纹理为清晰,根蒂为稍蜷且色泽为青绿的瓜),对于色泽为乌黑的,下一个结点属性是触感,对于触感为软粘的,判定为坏瓜(纹理为清晰,根蒂为稍蜷,色泽为乌黑且触感为软粘的瓜),对于触感为硬滑的,判定为好瓜(纹理为清晰,根蒂为稍蜷,色泽为乌黑且触感为硬滑的瓜)。这里有一个小的问题,一会儿再说。
先看《机器学习》教材上给出的树:
我们获得的结果和书本中的结果基本是一致的,唯一的一个区别是我们缺少一个叶——色泽为浅白的叶。这是因为,样本数据中不存在纹理为清晰、根蒂为稍蜷且色泽为浅白的瓜,导致在生成树的时候少了一个叶。这种情况需要特殊处理,比如处理成父类的类别。这里没有多做处理,该机制添加进去并不难。
性是触感,触感为软粘的瓜,判断为好瓜(纹理为稍糊且触感为软粘的瓜),触感为硬滑的瓜,判定为坏瓜(纹理为稍糊且触感为硬滑的瓜)。纹理为模糊的,直接判定为坏瓜(买瓜的要注意了);纹理为清晰的情形较为复杂。纹理为清晰的,下一个结点属性为根蒂,对于根蒂为硬挺的,判断为坏瓜(纹理为清晰且根蒂为硬挺的瓜),根蒂为蜷缩的,判断为好瓜(纹理为清晰且根蒂为蜷缩的瓜)。根蒂为稍蜷的,下一个结点的属性是色泽,对于色泽为青绿的,判断为好瓜(纹理为清晰,根蒂为稍蜷且色泽为青绿的瓜),对于色泽为乌黑的,下一个结点属性是触感,对于触感为软粘的,判定为坏瓜(纹理为清晰,根蒂为稍蜷,色泽为乌黑且触感为软粘的瓜),对于触感为硬滑的,判定为好瓜(纹理为清晰,根蒂为稍蜷,色泽为乌黑且触感为硬滑的瓜)。这里有一个小的问题,一会儿再说。
先看《机器学习》教材上给出的树:
我们获得的结果和书本中的结果基本是一致的,唯一的一个区别是我们缺少一个叶——色泽为浅白的叶。这是因为,样本数据中不存在纹理为清晰、根蒂为稍蜷且色泽为浅白的瓜,导致在生成树的时候少了一个叶。这种情况需要特殊处理,比如处理成父类的类别。这里没有多做处理,该机制添加进去并不难。