集体智慧编程——决策树建模(下)
一、决策树的显示:
前面我们已经得到了一棵决策树,下一步也许我们该进行数的浏览了。下面这段函数就是一个以纯文本的方式显示决策树的方法,虽然输出不是很美观,但是对于显示节点不是太多的树而言,这也是一种简单的方式。
def printtree(tree,indent=''): if tree.results!=None: print str(tree.results) else: print str(tree.col)+':'+str(tree.value)+'?' print indent+'T->' printtree(tree.tb,indent+' ') print indent+'F->' printtree(tree.fb,indent+' ')
这也是一个递归函数,接受buildtree返回的树作为参数,递归的显示出该树。
我们队前面构造好的树调用该函数,得到结果为:
>>> treepredict.printtree(tr) 0:google? T-> 3:21? T-> {'Premium': 3} F-> 2:yes? T-> {'Basic': 1} F-> {'None': 1} F-> 0:slashdot? T-> {'None': 3} F-> 2:yes? T-> {'Basic': 4} F-> 3:21? T-> {'Basic': 1} F-> {'None': 3}
图形显示方式:
对于节点不是特别多的树来说文本显示的方式是可行的,但是随着树的规模越来越大,我们需要用图形方式显示比较合适。
为了将树真正绘制出来,我们还需要安装Python Imageing Library。请从www.pythonware.com处下载该库。
安装完成后请将下列import语句添加到treepredict.py文件
from PIL import Image,ImageDraw
图形显示方式函数:
def getwidth(tree): if tree.tb==None and tree.fb==None:return 1 return getwidth(tree.tb)+getwidth(tree.fb) def getdepth(tree): if tree.tb==None and tree.fb==None:return 0 return max(getdepth(tree.tb),getdepth(tree.fb))+1 def drawtree(tree,jpeg='tree.jpg'): w=getwidth(tree)*100 h=getdepth(tree)*100+120 img=Image.new('RGB',(w,h),(255,255,255)) draw=ImageDraw.Draw(img) drawnode(draw,tree,w/2,20) img.save(jpeg,'JPEG') def drawnode(draw,tree,x,y): if tree.results==None: # Get the width of each branch w1=getwidth(tree.fb)*100 w2=getwidth(tree.tb)*100 # Determine the total space required by this node left=x-(w1+w2)/2 right=x+(w1+w2)/2 # Draw the condition string draw.text((x-20,y-10),str(tree.col)+':'+str(tree.value),(0,0,0)) # Draw links to the branches draw.line((x,y,left+w1/2,y+100),fill=(255,0,0)) draw.line((x,y,right-w2/2,y+100),fill=(255,0,0)) # Draw the branch nodes drawnode(draw,tree.fb,left+w1/2,y+100) drawnode(draw,tree.tb,right-w2/2,y+100) else: txt=' \n'.join(['%s:%d'%v for v in tree.results.items()]) draw.text((x-20,y),txt,(0,0,0))
现在,我们就可以尝试将决策树绘制出来了:
>>> reload(treepredict) <module 'treepredict' from 'treepredict.pyc'> >>> treepredict.drawtree(tr,jpeg='tree.jpg')
我们就会在python文件夹下发现一个名为‘tree.jpg’的文件,如下图示:
即为该决策树。
二:对新的观测数据进行分类:
def classify(observation,tree): if tree.results!=None: #is not a leafnode return tree.results else: v=observation[tree.col] branch=None if isinstance(v,int) or isinstance(v,float): if v>=tree.value: branch=tree.tb else: branch=tree.fb else: if v==tree.value: branch=tree.tb else: branch=tree.fb return classify(observation,branch)
现在我们就可以调用classify函数对新观测的数据进行分类了:
>>> reload(treepredict) <module 'treepredict' from 'treepredict.pyc'> >>> treepredict.classify(['(direct)','USA','yes',5],tr) {'Basic': 4}
至此,一棵完整的决策树我们就构造出来了。
参考自《集体智慧编程》