#《机器学习》_周志华(西瓜书)&南瓜书_第4章 决策树

待完成:

  • 参考所有笔记,整理习题
  • 有疑问的地方

在这里插入图片描述
步骤

1、先看习题部分有什么问题,带着问题
2、整体过一遍,记录
3、各平台关于该 知识点 的教程
3、做习题,再次整理,补充。

问题:

1、各种决策树划分选择准则的特点、优缺点
2、数据集含冲突数据怎么办?
3、未剪枝、预剪枝、后剪枝决策树有什么区别和联系?
4、统计显著性检验是什么?


第4章 决策树

在这里插入图片描述
关键: 第8行 选择最优划分属性。

决策树的生成, 递归过程。

递归返回的三种情形:
1、当前结点包含的样本全属于同一类别,无需划分
2、当前属性集为空,或是所有样本在所有属性上取值相同,无法划分。

  • 当前结点标记为叶结点,类别设定为 该结点所含样本最多的类别。
  • 利用当前结点的后验分布。

3、当前结点包含的样本集合为空,不能划分。

  • 当前结点标记为叶结点,类别设定为 其父结点所含样本最多的 类别。(因为当前结点的样本集合是空的。。。所以只能看父结点的情况)
  • 把父结点的样本分布作为当前结点的先验分布。

?上述三种情况的具体情形

4.2 划分选择

如何选择最优划分属性
目标:

  • 决策树的分支结点所包含的样本尽可能属于同一类别。
  • 即结点的“纯度”越来越高。

4.2.1 信息增益

信息熵(information entropy ): 度量 样本集合 纯度 最常用的 指标

样 本 集 合 D 中 第 k 类 样 本 所 占 的 比 例 为 p k ( k = 1 , 2 , 3 , . . ∣ Y ∣ ) 样本集合D中第k类样本所占的比例为p_k(k=1,2,3,..|\mathcal{Y}|) Dkpk(k=1,2,3,..Y)
D D D的信息熵: E n t ( D ) = − ∑ k = 1 ∣ Y ∣ p k l o g 2 P k Ent(D)=-\sum\limits_{k=1}^{|\mathcal{Y}|}p_klog_2P_k Ent(D)=k=1Ypklog2Pk

  • E n t ( D ) Ent(D) Ent(D)的值越小,D的纯度越高。

离 散 属 性 a 有 V 个 可 能 的 取 值 { a 1 , a 2 , . . . , a V } 离散属性a有V个可能的取值\left\{a^1,a^2,...,a^V\right\} aV{a1,a2,...,aV}
D v : 第 v 个 分 支 结 点 包 含 了 D 中 所 有 在 属 性 a 上 的 取 值 为 a v 的 样 本 D^v:第v个分支结点包含了D中所有在属性a上的取值为a^v的样本 Dv:vDaav

样本数越多,分支结点的影响越大。

属 性 a 对 样 本 集 D 进 行 划 分 获 得 的 " 信 息 增 益 " : G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) 属性a对样本集D进行划分获得的"信息增益":Gain(D,a)=Ent(D)-\sum\limits_{v=1}^V\frac{|D^v|}{|D|}Ent(D^v) aD""Gain(D,a)=Ent(D)v=1VDDvEnt(Dv)

  • 信息增益越大,使用属性 a a a来进行划分所获得的的纯度提升越大。

将4.2 算法中第8行选择属性改为 a ∗ = arg ⁡ max ⁡ a ∈ A G a i n ( D , a ) a_*=\arg\max\limits_{a \in A}Gain(D, a) a=argaAmaxGain(D,a)

ID3 决策树算法

  • ID(Iterative Dichotomiser), 迭代二分器

信息增益_计算示例:

在这里插入图片描述
1、计算,选择第一个划分属性
在这里插入图片描述
划分:
在这里插入图片描述
2、进行第二层划分,以最左的子集为例:
同样计算各属性的信息增益

在这里插入图片描述
最大增益的有三个,选其中一个即可。

最终得到的划分方案之一:
在这里插入图片描述

4.2.2 增益率

问题:信息增益准则对可选取数目多的属性有偏好

C4.5决策树算法, 增益率

  • 和ID3决策树算法是同一个学者设计

增益率(gain ratio):

G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain\_ratio(D, a)=\frac{Gain(D, a)}{IV(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)
I V ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ l o g 2 ∣ D v ∣ ∣ D ∣ IV(a)=-\sum\limits_{v=1}^V\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|} IV(a)=v=1VDDvlog2DDv, 属性a的固有值(intrinsic value)

在这里插入图片描述

增益率准则对 可取值数目较少的属性有所偏好。

  • C4.5算法选择划分属性的方法: 先从候选划分属性中找出信息增益 高于 平均水平的属性,再从中选择增益率高

4.2.3 基尼指数(Gini index)

CART(Classification and Regression Tree), 可用于分类回归任务。

数据集 D D D的纯度可用基尼值来度量:

G i n i ( D ) = ∑ k = 1 ∣ Y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ Y ∣ p k 2 Gini(D)=\sum\limits_{k=1}^{|\mathcal{Y}|}\sum\limits_{k^{'}\neq k}p_kp_{k^{'}}=1-\sum\limits_{k=1}^{|\mathcal{Y}|}p_k^2 Gini(D)=k=1Yk=kpkpk=1k=1Ypk2

G i n i ( D ) Gini(D) Gini(D)反映了从数据集 D D D中随机抽取两个样本,其类别不一致的概率。

  • 减去类别一致的概率,剩下的就是类别不一致的概率???

G i n i ( D ) Gini(D) Gini(D)越小,数据集 D D D的纯度越高

最优划分属性: 基尼指数小的

  • 图4.2 算法中第8行选择属性改为 a ∗ = arg ⁡ min ⁡ a ∈ A G i n i _ i n d e x ( D , a ) a_*=\arg\min\limits_{a \in A}Gini\_index(D, a) a=argaAminGini_index(D,a)

4.3 剪枝(pruning)处理_ 应对过拟合

决策树算法 对付 过拟合

过拟合: 把训练集自身的一些特点当作所有数据都具有的一般性质

主动去掉一些分支, 降低过拟合的风险。

决策树剪枝的基本策略特点
预剪枝(prepruning)1、决策树生成过程中;2、结点划分前进行估计:若当前结点的划分不能带来决策树泛化性能的提升,停止划分。
后剪枝(postpruning)1、完整的决策树已生成;2、自底向上对非叶结点进行考察: 若将该结点对应的子树替换为叶结点能带来决策树泛化性能的提升,则将该子树替换为叶结点。

如何判断决策树泛化性能是否提升呢?

  • 2.2节 性能评估方法

留出法

在这里插入图片描述
在这里插入图片描述

4.3.1 预剪枝

注: 类别标记为训练样例最多的类别。

1、对划分前后的泛化性能进行估计。

在这里插入图片描述

?结点3的判断是有问题吗?

在这里插入图片描述

在这里插入图片描述

预剪枝优缺点

1、预剪枝使得决策树的很多分支都没有展开。

  • 降低了过拟合的风险,显著减少了决策树的训练开销和测试时间开销

2、预剪枝基于"贪心"本质禁止分支展开,有欠拟合风险

  • 后续划分有可能性能显著提高。

4.3.2 后剪枝

同样处理图4.5的决策树,其验证集精度为42.9%。
在这里插入图片描述
后剪枝:

在这里插入图片描述
1、考察结点⑥,训练集包含{7,15},替换成叶结点"好瓜", 再看验证集中{8,9}都将是好瓜。剪枝后,8号判断正确,精确度为4/7=51.7%。

2、考察结点⑤,训练集包括{6,7,15}, 替换成叶结点"好瓜",对验证集无影响,可以不剪枝。

3、考察结点②,训练集包括{1,2,3,14},替换成叶结点"好瓜",对验证集{4,13,5},相比于剪枝前,{5}将判定正确,此时验证集精度为5/7=71.4%,进行剪枝。

在这里插入图片描述

①②③④⑤⑥⑦⑧⑨⑩

后剪枝优缺点

后剪枝决策树通常比预剪枝决策树保留了更多的分支。

1、后剪枝决策树的欠拟合风险很小泛化性能往往优于预剪枝决策树。

2、后剪枝过程是在生成完全决策树之后进行的,并且需要自底向上地对树中的所有非叶子结点进行逐一考察

  • 训练时间开销大

4.4 连续与缺失值

4.4.1 连续值处理

决策树学习 使用 连续属性

连续属性离散化。

二分法

样 本 集 D 和 连 续 属 性 a , 假 定 a 在 D 上 出 现 了 n 个 不 同 的 取 值 , 样本集D和连续属性a,假定a在D上出现了n个不同的取值, Da,aDn,
将 这 些 值 进 行 从 小 到 大 的 排 序 , 记 为 { a 1 , a 2 , . . . , a n } 将这些值进行从小到大的排序,记为\left\{a^1,a^2,...,a^n\right\} {a1,a2,...,an}
相 邻 的 属 性 取 值 a i 和 a i + 1 相邻的属性取值a^i和a^{i+1} aiai+1

包含n-1个元素的候选划分点
T a = { a i + a i + 1 2 ∣ 1 ≤ i ≤ n − 1 } T_a=\left\{\frac{a^i+a^{i+1}}{2}|1\le i\le n-1\right\} Ta={2ai+ai+11in1}

像离散属性值一样考察这些划分点。

G a i n ( D , a ) = max ⁡ t ∈ T a G a i n ( D , a , t ) = max ⁡ t ∈ T a E n t ( D ) − ∑ λ ∈ { − , + } ∣ D t λ ∣ ∣ D ∣ E n t ( D t λ ) Gain(D,a)=\max\limits_{t\in T_a }Gain(D,a,t)=\max\limits_{t\in T_a }Ent(D)-\sum\limits_{\lambda\in\left\{-,+\right\}}\frac{|D_t^{\lambda}|}{|D|}Ent(D_t^{\lambda}) Gain(D,a)=tTamaxGain(D,a,t)=tTamaxEnt(D)λ{,+}DDtλEnt(Dtλ)

P85

4.4.2 缺失值处理

诊测成本、隐私保护。

4.5 多变量决策树

1、把每个属性视为坐标空间的一个坐标轴,则d个属性描述的样本就对应了d维空间中的一个数据点。

  • 轴平行

问题
若是分类边界需要很多段划分,需要进行大量的属性测试,测试时间开销就会很大。

在这里插入图片描述

多变量决策树: 实现斜划分甚至更复杂划分的决策树。

  • 不是为每个非叶子结点寻找一个最优划分属性,而是试图建立一个合适的线性分类器

在这里插入图片描述


决策树学习算法的三大代表: ID3, C4.5,CART

增量学习: 调整分支路径上的划分属性次序来对树进行重构。

CLS(Concept Learning System)

  • 决策树分而治之
  • 信息增益准则,ID3算法

习题

4.1

4.1 试证明对于不含冲突数据(即特征向量完全相同但标记不同)的训练集,必存在与训练集一致(即训练误差为0)的决策树。

4.2

4.2 试析使用"最小训练误差"作为决策树划分选择准则的缺陷。

4.3

4.3 试编程实现基于信息熵进行划分选择的决策树算法,并为表4.3中的树生成一棵决策树。

4.4

4.4 试编程实现基于基尼指数进行划分选择的决策树算法算法,为表4.2中数据生成预剪枝、后剪枝决策树,并与未剪枝决策树进行比较。

4.5

4.5 试编程实现基于对率回归进行划分选择的决策树算法,并为表4.3中数据生成一棵决策树。

4.6

4.6 试选择4个UCI数据集,对上述3种算法所产生的未剪枝、预剪枝、后剪枝决策树实验进行比较,并进行适当的统计显著性检验。

4.7

4.7 图4.2 是一个递归算法,若面临巨量数据,则决策树的层数会很深,使用递归方法易导致“栈”溢出。试使用“队列”数据结构,以参数 M a x D e p t h MaxDepth MaxDepth控制树的最大深度,写出与图4.2等价、但不使用递归的决策树算法。

4.8

4.8 试将决策树生成的深度优先搜索过程修改为广度优先搜索,以参数 M a x N o d e MaxNode MaxNode控制树的最大结点数,将题4.7中基于队列的决策树算法进行改写,对比题4.7中的算法,试析哪种方式更易于控制决策树所需存储不超过内存。

4.9

4.9 试将4.2.2节对缺失值的处理机制推广到基尼指数的计算当中去。

4.10

4.10 从网上下载或自己编程实现任意一种多变量决策树算法,并观察其在西瓜数据集3.0上产生的结果。

Code_天池_基于决策树的分类预测

天池课程链接_决策树分类

金融风控,医疗辅助诊断

基于树结构对数据进行划分

决策树优缺点

优点:
1、解释性好
2、可以发现特征的重要程度
3、模型的计算复杂度较低

缺点:
1、模型易过拟合,需剪枝
2、预测能力有限
3、方差较高,数据分布的轻微改变很容易造成树结构完全不同。

以决策树作为基模型的集成模型:
1、梯度提升树(GBDT)
2 、XGBoost
3、LightGBM

广告计算、CTR(点击通过率)预测、金融风控。

P1 Demo实践

流程:
1、库函数导入
2、模型训练
3、数据和模型可视化
4、模型预测

"""
Step1: 库函数导入
"""

import numpy as np 

import  matplotlib.pyplot as plt 
import seaborn as sns ## 可视化库,是对matplotlib进行二次封装而成

##  导入 决策树模型函数

from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
"""
Step2: 训练模型
"""

## 构造数据集
x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]])
y_label = np.array([0, 1, 0, 1, 0, 1])

## 调用决策树回归模型
tree_clf = DecisionTreeClassifier()

## 调用决策树模型拟合构造的数据集
tree_clf = tree_clf.fit(x_fearures, y_label)
"""
Step3: 数据和模型可视化
"""

## 可视化构造的数据样本点
plt.figure()
plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis')
plt.title('Dataset')
plt.show()

在这里插入图片描述

## 可视化决策树
import graphviz
dot_data = tree.export_graphviz(tree_clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("pengunis")

有一个报错:关于Graphviz,解决链接

  • 可能需要重启IDE
    在这里插入图片描述
"""
Step4: 模型预测
"""
## 创建新样本
x_fearures_new1 = np.array([[0, -1]])
x_fearures_new2 = np.array([[2, 1]])

## 在训练集和测试集上分布利用训练好的模型进行预测
y_label_new1_predict = tree_clf.predict(x_fearures_new1)
y_label_new2_predict = tree_clf.predict(x_fearures_new2)

print('The New point 1 predict class:\n',y_label_new1_predict)
print('The New point 2 predict class:\n',y_label_new2_predict)


import graphviz
graphviz.__version__
P2 基于企鹅数据集的决策树分类实践

流程:
1、库函数导入
2、数据读取/载入
3、数据信息简单查看
4、可视化描述
5、利用 决策树模型 在二分类 上进行预测和训练
6、利用 决策树 模型 在三分类(多分类) 上进行 训练和预测

数据载入(网页->本地)
#下载需要用到的数据集
# !wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/6tree/penguins_raw.csv

####################  报错

## 需要先 pip install wget
"""
在Jupyter Notebook使用
"""
import wget
wget.download('https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/6tree/penguins_raw.csv', 'penguins_raw.csv')
"""
Step1: 库函数导入
"""
##  基础函数库
import numpy as np 
import pandas as pd

## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns

在这里插入图片描述

2、数据读取与载入(本地)
"""
Step2: 数据读取/载入
"""
## 利用Pandas自带的read_csv函数读取并转化为DataFrame格式
data = pd.read_csv('./penguins_raw.csv')

## 为了方便,仅选取四个简单的特征
data = data[['Species','Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']]
3、数据信息查看
"""
Step3: 数据信息简单查看
"""
## 利用.info()查看数据的整体信息
# data.info()
# data.head()    ## 看前5条 信息   , 这里发现存在缺失值 NaN ,填补方法: 补-1, 中位数填补、平均数填补
data.tail()    ## 看最后五条  信息
# data['Species'].unique()  ## 其对应的类别标签为'Adelie Penguin', 'Gentoo penguin', 'Chinstrap penguin'三种不同企鹅的类别。

# pd.Series(data['Species']).value_counts()  ## 利用value_counts函数查看每个类别数量

data.describe()  ## 对于特征进行一些统计描述
## 用-1填补缺失值
data = data.fillna(-1)
3、可视化描述
"""
Step4: 可视化描述
"""
## 特征与标签组合的散点可视化
sns.pairplot(data=data, diag_kind='hist', hue= 'Species')
plt.show()

在这里插入图片描述

从上图可以发现,在2D情况下不同的特征组合对于不同类别的企鹅的散点分布,以及大概的区分能力Culmen Lenth(第1行和第1列)与其他特征的组合散点的重合较少,所以对于数据集的划分能力最好

箱型图:可以得到不同类别在不同特征上的分布差异情况。
'''为了方便我们将标签转化为数字
       'Adelie Penguin (Pygoscelis adeliae)'        ------0
       'Gentoo penguin (Pygoscelis papua)'          ------1
       'Chinstrap penguin (Pygoscelis antarctica)   ------2 '''

def trans(x):
    if x == data['Species'].unique()[0]:
        return 0
    if x == data['Species'].unique()[1]:
        return 1
    if x == data['Species'].unique()[2]:
        return 2

data['Species'] = data['Species'].apply(trans)

for col in data.columns:
    if col != 'Species':
        sns.boxplot(x='Species', y=col, saturation=0.5, palette='pastel', data=data)
        plt.title(col)
        plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

# 选取其前三个特征绘制三维散点图
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')

data_class0 = data[data['Species']==0].values
data_class1 = data[data['Species']==1].values
data_class2 = data[data['Species']==2].values
# 'setosa'(0), 'versicolor'(1), 'virginica'(2)
ax.scatter(data_class0[:,0], data_class0[:,1], data_class0[:,2],label=data['Species'].unique()[0])
ax.scatter(data_class1[:,0], data_class1[:,1], data_class1[:,2],label=data['Species'].unique()[1])
ax.scatter(data_class2[:,0], data_class2[:,1], data_class2[:,2],label=data['Species'].unique()[2])
plt.legend()

plt.show()

在这里插入图片描述

决策树 二分类 训练+预测
## 为了正确评估模型性能,将数据划分为训练集和测试集,并在训练集上训练模型,在测试集上验证模型性能。
from sklearn.model_selection import train_test_split

## 选择其类别为0和1的样本 (不包括类别为2的样本)
data_target_part = data[data['Species'].isin([0,1])][['Species']]
data_features_part = data[data['Species'].isin([0,1])][['Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']]

## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data_features_part, data_target_part, test_size = 0.2, random_state = 2020)
## 从sklearn中导入决策树模型
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
## 定义 决策树模型 
clf = DecisionTreeClassifier(criterion='entropy')
# 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## 可视化
import graphviz
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("penguins")

在这里插入图片描述

## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
from sklearn import metrics

## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))

## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)

# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()

在这里插入图片描述

决策树模型 三分类 训练+预测
## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(data[['Culmen Length (mm)','Culmen Depth (mm)',
            'Flipper Length (mm)','Body Mass (g)']], data[['Species']], test_size = 0.2, random_state = 2020)
## 定义 决策树模型 
clf = DecisionTreeClassifier()
# 在训练集上训练决策树模型
clf.fit(x_train, y_train)
## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)

## 由于决策树模型是概率预测模型(前文介绍的 p = p(y=1|x,\theta)),所有我们可以利用 predict_proba 函数预测其概率
train_predict_proba = clf.predict_proba(x_train)
test_predict_proba = clf.predict_proba(x_test)

print('The test predict Probability of each class:\n',test_predict_proba)
## 其中第一列代表预测为0类的概率,第二列代表预测为1类的概率,第三列代表预测为2类的概率。

## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
## 查看混淆矩阵
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)

# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()

在这里插入图片描述

sklearn_决策树模型重要参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Code_sklearn_决策树

英文文档:https://scikit-learn.org/stable/modules/tree.html
中文文档:https://www.sklearncn.cn/11/

可用于分类与回归, 无参 监督学习

从数据特征中 学习决策规则 预测目标变量的值。

决策树优缺点

优势:
1、便于理解和解释。 树的结构可以可视化。
2、训练需要的数据少。但不支持缺失值
3、训练模型的时间复杂度是 参与训练的数据点对数 的数量。
4、能够处理数值型数据分类数据

缺点:
1、容易过拟合,导致泛化性能差。

  • 剪枝
  • 设置叶结点所需的最小样本数或设置树的最大深度。

2、数据中的 微小变化可能会导致完全不同的树。

  • 决策树的集成

3、拟合前先对数据进行平衡

简单分类:

二分类_决策树

"""
决策树——简单分类
"""
from sklearn import tree
X = [[0, 0], [1, 1]]
Y = [0, 1]
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)

## 预测类别和概率
print(clf.predict([[2., 2.]]))
print(clf.predict_proba([[2., 2.]]))

在这里插入图片描述

多分类_决策树

"""
决策树——多分类
"""

from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)

import graphviz   ## 可视化决策树
dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
graph.render("iris")

在这里插入图片描述

决策树可视化_美化
"""
美化决策树_Jupyter Notebook
"""
dot_data = tree.export_graphviz(clf, out_file=None,
                     feature_names=iris.feature_names,
                     class_names=iris.target_names,
                    filled=True, rounded=True,
                    special_characters=True)
graph = graphviz.Source(dot_data)
graph.render("iris2")   ## 到文件目录里找 d对应的pdf文件
graph

在这里插入图片描述

决策树可视化_文本导出
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_text
iris = load_iris()
decision_tree = DecisionTreeClassifier(random_state=0, max_depth=2)
decision_tree = decision_tree.fit(iris.data, iris.target)
r = export_text(decision_tree, feature_names=iris['feature_names'])
print(r)

在这里插入图片描述

Code例: iris数据集_决策树

可能需要更新版本:

pip install -U scikit-learn
from sklearn.datasets import load_iris

iris = load_iris()

"""
所有特征对  决策函数
"""
import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.inspection import DecisionBoundaryDisplay


# Parameters
n_classes = 3
plot_colors = "ryb"
plot_step = 0.02


for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]):
    # We only take the two corresponding features
    X = iris.data[:, pair]
    y = iris.target

    # Train
    clf = DecisionTreeClassifier().fit(X, y)

    # Plot the decision boundary
    ax = plt.subplot(2, 3, pairidx + 1)
    plt.tight_layout(h_pad=0.5, w_pad=0.5, pad=2.5)
    DecisionBoundaryDisplay.from_estimator(
        clf,
        X,
        cmap=plt.cm.RdYlBu,
        response_method="predict",
        ax=ax,
        xlabel=iris.feature_names[pair[0]],
        ylabel=iris.feature_names[pair[1]],
    )

    # Plot the training points
    for i, color in zip(range(n_classes), plot_colors):
        idx = np.where(y == i)
        plt.scatter(
            X[idx, 0],
            X[idx, 1],
            c=color,
            label=iris.target_names[i],
            cmap=plt.cm.RdYlBu,
            edgecolor="black",
            s=15,
        )

plt.suptitle("Decision surface of decision trees trained on pairs of features")
plt.legend(loc="lower right", borderpad=0, handletextpad=0)
_ = plt.axis("tight")


在这里插入图片描述

"""
决策树 可视化
"""
from sklearn.tree import plot_tree

plt.figure()
clf = DecisionTreeClassifier().fit(iris.data, iris.target)
plot_tree(clf, filled=True)
plt.title("Decision tree trained on all the iris features")
plt.show()

在这里插入图片描述
用于理解决策树结构的一些示例

Code例:回归_决策树

from sklearn import tree
X = [[0, 0], [2, 2]]
y = [0.5, 2.5]
clf = tree.DecisionTreeRegressor()
clf = clf.fit(X, y)
clf.predict([[1, 1]])

在这里插入图片描述

# Import the necessary modules and libraries
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))

# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)

# Predict
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)

# Plot the results
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, 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参数控制)设置得太高,则决策树学习了训练数据的细节过多,并从噪声中学习,将会过拟合

Code例:多输出_决策树回归

多输出问题: 有多个输出需要预测。

输出之间没有相关性: 构建n个独立的模型
与同一输入相关的输出值可能是相关的: 构建能够同时预测所有N输出的单个模型。

"""
决策树   多输出回归 示例

输入X: 单个实数值
输出Y: X 的正弦和余弦
"""

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor

# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(200 * rng.rand(100, 1) - 100, axis=0)
y = np.array([np.pi * np.sin(X).ravel(), np.pi * np.cos(X).ravel()]).T
y[::5, :] += 0.5 - rng.rand(20, 2)

# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_3 = DecisionTreeRegressor(max_depth=8)
regr_1.fit(X, y)
regr_2.fit(X, y)
regr_3.fit(X, y)

# Predict
X_test = np.arange(-100.0, 100.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
y_3 = regr_3.predict(X_test)

# Plot the results
plt.figure()
s = 25
plt.scatter(y[:, 0], y[:, 1], c="navy", s=s, edgecolor="black", label="data")
plt.scatter(
    y_1[:, 0],
    y_1[:, 1],
    c="cornflowerblue",
    s=s,
    edgecolor="black",
    label="max_depth=2",
)
plt.scatter(y_2[:, 0], y_2[:, 1], c="red", s=s, edgecolor="black", label="max_depth=5")
plt.scatter(
    y_3[:, 0], y_3[:, 1], c="orange", s=s, edgecolor="black", label="max_depth=8"
)
plt.xlim([-6, 6])
plt.ylim([-6, 6])
plt.xlabel("target 1")
plt.ylabel("target 2")
plt.title("Multi-output Decision Tree Regression")
plt.legend(loc="best")
plt.show()

在这里插入图片描述

Code例: 根据脸的上半部分预测下半部分

import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import fetch_olivetti_faces
from sklearn.utils.validation import check_random_state

from sklearn.ensemble import ExtraTreesRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import RidgeCV

# Load the faces datasets
data, targets = fetch_olivetti_faces(return_X_y=True)

train = data[targets < 30]
test = data[targets >= 30]  # Test on independent people

# Test on a subset of people
n_faces = 5
rng = check_random_state(4)
face_ids = rng.randint(test.shape[0], size=(n_faces,))
test = test[face_ids, :]

n_pixels = data.shape[1]
# Upper half of the faces
X_train = train[:, : (n_pixels + 1) // 2]
# Lower half of the faces
y_train = train[:, n_pixels // 2 :]
X_test = test[:, : (n_pixels + 1) // 2]
y_test = test[:, n_pixels // 2 :]

# Fit estimators
ESTIMATORS = {
    "Extra trees": ExtraTreesRegressor(
        n_estimators=10, max_features=32, random_state=0
    ),
    "K-nn": KNeighborsRegressor(),
    "Linear regression": LinearRegression(),
    "Ridge": RidgeCV(),
}

y_test_predict = dict()
for name, estimator in ESTIMATORS.items():
    estimator.fit(X_train, y_train)
    y_test_predict[name] = estimator.predict(X_test)

# Plot the completed faces
image_shape = (64, 64)

n_cols = 1 + len(ESTIMATORS)
plt.figure(figsize=(2.0 * n_cols, 2.26 * n_faces))
plt.suptitle("Face completion with multi-output estimators", size=16)

for i in range(n_faces):
    true_face = np.hstack((X_test[i], y_test[i]))

    if i:
        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1)
    else:
        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1, title="true faces")

    sub.axis("off")
    sub.imshow(
        true_face.reshape(image_shape), cmap=plt.cm.gray, interpolation="nearest"
    )

    for j, est in enumerate(sorted(ESTIMATORS)):
        completed_face = np.hstack((X_test[i], y_test_predict[est][i]))

        if i:
            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j)

        else:
            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j, title=est)

        sub.axis("off")
        sub.imshow(
            completed_face.reshape(image_shape),
            cmap=plt.cm.gray,
            interpolation="nearest",
        )

plt.show()

在这里插入图片描述

输入X是面的上半部分的像素,并且输出Y是这些面的下半部分的像素。

论文:M. Dumont et al, Fast multi-class image annotation with random subwindows and multiple output randomized trees, International Conference on Computer Vision Theory and Applications 2009

在这里插入图片描述

决策树 使用技巧

1、合适的样本比例和特征数量。

  • 高维空间、少量样本很容易过拟合

2、事先进行降维(PCA, ICA)
3、使用 max_depth=3 作为初始树深度,让决策树知道如何适应您的数据,然后再增加树的深度。

4、使用 max_depth 来控制输的大小防止过拟合。

5、尝试 min_samples_leaf=5 作为初始值。如果样本的变化量很大,可以使用浮点数作为这两个参数中的百分比。两者之间的主要区别在于 min_samples_leaf 保证叶结点中最少的采样数,而 min_samples_split 可以创建任意小的叶子,尽管在文献中 min_samples_split 更常见。

  • 通过使用 min_samples_split 和 min_samples_leaf 来控制叶节点上的样本数量。

6、训练之前平衡数据集

7、如果输入的矩阵X为稀疏矩阵,建议您在调用fit之前将矩阵X转换为稀疏的csc_matrix ,在调用predict之前将 csr_matrix 稀疏。当特征在大多数样本中具有零值时,与密集矩阵相比,稀疏矩阵输入的训练时间可以快几个数量级。

决策树算法: ID3,C4.5,C5.0,CART

1、ID3(Iterative Dichotomiser 3)由 Ross Quinlan 在1986年提出。该算法创建一个多路树,找到每个节点(即以贪心的方式)分类特征,这将产生分类目标的最大信息增益。决策树发展到其最大尺寸,然后通常利用剪枝来提高树对未知数据的泛化能力。
4、CART 使用在每个节点产生最大信息增益的特征和阈值来构造二叉树。

scikit-learn 使用 CART 算法的优化版本。

后剪枝一些参考资料

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值