机器学习——决策树(分类)

前言:内容参考周志华老师的《机器学习》,确实是一本好书,不过本科生读懂仍是有很大难度的,大多数模型都是直接给出公式,其实本身私下有推导,涉及好多本身不懂的数学知识,会一点点补充的

机器学习专栏html

  1. 机器学习——线性回归(预测)
  2. 机器学习——逻辑回归(分类)
  3. 机器学习——特征缩放
  4. 机器学习——正则化
  5. 机器学习——决策树

1、决策树基本流程

一颗决策树(decision tree)包括根节点、若干内部节点和若干叶子节点,不断的判断->分支->再判断->再分支……,决策树的构成实际上是一个递归的过程,遵循分而治之的策略。
在这里插入图片描述
(图源:周志华老师的《机器学习》)python

2、划分选择

决策树,最重要的固然是决策(或者说叫选择),那么根据什么标准进行选择呢?如何划分最优属性?咱们但愿决策树的分支结点所包含的样本尽量属于同有类别,就是结点的“纯度”(purity)愈来愈高。web

一、信息增益(ID3算法)

“信息熵”(information entropy)是度量样本集合纯度最经常使用的一种指标,信息熵的计算公式为:
E n t ( D ) = k = 1 K p k l o g 2 p k Ent(D)=-\sum_{k=1}^{K}p_klog_2p_k
E n t ( D ) Ent(D) 的值越小,则 D D 的纯度越高。其中, D D 是总样本集, p k p_k 表示第 k k 类样本出现的几率(第 k k 类样本占的比例), K K 是样本总类数。

“信息增益”(information gain)表示知道一个属性后,信息(标签判断)不肯定性减小的程度,信息增益的计算公式为:
G a i n ( D , a ) = E n t ( D ) v = 1 V D v D E n t ( D v ) Gain(D,a)=Ent(D)-\sum_{v=1}^{V}\frac{|D^v|}{|D|}Ent(D^v)
其中,离散属性 a a N N 种可能的取值 a 1 , a 2 , , a V {a^1,a^2,…,a^V} ,若是使用 a a 对样本进行划分,则会产生 V V 个分支结点,记 D v D^v D D 属性 a a 上取值为 a v a^v 的样本集。
因此,“信息增益”越大,就意味着用属性 a a 来划分数据集 D D 来进行划分所得到的纯度提高越大。故著名的ID3决策树算法就是以信息增益来选择划分属性:
a = a r g      m a x a A    G a i n ( D , a ) a^*=\mathop{arg\;\;max}\limits_{a\in A}\; Gain(D,a) 算法

二、信息增益率(C4.5算法)

ID3决策树经过信息增益选取划分属性,观察信息增益的公式能够看出,若是属性 a a 的属性值不少的状况下,一个属性值的分支节点的样本纯度就会很大,信息增益就会变大。因此C4.5决策算法采用“信息增益率”来选择划分属性。
“信息增益率”定义:
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)}
其中
I V ( a ) = v = 1 V D v D l o g 2 D v D IV(a)=-\sum_{v=1}^{V}\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|}
称为属性 a a 的“固有值”(intrinsic value)。属性 a a 的可能取值数目越多( V V 越大),则 I V ( a ) IV(a) 的值一般会越大。
可是,“信息增益率”准则可能会对取值数目较少的属性有所偏好。因此,C4.5算法并非直接选择“信息增益率”最大的候选划分属性,而是使用了一个启发式算法:app

  1. 先从候选划分属性中找出信息增益高于平均水平的属性;
  2. 再从中选择信息增益率最高的。

三、基尼指数(CART算法)

CART决策树使用“基尼指数”(Gini index)来选择划分属性,数据集 D D 的纯度用基尼指数来度量:
G i n i ( D ) = k = 1 K k k p k p k Gini(D)=\sum_{k=1}^{K}\sum_{k'\neq k}p_kp_{k'}
G i n i ( D ) Gini(D) 表示从 D D 中随机抽取两个样本,其类别不同的几率,故 G i n i ( D ) Gini(D) 越小, D D 纯度越高。
对属性 a a 的基尼指数定义为:
G i n i _ i n d e x ( D , a ) = v = 1 V D v D G i n i ( D v ) {Gini}\_{index(D,a)}=\sum_{v=1}^{V}\frac{D^v}{D}Gini(D^v)
所以,咱们选择那个使划分后基尼指数最小的属性做为最优划分属性,即:
a = a r g    m i n a A    G i n i _ i n d e x ( D , a ) a^*=\mathop {arg\;min}\limits_{a\in A}\;Gini\_index(D,a) 机器学习

3、剪枝处理

与线性回归同样,决策树也会存在过拟合的状况,线性回归的过拟合主要是经过正则化实现(可参考个人另外一篇博客机器学习——特征缩放、正则化),决策树的过拟合主要是经过剪枝处理来避免的。ide

一、预剪枝

预剪枝是在决策树生成的过程当中,对每一个结点进行划分前先进行估计,若当前结点的划分不能带来决策树泛化性能(验证集的准确度)的提高,则中止划分将当前结点做为叶子结点(分类结果为该结点下占比大的类别)。
在这里插入图片描述
(图源:周志华老师的《机器学习》)svg

二、后剪枝

后剪枝是指先从训练集生成一颗完整的决策树,而后自下而上对非叶子结点进行考察,若将该结点及其子结点替换为叶子结点能够提升泛化能力(验证集的准确度),将该结点及其子结点替换为叶子结点(分类结果为该结点下占比大的类别)。
在这里插入图片描述
(图源:周志华老师的《机器学习》)性能

3、连续与缺失值处理

一、连续值处理

前面咱们讨论的都是分类决策树,主要是经过离散属性来生成决策树,现实问题中,咱们遇到的每每会有连续属性,这时咱们就须要对连续值进行离散化处理,咱们一般采用二分法(C4.5中采用的方法)学习

二分法
给定样本集D和连续属性a,假定a在D中出现了n个不一样的取值,将这些值从小到大进行排序,记为 { a 1 , a 2 , a 3 , . . . , a n } \{a^1,a^2,a^3,...,a^n\} 。基于划分点 t t 能够将D分为子集 D t D^-_t D t + D^+_t ,显然对于相邻的值 a i a i + 1 a^i和a^{i+1} 来讲, t t 在区间 [ a i , a i + 1 ) [a^i,a^{i+1}) 中取任意值划分结果是同样的。所以,对于连续属性a,可能的侯划分点集合为:
T a = a i + a i + 1 2 i [ 1 , n 1 ] T_a=\frac{a^i+a^{i+1}}{2}\quad i\in[1,n-1]
二分法就体如今这,即把区间 [ a i , a i + 1 ) [a^i,a^{i+1}) 的中位点 a i + a i + 1 2 \frac{a^i+a^{i+1}}{2} 做为侯划分点,咱们要选取最优的划分点:
G a i n ( D , a ) = m a x t T a    G a i n ( D , a , t ) G a i n ( D , a , t ) = E n t ( D ) λ , + D t λ D E n t ( D t λ ) Gain(D,a)=\mathop {max}\limits_{t \in T_a}\;Gain(D,a,t)\\ Gain(D,a,t)=Ent(D)-\sum_{\lambda\in{-,+}}\frac{D_t^\lambda}{|D|}Ent(D_t^\lambda)
其中, G a i n ( D , a , t ) Gain(D,a,t) 就是样本集D基于划分点t二分后的信息增益,咱们就选择使 G a i n ( D , a , t ) Gain(D,a,t) 最大化的划分点。

二、缺失值处理

存在缺失值咱们主要有两个问题:

  1. 如何在属性值缺失的状况下选择最优划分属性(若有的样本在“色泽”这个属性上的值是缺失的,那么该如何计算“色泽”的信息增益等?);
  2. 给定划分属性,若样本在该属性上缺失,如何对该样本进行划分(即这个样本到底属于哪一类?)。

对于问题1,现有数据集D和属性a,令 D ~ \widetilde{D} 表示D在属性a上没有缺失值的样本子集,咱们能够根据 D ~ \widetilde{D} 来进行划分属性的选择。现假定属性a有V个值 a 1 , a 2 , . . . , a V {a^1,a^2,...,a^V} D ~ v \widetilde{D}^v 表示 D ~ \widetilde{D} 中属性a取值为 a v a^v 的样本子集, D ~ k \widetilde{D}_k 表示 D ~ \widetilde{D} 中属于第k类的样本子集。则有:
{ D ~ = k = 1 K D ~ k D ~ = v = 1 V D ~ v \left\{\begin{matrix} \widetilde{D}=\bigcup_{k=1}^{K}\widetilde{D}_k\\ \widetilde{D}=\bigcup_{v=1}^{V}\widetilde{D}^v \end{matrix}\right.
初始,咱们为每个样本 x x 赋予一个权重 w x w_x (初始化为1),并定义:
{ ρ = x D ~ w x x D w x p ~ k = x D ~ k w x x D ~ w x r ~ v = x D ~ v w x x D ~ w x \left\{\begin{matrix} \rho =\frac{\sum_{x\in \widetilde{D}}w_x}{\sum_{x\in D}w_x} \\ \widetilde{p}_k=\frac{\sum_{x \in \widetilde{D}_k}w_x}{\sum_{x \in \widetilde{D}}w_x} \\ \widetilde{r}_v=\frac{\sum_{x\in \widetilde{D}^v}w_x}{\sum_{x\in \widetilde{D}}w_x} \end{matrix}\right.
其中, ρ \rho 表示完好失值样本所占比例, p ~ k \widetilde{p}_k 表示完好失值样本中第k类中所占比例, r ~ v \widetilde{r}_v 表示完好失值样本中在属性a上取值为v的样本所占比例。显然:
{ k = 1 K p ~ k = 1 v = 1 V r ~ v = 1 \left\{\begin{matrix} \sum_{k=1}^{K}\widetilde{p}_k=1\\ \sum_{v=1}^{V}\widetilde{r}_v=1 \end{matrix}\right.
基于上述定义,咱们将含缺失值属性的信息增益计算推广为:
G a i n ( D , a ) = ρ × G a i n ( D ~ , a ) = ρ × ( E n t ( D ~ ) v = 1 V r ~ v E n t ( D ~ v ) ) \begin{aligned} Gain(D,a)&=\rho \times Gain(\widetilde{D},a)\\ &=\rho \times (Ent(\widetilde{D})-\sum_{v=1}^{V}\widetilde{r}_vEnt(\widetilde{D}^v)) \end{aligned}
对问题2,若样本 x x 在属性a上的取值未知,则将 x x 划入全部子结点,权值由 w x w_x 变为 r ~ w x \widetilde{r}\cdot w_x ,即让同一个样本以不一样的几率划入不一样的子结点中去。
这里推荐一篇博客,讲的很详细(包括实例计算过程)决策树(decision tree)(四)——缺失值处理

4、多变量决策树

咱们把每一个属性视为坐标空间中的一个坐标轴,以前咱们介绍的单变量决策树的分类边界都是与各个坐标轴平行
在这里插入图片描述
(图源:周志华老师的《机器学习》)

可是,当学习任务的真实边界比较复杂的时候,必需要使用不少段划分才能得到较好的近似,此时生成的决策树会很复杂。
此时,咱们可能须要斜边去划分,“多变量决策树”(multivariate decision tree)的分叶子结点再也不是针对某一个属性,而是一个线性分类器 i = 1 n w i a i = t \sum_{i=1}^{n}w_ia_i=t ,其中 w i w_i 是属性 a i a_i 的权重, w i w_i 和t可在该结点所含的样本集和属性值上学的。
在这里插入图片描述

5、sklearn实现决策树

能够看一看这一篇博文:DecisionTreeClassifier重要参数
这里再推荐一篇博文(分类结果的评价指标):分类效果评估

# -*- coding: utf-8 -*-
""" Created on Sun Nov 17 23:19:23 2019 @author: 1 """

from sklearn import tree
import pydotplus
from IPython.display import Image
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score#准确率

df=pd.read_csv("D:\workspace\python\machine learning\data\iris.csv",sep=',')
iris_data=df.iloc[:,0:3]
iris_target=df.iloc[:,4]
iris_data_train,iris_data_test,iris_target_train,iris_target_test = train_test_split(iris_data,iris_target,train_size=.80)
clf = tree.DecisionTreeClassifier(criterion='gini')#criterion='gini'基尼指数,criterion='entropy'信息增益,
clf = clf.fit(iris_data_train, iris_target_train)  
dot_data = tree.export_graphviz(clf, out_file=None, 
                         feature_names=df.columns[:3], # 特征名称
                         class_names=df.columns[4], # 目标变量的类别
                         filled=True, rounded=True,  
                         special_characters=True)  
y_pred=clf.predict(iris_data_test)
print('accuracy_score:',accuracy_score(iris_target_test, y_pred))
graph = pydotplus.graph_from_dot_data(dot_data)  
image=Image(graph.create_png())

由iris数据集获得的决策树:
在这里插入图片描述

相关文章
相关标签/搜索