python怎么实现决策树建模


这篇文章主要介绍“python怎么实现决策树建模”,在日常操作中,相信很多人在python怎么实现决策树建模问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python怎么实现决策树建模”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!决策树是一种简单的机器学习方法。决策树经过训练之后,看起来像是以树状形式排列的一系列if-then语句。一旦我们有了决策树,只要沿着树的路径一直向下,正确回答每一个问题,最终就会得到答案。沿着最终的叶节点向上回溯,就会得到一个有关最终分类结果的推理过程。决策树:下面利用分类回归树的算法。为了构造决策树,算法首先创建一个根节点,然后评估表中的所有观测变量,从中选出最合适的变量对数据进行拆分。为了选择合适的变量,我们需要一种方法来衡量数据集合中各种因素的混合情况。对于混杂程度的测度,有几种度量方式可供选择:基尼不纯度:将来自集合中的某种结果随机应用于集合中某一数据项的预期误差率。下面是python实现:123456789101112131415161718192021defuniquecounts(rows):results={}forrow inrows:# The result is the last columnr=row[len(row)-1]ifr notinresults: results[r]=0results[r]+=1returnresultsdefginiimpurity(rows):total=len(rows)counts=uniquecounts(rows)imp=0fork1 incounts:p1=float(counts[k1])/total#imp+=p1*p1fork2 incounts:ifk1==k2: continuep2=float(counts[k2])/totalimp+=p1*p2returnimp#1-imp《集》中的实现:12345678910defentropy(rows):frommath importloglog2=lambdax:log(x)/log(2)results=uniquecounts(rows)# Now calculate the entropyent=0.0forr inresults.keys():p=float(results[r])/len(rows)ent=ent-p*log2(p)returnent熵和基尼不纯度之间的主要区别在于,熵达到峰值的过程要相对慢一些。因此,熵对于混乱集合的判罚要更重一些。我们的算法首先求出整个群组的熵,然后尝试利用每个属性的可能取值对群组进行拆分,并求出两个新群组的熵。算法会计算相应的信息增益。信息增益是指当前熵与两个新群组经加权平均后的熵之间的差值。算法会对每个属性计算相应的信息增益,然后从中选出信息增益最大的属性。通过计算每个新生节点的最佳拆分属性,对分支的拆分过程和树的构造过程会不断持续下去。当拆分某个节点所得的信息增益不大于0的时候,对分支的拆分才会停止:123456789101112131415161718192021222324252627282930313233343536defbuildtree(rows,scoref=entropy):iflen(rows)==0: returndecisionnode()current_score=scoref(rows)# Set up some variables to track the best criteriabest_gain=0.0best_criteria=Nonebest_sets=Nonecolumn_count=len(rows[0])-1forcol inrange(0,column_count):# Generate the list of different values in# this columncolumn_values={}forrow inrows:column_values[row[col]]=1# Now try dividing the rows up for each value# in this columnforvalue incolumn_values.keys():(set1,set2)=divideset(rows,col,value)# Information gainp=float(len(免费云主机域名set1))/len(rows)gain=current_score-p*scoref(set1)-(1-p)*scoref(set2)ifgain>best_gain andlen(set1)>0andlen(set2)>0:best_gain=gainbest_criteria=(col,value)best_sets=(set1,set2)# Create the sub branchesifbest_gain>0:trueBranch=buildtree(best_sets[0])falseBranch=buildtree(best_sets[1])returndecisionnode(col=best_criteria[0],value=best_criteria[1],tb=trueBranch,fb=falseBranch)else:returndecisionnode(results=uniquecounts(rows))函数首先接受一个由数据行构成的列表作为参数。它遍历了数据集中的每一列,针对各列查找每一种可能的取值,并将数据集拆分成两个新的子集。通过将每个子集的熵乘以子集中所含数据项在元数据集中所占的比重,函数求出了每一对新生子集的甲醛平均熵,并记录下熵最低的那一对子集。如果由熵值最低的一对子集求得的加权平均熵比当前集合的当前集合的熵要大,则拆分结束了,针对各种可能结果的计数所得将会被保存起来。否则,算法会在新生成的子集继续调用buildtree函数,并把调用所得的结果添加到树上。我们把针对每个子集的调用结果,分别附加到节点的True分支和False分支上,最终整棵树就这样构造出来了。我们可以把它打印出来:12345678910111213defprinttree(tree,indent=”):# Is this a leaf node?iftree.results!=None:printstr(tree.results)else:# Print the criteriaprintstr(tree.col)+’:’+str(tree.value)+’? ‘# Print the branchesprintindent+’T->’,printtree(tree.tb,indent+’ ‘)printindent+’F->’,printtree(tree.fb,indent+’ ‘)现在到我们使用决策树的时候了。接受新的观测数据作为参数,然后根据决策树对其分类:?12345678910111213defclassify(observation,tree):iftree.results!=None:returntree.resultselse:v=observation[tree.col]branch=Noneifisinstance(v,int) orisinstance(v,float):ifv>=tree.value: branch=tree.tbelse: branch=tree.fbelse:ifv==tree.value: branch=tree.tbelse: branch=tree.fbreturnclassify(observation,branch)该函数采用与printtree相同的方式对树进行遍历。每次调用后,函数会根据调用结果来判断是否到达分支的末端。如果尚未到达末端,它会对观测数据评估,以确认列数据是否与参考值匹配。如果匹配,则会在True分支调用classify,不匹配则在False分支调用classify。上面方法训练决策树会有一个问题:过度拟合:它可能会变得过于针对训练数据,其熵值与真实情况相比可能会有所降低。剪枝的过程就是对具有相同父节点的一组节点进行检查,判断如果将其合并,熵的增加量是否会小于某个指定的阈值。如果确实如此,则这些叶节点会被合并成一个单一的节点,合并后的新节点包含了所有可能的结果值。这种做法有助于过度避免过度拟合的情况,使得决策树做出的预测结果,不至于比从数据集中得到的实际结论还要特殊:1234567891011121314151617181920212223defprune(tree,mingain):# 如果分支不是叶节点,则对其进行剪枝操作iftree.tb.results==None:prune(tree.tb,mingain)iftree.fb.results==None:prune(tree.fb,mingain)# 如果两个分支都是叶节点,则判断它们是否需要合并iftree.tb.results!=Noneandtree.fb.results!=None:# 构造合并后的数据集tb,fb=[],[]forv,c intree.tb.results.items():tb+=[[v]]*cforv,c intree.fb.results.items():fb+=[[v]]*c# 检查熵的减少情况delta=entropy(tb+fb)-(entropy(tb)+entropy(fb)/2)ifdelta

# 合并分支

tree.tb,tree.fb=None,None

tree.results=uniquecounts(tb+fb)

# 合并分支tree.tb,tree.fb=None,Nonetree.results=uniquecounts(tb+fb)当我们在根节点调用上述函数时,算法将沿着树的所有路径向下遍历到只包含叶节点的节点处。函数会将两个叶节点中的结果值合起来形成一个新的列表,同时还会对熵进行测试。如果熵的变化小于mingain参数指定的值,则叶节点也可能成为删除对象,以及与其它节点的合并对象。如果我们缺失了某些数据,而这些数据是确定分支走向所必需的,那么我们可以选择两个分支都走。在一棵基本的决策树中,所有节点都隐含有一个值为1的权重,即观测数据项是否属于某个特定分类的概率具有百分之百的影响。而如果要走多个分支的话,那么我们可以给每个分支赋以一个权重,其值等于所有位于该分支的其它数据行所占的比重:1234567891011121314151617181920212223defmdclassify(observation,tree):iftree.results!=None:returntree.resultselse:v=observation[tree.col]ifv==None:tr,fr=mdclassify(observation,tree.tb),mdclassify(observation,tree.fb)tcount=sum(tr.values())fcount=sum(fr.values())tw=float(tcount)/(tcount+fcount)fw=float(fcount)/(tcount+fcount)result={}fork,v intr.items(): result[k]=v*twfork,v infr.items(): result[k]=v*fwreturnresultelse:ifisinstance(v,int) orisinstance(v,float):ifv>=tree.value: branch=tree.tbelse: branch=tree.fbelse:ifv==tree.value: branch=tree.tbelse: branch=tree.fbreturnmdclassify(observation,branch)mdclassify与classify相比,唯一的区别在于末尾处:如果发现有重要数据缺失,则每个分支的对应结果值都会被计算一遍,并且最终的结果值会乘以它们各自的权重。对与数值型问题,我们可以使用方差作为评价函数来取代熵或基尼不纯度。偏低的方差代表数字彼此都非常接近,而偏高的方差则意味着数字分散得很开。这样,选择节点判断条件的依据就变成了拆分后令数字较大者位于树的一侧,数字较小者位于树的另一侧。到此,关于“python怎么实现决策树建模”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注百云主机网站,小编会继续努力为大家带来更多实用的文章!

相关推荐: React怎么实现单向数据流

这篇文章主要讲解了“React怎么实现单向数据流”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React怎么实现单向数据流”吧!React单向数据流的设计,是React开发人员所推崇的一种设计思想。在这种模式下…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 07/28 13:21
下一篇 07/28 13:21

相关推荐