决策树是一种基本的回归与分类算法,可以将决策树看作一个 i f − t h e n if-then if−then规则的集合(e.g.内部结点处对特定条件进行判断,为True则访问左子树,反之访问右子树)或者是给定条件下的概率分布(e.g.将特征空间划分为互不相交的单元或者区域,并在每一个单元定义一个类的概率分布就构成一个条件概率分布),其模型呈现树形结构,决策树由结点和有向边组成,其中结点可进一步分为内部结点(一个属性或者一个特征)和叶结点(一个类)。
决策树在分类问题中表示基于特征对实例进行分类的过程,决策树具有模型可读、分类速度快的优点。决策树的学习本质是从训练集中归纳出一组分类规则,通常以正则化的极大似然函数作为损失函数,以损失函数为目标函数从而进行最小化为学习策略。决策树的学习有三个需要关注的方面:特征选择
、决策树的生成
、决策树的剪枝
。决策树的生成对应于模型的局部选择,只考虑局部最优。决策树的剪枝对应于模型的全局选择,考虑全局最优。
特征选择的准则通常是信息增益或者信息增益比,首先给出熵与条件熵的定义
数据准备:
import pandas as pd
import numpy as np
def create_data():
datasets = [
# 1
['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '是'],
# 2
['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '是'],
# 3
['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '是'],
# 4
['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '是'],
# 5
['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '是'],
# 6
['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '是'],
# 7
['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '是'],
# 8
['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '是'],
# 9
['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '否'],
# 10
['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '否'],
# 11
['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '否'],
# 12
['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '否'],
# 13
['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '否'],
# 14
['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '否'],
# 15
['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '否'],
# 16
['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '否'],
# 17
['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '否']
]
labels = [
u'色泽',u'根蒂',u'敲声',u'纹理',u'脐部',u'触感',u'好瓜'
]
return datasets, labels
datasets, labels = create_data()
data = pd.DataFrame(datasets, columns=labels)
信息增益指的是得知特征的信息而使得y的信息的不确定性减少的程度:
def ent(data, label):
prob = []
for i in data[label].unique():
prob.append(len(data[data[label] == i]) / len(data))
log_prob = np.log2(prob)
return -log_prob.dot(prob)
def gain(data, attr, label):
entropy = []
d = []
for i in data[attr].unique():
entropy.append(ent(data[data[attr] == i], label))
d.append(len(data[data[attr] == i]) / len(data))
return ent(data, label) - np.array(entropy).dot(d)
用信息增益作为划分训练集的特征,存在偏向于选择取值较多的特征的问题。而信息增益比可以对这个问题进行校正。
def gain_ratio(data, attr, label):
d = []
log_d = []
for i in data[attr].unique():
d.append(len(data[data[attr] == i]) / len(data))
log_d = np.log2(d)
IV = -np.array(log_d).dot(d)
return gain(data, attr, label) / IV
#基尼指数Gini(D)表示集合D的不确定性
def gini(data, label):
prob = []
for i in data[label].unique():
prob.append((len(data[data[label] == i]) / len(data))**2)
return 1 - sum(prob)
#基尼系数Gini(D,A)表示经过A=a分割后集合D的不确定性:
#在特征A的条件下,集合D的基尼指数定义为
def gini_index(data, attr, label):
d = []
ginis = []
for i in data[attr].unique():
d.append(len(data[data[attr] == i]) / len(data))
ginis.append(gini(data[data[attr] == i], label))
return np.array(d).dot(ginis)
决策树生成有许多方法,这里记录ID3算法、C4.5算法以及CART算法:
C4.5算法与ID3算法相似,只是在生成树的过程中,用信息增益比来选择特征。