1 逻决策树的介绍和应用
1.1 决策树的介绍
决策树是一种常见的分类模型,在金融风控、医疗辅助诊断等诸多行业具有较为广泛的应用。决策树的核心思想是基于树结构对数据进行划分,这种思想是人类处理问题时的本能方法。例如在婚恋市场中,女方通常会先询问男方是否有房产,如果有房产再了解是否有车产,如果有车产再看是否有稳定工作……最后得出是否要深入了解的判断。
决策树的主要优点:
- 具有很好的解释性,模型可以生成可以理解的规则。
- 可以发现特征的重要程度。
- 模型的计算复杂度较低。
决策树的主要缺点:
- 模型容易过拟合,需要采用减枝技术处理。
- 不能很好利用连续型特征。
- 预测能力有限,无法达到其他强监督模型效果。
- 方差较高,数据分布的轻微改变很容易造成树结构完全不同。
1.2 决策树的应用
由于决策树模型中自变量与因变量的非线性关系以及决策树简单的计算方法,使得它成为集成学习中最为广泛使用的基模型。梯度提升树(GBDT),XGBoost以及LightGBM等先进的集成模型都采用了决策树作为基模型,在广告计算、CTR预估、金融风控等领域大放异彩,成为当今与神经网络相提并论的复杂模型,更是数据挖掘比赛中的常客。在新的研究中,南京大学周志华教授提出一种多粒度级联森林模型,创造了一种全新的基于决策树的深度集成方法,为我们提供了决策树发展的另一种可能。
同时决策树在一些明确需要可解释性或者提取分类规则的场景中被广泛应用,而其他机器学习模型在这一点很难做到。例如在医疗辅助系统中,为了方便专业人员发现错误,常常将决策树算法用于辅助病症检测。例如在一个预测哮喘患者的模型中,医生发现测试的许多高级模型的效果非常差。在他们运行了一个决策树模型后发现,算法认为剧烈咳嗽的病人患哮喘的风险很小。但医生非常清楚剧烈咳嗽一般都会被立刻检查治疗,这意味着患有剧烈咳嗽的哮喘病人都会马上得到收治。用于建模的数据认为这类病人风险很小,是因为所有这类病人都得到了及时治疗,所以极少有人在此之后患病或死亡。
2. 实验室手册
2.1 学习目标
了解 决策树 的理论知识
掌握 决策树 的 sklearn 函数调用并将其运用在企鹅数据集的预测中
2.2 代码流程
Part1 Demo实践
- Step1:库函数导入
- Step2:模型训练
- Step3:数据和模型可视化
- Step4:模型预测
Part2 基于企鹅(penguins)数据集的决策树分类实践
- Step1:库函数导入
- Step2:数据读取/载入
- Step3:数据信息简单查看
- Step4:可视化描述
- Step5:利用 决策树模型 在二分类上 进行训练和预测
- Step6:利用 决策树模型 在三分类(多分类)上 进行训练和预测
2.3 算法实战
2.3.1 Demo实践
Step1: 库函数导入
1 | ## 基础函数库 |
Step2:模型训练
1 | ##Demo演示LogisticRegression分类 |
Step3:数据和模型可视化
1 | ## 可视化构造的数据样本点 |

Step4:模型预测
1 | ## 创建新样本 |
The New point 1 predict class:
[1]
The New point 2 predict class:
[0]
2.3.2 基于企鹅数据集的决策树实战
在实践的最开始,我们首先需要导入一些基础的函数库包括:numpy (Python进行科学计算的基础软件包),pandas(pandas是一种快速,强大,灵活且易于使用的开源数据分析和处理工具),matplotlib和seaborn绘图。
1 | #下载需要用到的数据集 |
- Step1:库函数导入
1 | ## 基础函数库 |
本次我们选择企鹅数据(palmerpenguins)进行方法的尝试训练,该数据集一共包含8个变量,其中7个特征变量,1个目标分类变量。共有150个样本,目标变量为 企鹅的类别 其都属于企鹅类的三个亚属,分别是(Adélie, Chinstrap and Gentoo)。包含的三种种企鹅的七个特征,分别是所在岛屿,嘴巴长度,嘴巴深度,脚蹼长度,身体体积,性别以及年龄。
| 变量 | 描述 |
|---|---|
| species | a factor denoting penguin species |
| island | a factor denoting island in Palmer Archipelago, Antarctica |
| bill_length_mm | a number denoting bill length |
| bill_depth_mm | a number denoting bill depth |
| flipper_length_mm | an integer denoting flipper length |
| body_mass_g | an integer denoting body mass |
| sex | a factor denoting penguin sex |
| year | an integer denoting the study year |
- Step2:数据读取/载入
1 | ## 我们利用Pandas自带的read_csv函数读取并转化为DataFrame格式 |
1 | ## 为了方便我们仅选取四个简单的特征,有兴趣的同学可以研究下其他特征的含义以及使用方法 |
- Step3:数据信息简单查看
1 | ## 利用.info()查看数据的整体信息 |
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 344 entries, 0 to 343
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Species 344 non-null object
1 Culmen Length (mm) 342 non-null float64
2 Culmen Depth (mm) 342 non-null float64
3 Flipper Length (mm) 342 non-null float64
4 Body Mass (g) 342 non-null float64
dtypes: float64(4), object(1)
memory usage: 13.6+ KB
1 | ## 进行简单的数据查看,我们可以利用 .head() 头部.tail()尾部 |
| Species | Culmen Length (mm) | Culmen Depth (mm) | Flipper Length (mm) | Body Mass (g) | |
|---|---|---|---|---|---|
| 0 | Adelie Penguin (Pygoscelis adeliae) | 39.1 | 18.7 | 181.0 | 3750.0 |
| 1 | Adelie Penguin (Pygoscelis adeliae) | 39.5 | 17.4 | 186.0 | 3800.0 |
| 2 | Adelie Penguin (Pygoscelis adeliae) | 40.3 | 18.0 | 195.0 | 3250.0 |
| 3 | Adelie Penguin (Pygoscelis adeliae) | NaN | NaN | NaN | NaN |
| 4 | Adelie Penguin (Pygoscelis adeliae) | 36.7 | 19.3 | 193.0 | 3450.0 |
这里我们发现数据集中存在NaN,一般的我们认为NaN在数据集中代表了缺失值,可能是数据采集或处理时产生的一种错误。这里我们采用-1将缺失值进行填补,还有其他例如“中位数填补、平均数填补”的缺失值处理方法有兴趣的同学也可以尝试。
1 | data = data.fillna(-1) |
| Species | Culmen Length (mm) | Culmen Depth (mm) | Flipper Length (mm) | Body Mass (g) | |
|---|---|---|---|---|---|
| 339 | Chinstrap penguin (Pygoscelis antarctica) | 55.8 | 19.8 | 207.0 | 4000.0 |
| 340 | Chinstrap penguin (Pygoscelis antarctica) | 43.5 | 18.1 | 202.0 | 3400.0 |
| 341 | Chinstrap penguin (Pygoscelis antarctica) | 49.6 | 18.2 | 193.0 | 3775.0 |
| 342 | Chinstrap penguin (Pygoscelis antarctica) | 50.8 | 19.0 | 210.0 | 4100.0 |
| 343 | Chinstrap penguin (Pygoscelis antarctica) | 50.2 | 18.7 | 198.0 | 3775.0 |
1 | ## 其对应的类别标签为'Adelie Penguin', 'Gentoo penguin', |
array(['Adelie Penguin (Pygoscelis adeliae)',
'Gentoo penguin (Pygoscelis papua)',
'Chinstrap penguin (Pygoscelis antarctica)'], dtype=object)
1 | ## 利用value_counts函数查看每个类别数量 |
Adelie Penguin (Pygoscelis adeliae) 152
Gentoo penguin (Pygoscelis papua) 124
Chinstrap penguin (Pygoscelis antarctica) 68
Name: Species, dtype: int64
1 | ## 对于特征进行一些统计描述 |
| Culmen Length (mm) | Culmen Depth (mm) | Flipper Length (mm) | Body Mass (g) | |
|---|---|---|---|---|
| count | 344.000000 | 344.000000 | 344.000000 | 344.000000 |
| mean | 43.660756 | 17.045640 | 199.741279 | 4177.319767 |
| std | 6.428957 | 2.405614 | 20.806759 | 861.263227 |
| min | -1.000000 | -1.000000 | -1.000000 | -1.000000 |
| 25% | 39.200000 | 15.500000 | 190.000000 | 3550.000000 |
| 50% | 44.250000 | 17.300000 | 197.000000 | 4025.000000 |
| 75% | 48.500000 | 18.700000 | 213.000000 | 4750.000000 |
| max | 59.600000 | 21.500000 | 231.000000 | 6300.000000 |
- Step4:可视化描述
1 | ## 特征与标签组合的散点可视化 |

从上图可以发现,在2D情况下不同的特征组合对于不同类别的企鹅的散点分布,以及大概的区分能力。Culmen Lenth与其他特征的组合散点的重合较少,所以对于数据集的划分能力最好。
我们发现
1 | '''为了方便我们将标签转化为数字 |
1 | for col in data.columns: |




利用箱型图我们也可以得到不同类别在不同特征上的分布差异情况。
1 | # 选取其前三个特征绘制三维散点图 |

- Step5:利用 决策树模型 在二分类上 进行训练和预测
1 | ## 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型, |
1 | ## 从sklearn中导入决策树模型 |
DecisionTreeClassifier(criterion='entropy')
1 | ## 在训练集和测试集上分布利用训练好的模型进行预测 |
The accuracy of the Logistic Regression is: 0.9954545454545455
The accuracy of the Logistic Regression is: 1.0
The confusion matrix result:
[[31 0]
[ 0 25]]

我们可以发现其准确度为1,代表所有的样本都预测正确了。
- Step6:利用 决策树模型 在三分类(多分类)上 进行训练和预测
1 | ## 测试集大小为20%, 80%/20%分 |
DecisionTreeClassifier()
1 | ## 在训练集和测试集上分布利用训练好的模型进行预测 |
The test predict Probability of each class:
[[0. 0. 1.]
[0. 1. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[0. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[0. 1. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[1. 0. 0.]
[0. 0. 1.]
[1. 0. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[0. 0. 1.]
[0. 1. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[0. 0. 1.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[0. 0. 1.]
[0. 0. 1.]
[0. 1. 0.]
[1. 0. 0.]
[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[0. 0. 1.]
[0. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]
[1. 0. 0.]
[1. 0. 0.]]
The accuracy of the Logistic Regression is: 0.9963636363636363
The accuracy of the Logistic Regression is: 0.9710144927536232
1 | ## 查看混淆矩阵 |
The confusion matrix result:
[[31 1 0]
[ 0 23 0]
[ 1 0 13]]

2.4 重要知识点
2.4.3 重要参数
2.4.3.1 criterion
Criterion这个参数正是用来决定模型特征选择的计算方法的。sklearn提供了两种选择:
输入”entropy“,使用信息熵(Entropy)
输入”gini“,使用基尼系数(Gini Impurity)
2.4.3.2 random_state & splitter
random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显。splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。
2.4.3.3 max_depth
限制树的最大深度,超过设定深度的树枝全部剪掉。这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合。
2.4.3.4 min_samples_leaf
min_samples_leaf 限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生。一般搭配max_depth使用,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太小会引起过拟合,设置得太大就会阻止模型学习数据。