您的位置:首页 > 编程语言 > Python开发

决策树Python实现

2017-05-07 15:53 197 查看
决策树的实现主要是通过进行特征选择来进行决策树构建,而特征选择取决于信息增益或者信息增益比

信息增益由熵和条件熵确定 熵是表示随机变量不确定时的度量

决策树的实现比较多的是利用信息增益来实现的,在 划 分 数 据 集 之 前 之 后 信 息 发 生 的 变 化 称 为 信 息 增 益 ,通过特 征 值 划 分 数 据 集 获 得 的 信 息 增 益 ,获 得 信 息 增 益 最 高 的 特 征 就 是 最 好 的 选 择。

得 到 熵 之 后 , 我 们 就 可 以 按 照 获 取 最 大 信 息 增 益 的 方 法 划 分 数 据 集

计算香农熵的函数
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 splitDataSet(dataSet, axis, value):
retDataSet = []
for featVec in dataSet:
if featVec[axis] == value:
reducedFeatVec = featVec[:axis]     #选择划分数据集的特征进行划分
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet


选择最好的特征划分方式

def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 # 获取数据集长度
baseEntropy = calcShannonEnt(dataSet) # 计算数据集的熵
bestInfoGain = 0.0; bestFeature = -1
for i in range(numFeatures):
featList = [example[i] for example in dataSet] # 创建唯一的分类标签列表
uniqueVals = set(featList)
newEntropy = 0.0
for value in uniqueVals:   #计算每种划分方式的信息熵
subDataSet = splitDataSet(dataSet, i, value)
prob = len(subDataSet)/float(len(dataSet))
newEntropy += prob * calcShannonEnt(subDataSet)
infoGain = baseEntropy - newEntropy
if (infoGain > bestInfoGain):   # 计算最好的信息增益
bestInfoGain = infoGain
bestFeature = i
return bestFeature


采 用 多 数 表 决 的 方 法 决定 该 叶 子 节 点 的 分 类

def majorityCnt(classList):
classCount={}
for vote in classList:
if vote not in classCount.keys(): classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]


创建树函数

def createTree(dataSet,labels):
classList = [example[-1] for example in dataSet]
if classList.count(classList[0]) == len(classList):  #类别相同停止划分
return classList[0]
if len(dataSet[0]) == 1:   # 遍历 完 所 有 特 征 时 返 回 出 现 次 数 最 多 的
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
return myTree


对于创建好的树,可以通过matplotlib画出来 也可以通过pydotplus,
graphviz转化为可视化pdf

createTree.export_graphviz(clf, out_file=dot_data)

graph = pydotplus.graph_from_dot_data(dot_data.getvalue())

graph.write_pdf("xxx.pdf")#写入pdf


决 策 树 非 常 好 地 匹 配 了 实 验 数 据 , 然 而 这 些 匹 配 选 项 可 能 太 多 了 。我 们 将 这 种问 题 称 之 为 过 度 匹 配 。为 了 减 少 过 度 匹 配 问 题 , 我 们 可 以 裁 剪 决 策 树 , 去 掉 一 些 不必要 的 叶 子 节 点。如果 叶 子 节 点只 能 增 加 少 许 信 息 , 则 可 以 删 除 该 节 点, 将 它 并 人 到 其 他 叶 子 节点 中 本次使用的算法是ID3 算法 ,但是该算法并不完美,如果 存 在 太 多 的 特 征 划 分 , ID3 算 法 仍 然 会 面 临 其 他 问 题

决 策 树 分 类 器 就 像 带有 终 止 块 的 流 程 图 , 终 止 块 表 示 分 类 结 果 。开 始 处 理 数 据 集 时 , 我 们 首先 需 要 测 量 集 合 中 数 据 的 不 一 致 性 , 也 就 是 熵 , 然 后 寻 找 最 优 方 案 划 分 数 据 集 , 直 到 数 据 集 中 的所 有 数 据 属 于 同 一 分 类

通 过 裁 剪 决 策 树 , 合 并 相 邻 的 无 法 产 生 大 量 信 息 增 益

的 叶 节 点, 消 除 过 度 匹 配 问 题

决策树有多种生成方式,第一种就是上面使用的iD3,还有就是使用信息增益比的 C4.5生成算法以及使用基尼指数的CART 分类回归树生成,值得一提的是,在使用CART 生成决策树的时候,基尼指数和信息增益的选取恰恰相反。选取基尼指数最小的最优特征
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: