决策树php,python机器学习决策树详细介绍

决策树(Decision Trees ,DTs)是一种无监督的学习方法,用于分类和回归。

优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据

缺点:可能会产生过度匹配的问题

适用数据类型:数值型和标称型  source code下载  https://www.manning.com/books/machine-learning-in-action

运行demo

关键算法

寻找划分数据集的最好特征

划分数据集

创建分支节点

for 每个分支节点

调用函数createBranch并增加返回结果到分支节点中

return 分支节点

对应代码

def createTree(dataSet,labels):

classList = [example[-1] for example in dataSet]不是dataset[-1] {dataset倒数第一元素},而这时里,dataset每一个元素里的倒数第一元素

if classList.count(classList[0]) == len(classList): 如果返回分类List count类型一样,则返回该类型!在子节点 是否可分类 如是一类型 返回 否则 递归往下分类

return classList[0]#stop splitting when all of the classes are equal

if len(dataSet[0]) == 1: #stop splitting when there are no more features in dataSet如果只有一个元素

return majorityCnt(classList)

bestFeat = chooseBestFeatureToSplit(dataSet)    选择最好的特征索引

bestFeatLabel = labels[bestFeat]    而得到这个label flippers 还是 no surfaces 呢

myTree = {bestFeatLabel:{}}    然后创建该最好的分类 的子树

del(labels[bestFeat])  删除了该最好分类

featValues = [example[bestFeat] for example in dataSet]

uniqueVals = set(featValues)     set是归类,看只有多少种类

for value in uniqueVals:

subLabels = labels[:] #copy all of labels, so trees don't mess up existing labels

myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)

return myTree

在划分数据集之前之后信息发生的变化称为信息增益,划分数据集的最大原则是将无序的数据变得更加有序。 这里理解成切饼原理:

b59987658eccb63d0c4e8d9a423ac703.png

把信息的复杂度,信息量用单位熵描述程度。 对应的是饼的密度,如果是均等密度的垂直切饼,

每部分重量g = 总G * 其占大圆比例! 类比地,如果划分后信息熵一样, 每个小部分数据的 小h = pro * 总 H, 而 求和 h[i] = H.

然而:我们需要的恰恰相反:需要的不是信息熵一样,而是不均等,比如上面,上绿的可能是草每馅,黄色是苹果馅,蓝色是紫薯,每个密度不同!

我们需要把它正确划分!分类出来,找出逼近不同馅之间的那条线。 这里的 小h会最小化,而最终在面积不变下,总H会 逼近最小值,是最优化问题求解。

调试过程

calcShannonEnt : [[1, 'no'], [1, 'no']]= 0 log(1,2) * 0.4 = 0为什么是0,因为pro必然是1

log(prob,2) log(1,2) = 0;2^0=1,因为 prob <=1,所以 log(Value,2) <0

: [[1, 'yes'], [1, 'yes'], [0, 'no']]=0.91>> * 0.6 = 0.55

25行 for featVec in dataSet: 计频for prop

chooseBestFeatureToSplit()

0.9709505944546686 = calcShannonEnt(dataSet): [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]

#检测数据集的每个子项是否属于同一类: 如果值都是a,而result都是y或n 则为一类 所以,只是两个参数输入

0.5509775004326937= += prob * calcShannonEnt(subDataSet) 分开的子集后,的概率*香农滴,得到的和,原来的整体的香浓滴比# 数据越接近,香浓熵值越少,越接近0 ,越不同,越多分逻辑,香浓熵就越大

# 只计算 其dataSet的featVec[-1] 结果标签

def calcShannonEnt(dataSet):

0.4199730940219749 infoGain = baseEntropy - newEntropy

总结:

一开始,看代码看不懂,不明白到底是要做什么!分类,我们的目标是把一堆数据分类,以label来标签上。

像k邻近classify([0, 0], group, labels, 3)意思是,把新数据[0,0] 按k=3的邻近算法在 group,labels数据里的分类!group与label对应!

后面看到了

5bfe0163a4b590621a412f234993fb76.png

才理解,数据dataSet 的意思是条个维度的值而最后一个是 是否为 fish的,结果标签

所以,是要把每个维度 切出来 + 结果标签成二维的一列数组,去比较分类

测试应该是,把前n个维量的值,向量输入,输出是yes or no!

一开始看,比较头晕,条理清楚,理顺下思路,看代码才易懂!

理解了目标和初始数据,你才明白,原来classList是结果标签!,是对应将要分类的dataset的对应结果标签

而labels 则是 特征名,对应开始的dataset的维度,特征的名strname

bestFeatLabel最好分类特征的维度名是第一维度还是第二,第N

featValues是bestFeatLabel 的维度下,的值数组。就是这一维度下的组用来做新的分类比较。

uniqueVals用set判断来是否一类,

比如

dataSet = [[1, 1, 'yes'],[0, 1, 'yes'],[1, 0, 'no'],[1, 0, 'no'],[0, 0, 'no']]

labels = ['no surfacing','flippers',]

这样的createTree:{'flippers': {0: 'no', 1: 'yes'}}直接把no surfacing的维度省略了

最后,再用一段话来讲讲决策树:

决策树本质上:是加快效率!用‘最大最优’划分 第一个否定标签,而肯定标签要继续划分!而否定,直接返回叶结点答案!而对应的其它维度就不继续判断!

理论上,即使不用决策树算法,就盲目穷举,就是每次都把数据所有维度轮一次!而有最后个标签答案!维度数*数据个数!为复杂度!这是对记忆的匹配回答!合适专家系统! 预测未出现的情况能力差!但数据量大,速度快,也能有智能的感觉!因为是对过去经验的重演!然而它是死的?不,它不是死的!穷举是死的,但决策树是动态的! 学习的!变化树!至少它的建成是动态的!当数据不完全时,它也可能是不完全的!当一个判断可以解决就用一个判断,不能就再需要一个!维度增加!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值