机器学习实战ch03

3.1.1

>>>a="qwe"

>>> a[-1]

'e'

列表的最后一位是-1.

>>>import trees

之后在Python的console中就可以使用trees.py中的函数了。

>>> lc={}

>>>lc["no"]=0

>>>lc['yes']=3

>>> lc

{'yes': 3, 'no':0}

>>>lc.keys()

['yes', 'no']

>>>lc.values()

[3, 0]

一个简单的例子,字典lc由key和value组成。这里,key是'no'和'yes',value分别是0和3。

>>> 'yes'in lc.keys()

True

>>> 'mo'in lc.keys()

False

可以用keys()函数检测字典中有什么样的key。

>>>float(lc['no'])

0.0

>>>float(lc['yes'])

3.0

根据 key得到相应的value,并且将value转化成float形式。

>>>mydata

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

>>>trees.calcShannonEnt(mydata)

0.9709505944546686

在这个函数中会新建一个字典labelCounts = {},输入mydata经过计算后,该字典中的key是’'yes'和'no',相应的value是2和3.求出每种key发生的频率,求对数后,可以得到相应的熵。

3.1.2

>>>a=[0,1,2,3,4,5]

>>>b=a[:2]

>>> b

[0, 1]

b包含的列表的前面两个数。

>>>c=a[3:]

>>> c

[3, 4, 5]

c包含了列表的从第3个数开始到最后一个数(开头的是第0个数)。

>>>b.extend(c)

>>> b

[0, 1, 3, 4, 5]

把c中的元素加到b中,b比a少了第2个数。

>>>d=b.extend(c)

>>> d

错误用法,d显示为空。

>>>b.append(c)

>>> b

[0, 1, 3, 4, 5,[3, 4, 5]]

跟上面对比可以看出,extend是把列表中的元素一个个加进去,append是将列表整个加进去。

>>>mydata

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

>>>d=[a[0] for a in mydata]

>>> d

[1, 1, 1, 0, 0]

>>>set(d)

set([0, 1])

>>>e=set(d)

>>> e

set([0, 1])

>>> y=[ vfor v in e]

>>> y

[0, 1]

可以用这些函数将mydata中5条数据中的第0个元素提取出来,然后看第0个元素有多少种类,组成一个集合。

>>>trees.chooseBestFeatureToSplit(mydata)

0

这个函数先将mydata根据每条数据中的第0个元素的分类(第0个元素是1)形成一个新的子集[[1, 'yes'], [1, 'yes'], [ 0, 'no']],根据'yes'和'no'计算该子集的熵,乘以3/5的比例后加到newEntropy中,然后再根据第0个元素的分类(第0个元素是0)形成一个新的子集[ [1, 'no'], [1, 'no']], 根据'yes'和'no'计算该子集的熵,乘以2/5的比例后加到newEntropy中。同样原理可以将mydata根据每条数据中的第1个元素的分类得到相应的newEntropy。该函数等效于比较newEntropy的大小,根据第i个元素得到的newEntropy小,就把bestFeature改成i。

3.13

>>>mytree=trees.createTree(mydata,label)

>>>mytree

{'no surfacing':{0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

这个函数的输入是mydata和label,返回的是包含了很多代表树结构信息的嵌套字典。当进入函数,但还没有进入 for value in uniqueVals:循环前,mytree={'no surfacing': {}}。 uniqueVals是一个有0和1的set,由数据集中的第0个元素得到。

>>>mytree['no surfacing']

{}

mytree['nosurfacing']是一个空的字典

mytree['nosurfacing'][0]

这相当于在空字典中新建一个名称为0的key,而创建与该key对应的value则需要再一次进入 createTree()函数。这次输入的数据集是:[[1, 'no'], [1, 'no']]

>>>trees.splitDataSet(mydata,0,0)

[[1, 'no'], [1,'no']]

由于输入数据集的两个数据最后一个元素类别完全相同,都是'no',所以,直接返回'no'。这时mytree={'no surfacing': {0: 'no'}}。

      然后运行mytree['no surfacing'][1],相当于在嵌套的字典中再新建一个名称为1的key,与前面那个名称为0的key并列。而创建与该key对应的value则需要再一次进入 createTree()函数。这次输入的数据集是:[[1, 'yes'], [1, 'yes'], [0, 'no']]

>>>trees.splitDataSet(mydata,0,1)

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

      接下来又会新建一个字典,假设是 mytree2={'flippers': {}}。

      然后进入for value in uniqueVals:循环, uniqueVals是一个有0和1的set,由数据集中的第1个元素得到。在空字典中新建一个名称为0的key,而创建与该key对应的value则需要再一次进入 createTree()函数。这次输入的数据集是:[['no']]

>>>b=trees.splitDataSet(mydata,0,1)

>>> b

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

>>>trees.splitDataSet(b,0,0)

[['no']]

所以返回的是'no'。这时mytree2={'flippers': {0:'no'}}

      接下去在字典中新建一个名称为1的key,而创建与该key对应的value则需要再一次进入 createTree()函数。这次输入的数据集是:[['yes'], ['yes']]

>>>trees.splitDataSet(b,0,1)

[['yes'], ['yes']]

所以返回的是'yes'。这时mytree2={'flippers': {0: 'no', 1: 'yes'}}.

      跳出for value in uniqueVals:循环,返还mytree2。这时mytree={'no surfacing': {0: 'no', 1: {'flippers':{0: 'no', 1: 'yes'}}}}

      最后跳出前面一个for value in uniqueVals:循环,返还mytree。

3.2.1

      Linux系统中没有自己安装matplotlib。所以要在linux命令行中输入:

sudo apt-getinstall python-matplotlib

>>>dict(p='pig',d='dog')

{'p': 'pig', 'd':'dog'}

>>>dict(p="pig",d="dog")

{'p': 'pig', 'd': 'dog'}

dict函数用于构造字典,双引号和单引号效果一样。

在官方给的例程中有两个createPlot(),但是把3.2.1中的createPlot()函数用#号屏蔽掉了,把多个#号删除,并且把那个createPlot()改成createPlot2()。输入下面命令:

>>>reload(treePlotter)

<module'treePlotter' from 'treePlotter.py'>

>>>treePlotter.createPlot2()

可以得到书中图3-5的图像。

      plotNode()函数中nodeTxt指的是要在图中打印的文字,xy是箭头起始的座标,xytext是文字的位置。axes fraction指的是座标的值是从0到1的。arrowstyle="<-"指的是箭头是指向文字的,bbox是包装文字的盒子,有圆润的和锯齿形两种。

      createPlot()函数中的createPlot.ax1是全局变量,所以该函数中调用的plotNode函数也可以对createPlot.ax1进行修改。

      getNumLeafs()函数中myTree.keys()[0]指的是myTree字典中第0个key,也就是'no surfacing'。secondDict是{0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}。然后进入循环for key in secondDict.keys():。secondDict里面有两个key,当key等于0时,所对应的secondDict[key]不是字典,所以进入else语句,此时numLeafs==1。当key==1时,所对应的secondDict[key]不是字典,所以又进入getNumLeafs函数中(为了与前面的区分,假设为getNumLeafs2),输入的字典为{'flippers': {0: 'no', 1: 'yes'}},输入字典的value中没有字典了,返还numLeafs(为了与前面的区分,假设为NumLeafs2),numLeafs2=2。跳出getNumLeafs2函数,此时numLeafs==3,返还numLeafs,跳出getNumLeafs函数。

      getTreeDepth()函数与前面一个函数大致一样,不一样的是在if type(secondDict[key]).__name__=='dict':语句后thisDepth至少是1,如果不是字典,那么thisDepth就是1。

      plotTree()函数的输入是myTree,parentPt,nodeText。当createPlot函数调用该函数时,myTree=={'no surfacing': {0: 'no', 1: {'flippers': {0:'no', 1: 'yes'}}}},parentPt==(0.5,1.0),nodeText==‘ ’。进入函数后firstStr='no surfacing',plotTree()函数中的cntrPt是用来计算当前决策节点的位置。假设现在的 plotTree.xOff记为x(也就是上一个叶节点的x轴位置),总的叶节点plotTree.totalW为N,输入myTree的叶节点numLeafs为n。那么当前决策节点下面的叶节点x轴就是(x+1/N, x+2/N.............x+n/N),那么决策节点的x轴位置应该是 x+1/N和 x+n/N的中间,也就是[2x+(1+n)/N]/2,y轴位置不变。cntrPt==(0.5,1.0),接下来的两个函数plotNode()和plotMidText()就画了一个位于(0.5,1)的决策节点。接下来plotTree.yOff=0.5。secondDict=={0: 'no', 1: {'flippers': {0: 'no', 1:'yes'}}}。接下去的for循环。首先key==0,进入else语句,plotTree.xOff变成了0.5/3,于是plotNode()在(plotTree.xOff,plotTree.yOff)即(0.5/3,0.5)画了一个no的叶节点,plotMidText()在cntrPt和(plotTree.xOff,plotTree.yOff)中间写上key的名称0。接着key==1,进入if语句,进入循环(假设是plotTree2()),输入是myTree== {'flippers': {0: 'no', 1: 'yes'}},parentPt==(0.5,1.0),nodeText==‘ 1’。接下来,cntrPt变成了(2/3,0.5),然后从 parentPt到cntrPt画了一个箭头到决策节点,中间标上 nodeText,secondDict 变成{0: 'no', 1: 'yes'},plotTree.yOff变成0。接下来进入for循环,由于 secondDict中没有字典,所以循环的两次都有进入else语句。当key==0时,从cntrPt到(plotTree.xOff,plotTree.yOff)==(1.5/3,0)处画箭头到叶节点,中间表上str(key)。当key==1时,从cntrPt到(plotTree.xOff,plotTree.yOff)==(2.5/3,0)处画箭头到叶节点,中间表上str(key)。跳出plotTree2(),接着再跳出plotTree()。

3.4

>>>ar=open('lenses.txt')

>>>a=ar.readlines()

>>> a

['young\tmyope\tno\treduced\tnolenses\r\n', 'young\tmyope\tno\tnormal\tsoft\r\n','young\tmyope\tyes\treduced\tno lenses\r\n', 'young\tmyope\tyes\tnormal\thard\r\n','young\thyper\tno\treduced\tno lenses\r\n','young\thyper\tno\tnormal\tsoft\r\n', 'young\thyper\tyes\treduced\tnolenses\r\n', 'young\thyper\tyes\tnormal\thard\r\n','pre\tmyope\tno\treduced\tno lenses\r\n', 'pre\tmyope\tno\tnormal\tsoft\r\n','pre\tmyope\tyes\treduced\tno lenses\r\n', 'pre\tmyope\tyes\tnormal\thard\r\n','pre\thyper\tno\treduced\tno lenses\r\n', 'pre\thyper\tno\tnormal\tsoft\r\n','pre\thyper\tyes\treduced\tno lenses\r\n', 'pre\thyper\tyes\tnormal\tnolenses\r\n', 'presbyopic\tmyope\tno\treduced\tno lenses\r\n','presbyopic\tmyope\tno\tnormal\tno lenses\r\n','presbyopic\tmyope\tyes\treduced\tno lenses\r\n','presbyopic\tmyope\tyes\tnormal\thard\r\n', 'presbyopic\thyper\tno\treduced\tnolenses\r\n', 'presbyopic\thyper\tno\tnormal\tsoft\r\n','presbyopic\thyper\tyes\treduced\tno lenses\r\n','presbyopic\thyper\tyes\tnormal\tno lenses\r\n']

>>> a[0]

'young\tmyope\tno\treduced\tnolenses\r\n'

>>>a[0].strip()

'young\tmyope\tno\treduced\tnolenses'

>>>a[0].strip().split('\t')

['young', 'myope','no', 'reduced', 'no lenses']

 

 

>>>fr=open('lenses.txt')

>>> fr

<open file'lenses.txt', mode 'r' at 0x7f5600bf6660>

>>>lenses=[inst.strip().split('\t') for inst in fr.readlines()]

>>>lenses

[['young','myope', 'no', 'reduced', 'no lenses'], ['young', 'myope', 'no', 'normal','soft'], ['young', 'myope', 'yes', 'reduced', 'no lenses'], ['young', 'myope','yes', 'normal', 'hard'], ['young', 'hyper', 'no', 'reduced', 'no lenses'],['young', 'hyper', 'no', 'normal', 'soft'], ['young', 'hyper', 'yes','reduced', 'no lenses'], ['young', 'hyper', 'yes', 'normal', 'hard'], ['pre','myope', 'no', 'reduced', 'no lenses'], ['pre', 'myope', 'no', 'normal','soft'], ['pre', 'myope', 'yes', 'reduced', 'no lenses'], ['pre', 'myope','yes', 'normal', 'hard'], ['pre', 'hyper', 'no', 'reduced', 'no lenses'],['pre', 'hyper', 'no', 'normal', 'soft'], ['pre', 'hyper', 'yes', 'reduced','no lenses'], ['pre', 'hyper', 'yes', 'normal', 'no lenses'], ['presbyopic','myope', 'no', 'reduced', 'no lenses'], ['presbyopic', 'myope', 'no', 'normal','no lenses'], ['presbyopic', 'myope', 'yes', 'reduced', 'no lenses'],['presbyopic', 'myope', 'yes', 'normal', 'hard'], ['presbyopic', 'hyper', 'no','reduced', 'no lenses'], ['presbyopic', 'hyper', 'no', 'normal', 'soft'],['presbyopic', 'hyper', 'yes', 'reduced', 'no lenses'], ['presbyopic', 'hyper','yes', 'normal', 'no lenses']]

>>>lensesTree=trees.createTree(lenses,lensesLabels)

>>>treePlotter.createPlot(lensesTree)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章