【机器学习与实战】分类与聚类算法:决策树
一、什么是决策树
决策树是一种通过训练样本的特征值来构造一个树形结构的判定规则的监督学习算法。
在这个树中,内部节点代表基于特征的判定条件,叶节点代表决策的结果。当对未知样本进行预测时,我们根据该样本的特征值从树的根部节点开始判定,直到达到叶节点,该叶节点的值即为预测值。(对于分类问题,这是类标签;对于回归问题,这是一个连续值)
下面通过一个例子来帮助我们理解什么是决策树,假设你正在决定今天晚上是否应该去锻炼,你可能会像下面这样考虑:
- 天气:如果天气好,你可能更愿意出门去健身房锻炼;但如果天气不好(比如正在下雨),你可能会选择在家锻炼或者不锻炼;
- 工作压力:如果你今天工作压力较大,可能已经很疲惫,就可能会选择放松一下,而不去锻炼;如果工作压力正常,你可能会觉得去健身房锻炼是一个不错的选择。
- 健康状况:如果你感到身体疲劳或者不舒服,你可能会选择休息,而不是去锻炼。
上图,就是把基于以上因素的决策过程表示为了一个决策树:
- 第一层(根节点)是”天气”:如果天气好,则进入下一层左边分支;如果天气不好,也进入下一层右边分支;
- 第二层是”工作压力”:如果工作压力较大,可能就选择”休息”;如果工作压力正常,那么进入下一层右边分支继续决策;
- 第三层是”健康状况”:如果感觉身体不适,可能就选择”休息”;如果身体状态良好,天气好的情况下,那么就”去健身房锻炼”,天气不好的情况下,那么就”在家锻炼”。
决策树本质是一颗由多个判断节点组成的树形结构:
- 每个内部节点表示一个属性上的判断
- 每个分支代表一种判断结果
- 每个叶子节点代表最终的一种分类结果
二、如何构建决策树
决策树既可用于分类任务,也可用于回归任务。决策树本质就是利用 if-else 这类逻辑分支结构对样本空间进行分割,对于分类任务,未知样本的类别就是分割后同一个空间中占比最多的已知样本的类别;对于回归任务,未知样本的值就是分割后同一个空间中已知样本的值的平均数。
比如,下表是一个根据是否有房、婚姻状况、年收入这3个特征,判断用户是否会拖欠贷款的分类任务。
| 序号 | 是否有房 | 婚姻状况 | 年收入 | 是否拖欠贷款 |
|---|---|---|---|---|
| 1 | yes | single | 125k | no |
| 2 | no | married | 100k | no |
| 3 | no | single | 70k | no |
| 4 | yes | married | 120k | no |
| 5 | no | divorced | 95k | yes |
| 6 | no | married | 60k | no |
| 7 | yes | divorced | 220k | no |
| 8 | no | single | 85k | yes |
| 9 | no | married | 75k | no |
| 10 | no | Single | 90k | Yes |
| 11 | yes | Single | 50k | ? |
根据上表数据,我们可以构建得到如下的决策树
决策树就是利用 if-else 这类逻辑分支结构对样本空间进行分割
决策树的构建过程涉及信息熵和信息增益等概念,见教材算法详情
三、在SKLearn中使用决策树
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
heart = pd.read_csv('../regress/heart.csv')
x = heart.iloc[:, 0:13]
y = heart['target']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
scaler = MinMaxScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)
dt = DecisionTreeClassifier(max_depth=10)
dt.fit(x_train, y_train)
print(dt.score(x_test, y_test))