集体智慧编程——决策树建模(下)

一、决策树的显示:

前面我们已经得到了一棵决策树,下一步也许我们该进行数的浏览了。下面这段函数就是一个以纯文本的方式显示决策树的方法,虽然输出不是很美观,但是对于显示节点不是太多的树而言,这也是一种简单的方式。

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}

至此,一棵完整的决策树我们就构造出来了。

参考自《集体智慧编程》

 

posted on 2015-12-05 19:40  波比12  阅读(969)  评论(0编辑  收藏  举报

导航