决策树的优点:计算的复杂度不高,输出的结果易于理解,对中间值的确实不敏感,可以处理不相关的特征数据
决策树的缺点:可能会产生过度匹配的问题。
其本质的思想是通过寻找区分度最好的特征(属性),用于支持分类规则的制定。
那么哪些特征是区分度好的,哪些特征是区分度坏的呢?换句话说,如何衡量数据集中特征(属性)对实例的区分程度呢?
依据香农的信息论,引入信息熵的思想作为对特征区分程度的度量。当然,信息熵并不是唯一的度量指标,在一些机器学习的开源包中,也提供了别的依据。跟着书走,本次实验还是选择信息熵作为划分数据集的标准。原书《机器学习实战》中使用的是python2,本人在python3实现,略有不同。
源码+实验数据地址:https://github.com/MoonTreee/machine_learning
代码如下。
shannon.py
from math import log
import operator
# 计算信息熵
def clacShannon(data):
num = len(data)
# 用于计算每个类别出现的次数,配合num就可以计算该类别的概率了
label_count = {}
for feat_vec in data:
# 向量的最后一个为标签(类别)
current_label = feat_vec[-1]
if current_label in label_count.keys():
label_count[current_label] += 1
else:
label_count[current_label] = 1
entropy = 0.0
for key in label_count.keys():
prob = float(label_count[key]) / num
entropy -= prob * log(prob, 2)
return entropy
# 划分数据集
# data 需要划分的数据,双重列表[[],[],……,[]]
# axis 划分的特征
# value 上述axis的值
def splitData(data, axis, value):
result = []
for feature_vec in data:
if feature_vec[axis] == value:
# 将符合条件的实例加入到result中(并去除了相应的特征)
# result.append(feature_vec[:axis].extend(feature_vec[axis + 1:]))
reduce_feat = feature_vec[:axis]
reduce_feat.extend(feature_vec[axis+1:])
result.append(reduce_feat)
return result
# 选择分类效果最好的特征
def chooseFeature(data):
num_data = len(data)
num_feature = len(data[0]) - 1
# 原始数据的香农熵
base_entropy = clacShannon(data)
# 信息增益
bes