决策树的一般流程
(1)收集数据:可以使用任何方法
(2)准备数据: 树构造算法值适用于标称型数据(结果只在有限目标集中取,如真与假),因此数值型数据必须离散化
(3)分析数据: 构造树完成之后,应该检查图形是否符合预期
(4)训练算法:构造树的数据结构
(5)测试算法:使用经验树计算错误率
(6)使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义
创建分支的伪代码递归函数 createBranch():
检测数据集中的每个子项是否属于同一分类:
If so return 类标签
Else
寻找划分数据集的最好特征
划分数据集
创建分支节点
for 每个划分的子集
调用函数createBranch并增加返回结果到分支节点中
return 分支节点
补充功能: 在 Markdown 文档中,可以直接采用 HTML 标记插入空格(blank space),而且无需任何其他前缀或分隔符。具体如下所示:
插入一个空格 (non-breaking space)
或 &
插入两个空格 (en space)
  或 &
插入四个空格 (em space)
  或 &
插入细空格 (thin space)
  或 &
程序清单3-1 计算给定数据集的香农熵
熵(entropy)定义为信息的期望值: l ( x i ) = − log 2 p ( x i ) l(x_{i})=-\log_{2} p(x_{i}) l(xi)=−log2p(xi)
计算熵,需要计算所有类别所有可能值包含的信息期望值:
H = − ∑ i = 1 n p ( x i ) log 2 p ( x i ) H = -\sum_{i=1}^{n}p(x_{i})\log_{_{2}}p(x_{i}) H=−∑i=1np(xi)log2p(xi)
from math import log
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts={
}
for featVec in dataSet:
currentLabel = featVec[-1]
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key])/numEntries
shannonEnt -= prob * log(prob,2)
return shannonEnt
def createDataSet():
dataSet = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
labels = ['no surfacing','flippers']
return dataSet, labels
myDat,labels = createDataSet()
calcShannonEnt(myDat)
0.9709505944546686
print(-0.4*log(0.4,2)-0.6*log(0.6,2))
0.9709505944546686
myDat[0][-1] = 'maybe'
myDat[0][1] = 1
myDat
[[1, 1, 'maybe'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
calcShannonEnt(myDat)
1.3709505944546687
程序清单3-2 按照给定特征划分数据集
def splitDataSet(dataSet,axis,value):
retDataSet = []
'''
for featVec in dataSet:
print(featVec)
if featVec[axis] == value:
print(featVec[axis])
reducedFeatVec = featVec[:axis]
print(reducedFeatVec)
reducedFeatVec.extend(featVec[axis+1:])
print(featVec[axis+1:])
retDataSet.append(reducedFeatVec) # 抽取
print(retDataSet)
'''
for featVec in dataSet:
if featVec[axis] == value:
reducedFeatVec = featVec[: