蜜桃av色欲a片精品一区,麻豆aⅴ精品无码一区二区,亚洲人成网站在线播放影院在线,亚洲 素人 字幕 在线 最新

微立頂科技

新聞資訊

創(chuàng)新 服務(wù) 價(jià)值

  機(jī)器學(xué)習(xí)實(shí)戰(zhàn)——決策樹(shù)

發(fā)布日期:2022/10/21 10:18:21      瀏覽量:

1.決策樹(shù)的構(gòu)造

1.1優(yōu)缺點(diǎn)

優(yōu)點(diǎn):
  • 計(jì)算復(fù)雜度不高:以ID3為例,每次運(yùn)算都是基于某一列特征,特征計(jì)算完后,下次計(jì)算不考慮該最有特征,并且通過(guò)適當(dāng)剪枝可以簡(jiǎn)化復(fù)雜度

  • 輸出結(jié)果易于理解:因?yàn)檩敵龅氖且粋€(gè)樹(shù)的結(jié)構(gòu),樹(shù)的走向一目了然

  • 對(duì)中間值的缺失不敏感

  • 可以處理不相關(guān)特 征數(shù)據(jù):是基于每列特征來(lái)計(jì)算,不考慮特征之間的依賴關(guān)系

缺點(diǎn):可能會(huì)產(chǎn)生過(guò)度匹配問(wèn)題。
適用數(shù)據(jù)類型:數(shù)值型和標(biāo)稱型。

1.2信息熵

主要用來(lái)度量信息的混亂程度,信息越混亂,說(shuō)明能夠包含的信息量越多,則熵越大。反之若信息越有序說(shuō)明包含的信息量越少,則熵越小。

1.3信息增益

標(biāo)準(zhǔn)的說(shuō)法就是:一個(gè)隨機(jī)變量的引入導(dǎo)致了另一個(gè)隨機(jī)變量的混亂性變化(約束),如果約束越大,信息增益就越大。舉個(gè)通俗易懂的例子就是:比如你去銀行貸款,如果你自己的個(gè)人信息你對(duì)貸款員什么都不說(shuō),那貸款員是不是就很不確定是否貸款給你,如果你只說(shuō)了你的薪資,那較之前相比,貸款員是否給你貸款是不是就多了一種判斷的依據(jù),也就是說(shuō),你告訴貸款員你的個(gè)人信息越多,貸款員是否給你貸款就越確定,此時(shí)的信息增益也就是最大。在舉一個(gè)例子:了解一個(gè)人的信息,如果給一個(gè)身份證號(hào),由于每個(gè)人的身份證號(hào)都是唯一的,所以一個(gè)身份證號(hào)就可以判斷這個(gè)的所有信息,也就是引入身份證號(hào)這個(gè)屬性之后,就會(huì)唯一確定一個(gè)人,這時(shí)身份證號(hào)對(duì)判斷這個(gè)人的約束是最大,信息增益也就是最大。

2.決策樹(shù)的構(gòu)造

2.1熵的計(jì)算

數(shù)據(jù)集:

根據(jù)表中的數(shù)據(jù)統(tǒng)計(jì)可知,在15個(gè)數(shù)據(jù)中,9個(gè)數(shù)據(jù)的結(jié)果為放貸,6個(gè)數(shù)據(jù)的結(jié)果為不放貸。所以數(shù)據(jù)集D的經(jīng)驗(yàn)熵H(D)為:

def calcShannonEnt(dataSet):
    numEntires = len(dataSet) #返回?cái)?shù)據(jù)集的行數(shù) labelCounts = {} #保存每個(gè)標(biāo)簽(Label)出現(xiàn)次數(shù)的字典 for featVec in dataSet: #featVec代表一行一行的數(shù)據(jù)   #對(duì)每組特征向量進(jìn)行統(tǒng)計(jì) currentLabel = featVec[-1] #取每一行的最后一列也即是否貸款的值 if currentLabel not in labelCounts.keys(): #如果標(biāo)簽(Label)沒(méi)有放入統(tǒng)計(jì)次數(shù)的字典,添加進(jìn)去 labelCounts[currentLabel] = 0#鍵對(duì)應(yīng)的值設(shè)為零 labelCounts[currentLabel] += 1 #鍵對(duì)應(yīng)的值加一 shannonEnt = 0.0 #經(jīng)驗(yàn)熵(香農(nóng)熵) for key in labelCounts: #計(jì)算香農(nóng)熵 prob = float(labelCounts[key]) / numEntires #選擇該標(biāo)簽(Label)的概率 shannonEnt -= prob * log(prob, 2) #利用公式計(jì)算 return shannonEnt def createDataSet(): #年齡:0代表青年,1代表中年,2代表老年 #信貸情況:0代表一般,1代表好,2代表非常好 dataSet = [[0, 0, 0, 0, ’no’], # 數(shù)據(jù)集 [0, 0, 0, 1, ’no’],
               [0, 1, 0, 1, ’yes’],
               [0, 1, 1, 0, ’yes’],
               [0, 0, 0, 0, ’no’],
               [1, 0, 0, 0, ’no’],
               [1, 0, 0, 1, ’no’],
               [1, 1, 1, 1, ’yes’],
               [1, 0, 1, 2, ’yes’],
               [1, 0, 1, 2, ’yes’],
               [2, 0, 1, 2, ’yes’],
               [2, 0, 1, 1, ’yes’],
               [2, 1, 0, 1, ’yes’],
               [2, 1, 0, 2, ’yes’],
               [2, 0, 0, 0, ’no’]]
    labels = [’年齡’, ’有工作’, ’有自己的房子’, ’信貸情況’] # 特征標(biāo)簽 return dataSet, labels # 返回?cái)?shù)據(jù)集和分類屬性 myDat,labels=createDataSet() print(myDat) print(calcShannonEnt(myDat))

測(cè)試結(jié)果:

2.2劃分?jǐn)?shù)據(jù)集

2.2.1按照給定特征劃分?jǐn)?shù)據(jù)集

#三個(gè)輸入?yún)?shù):待劃分的數(shù)據(jù)集、劃分?jǐn)?shù)據(jù)集的特征、需要返回的特征的值 def splitDataSet(dataSet, axis, value):
    retDataSet = [] #創(chuàng)建返回的數(shù)據(jù)集列表 for featVec in dataSet: #遍歷數(shù)據(jù)集 if featVec[axis] == value:
            reducedFeatVec = featVec[:axis] #去掉axis特征 reducedFeatVec.extend(featVec[axis+1:]) #將符合條件的添加到返回的數(shù)據(jù)集 retDataSet.append(reducedFeatVec) return retDataSet #返回劃分后的數(shù)據(jù)集 

上面代碼的解釋,假設(shè)axis=0,value=1,表示的是在第一列年齡的屬性中,找到值為1(也即為中年)的所有行,然后去掉每一行中第一列的數(shù)據(jù)(其實(shí)很多余,因?yàn)樵谒沆氐臅r(shí)候只取最后一列的數(shù)據(jù)),然后每一行的剩余列的數(shù)據(jù)保存

以添加年齡之后算此時(shí)是否貸款的信息增益的方法如下圖:

2.2.2選擇最好的數(shù)據(jù)集劃分方式

代碼實(shí)現(xiàn):
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1 #特征數(shù)量 baseEntropy = calcShannonEnt(dataSet) #計(jì)算數(shù)據(jù)集的香農(nóng)熵 bestInfoGain = 0.0 #信息增益 bestFeature = -1 #最優(yōu)特征的索引值 for i in range(numFeatures): #遍歷所有特征 #獲取dataSet的第i個(gè)所有特征-第i列全部的值 featList = [example[i] for example in dataSet]
        uniqueVals = set(featList) #創(chuàng)建set集合{},元素不可重復(fù) newEntropy = 0.0 #經(jīng)驗(yàn)條件熵 for value in uniqueVals: #計(jì)算信息增益 subDataSet = splitDataSet(dataSet, i, value) #subDataSet劃分后的子集 prob = len(subDataSet) / float(len(dataSet)) #計(jì)算子集的概率如上圖的p(youth),p(middle),p(old)的值 newEntropy += prob * calcShannonEnt(subDataSet) #根據(jù)公式計(jì)算經(jīng)驗(yàn)條件熵 infoGain = baseEntropy - newEntropy #信息增益=h(D)-h(D|A) # print("第%d個(gè)特征的增益為%.3f" % (i, infoGain))            #打印每個(gè)特征的信息增益 if (infoGain > bestInfoGain): #取出信息增益的最大值                            #計(jì)算信息增益 bestInfoGain = infoGain #更新信息增益,找到最大的信息增益 bestFeature = i #記錄信息增益最大的特征的索引值 return bestFeature

2.3遞歸構(gòu)建決策樹(shù)

#當(dāng)所有的特征及屬性都遍歷完成之后任然不能確定是否貸款 #此時(shí)可根據(jù)classlist中是否貸款各自的數(shù)量,取最大票數(shù)的即可 def majorityCnt(classList):
    classCount = {} for vote in classList: #統(tǒng)計(jì)classList中每個(gè)元素出現(xiàn)的次數(shù) if vote not in classCount.keys():
            classCount[vote] = 0 classCount[vote] += 1 sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True) #根據(jù)字典的值降序排序 return sortedClassCount[0][0] #返回classList中出現(xiàn)次數(shù)最多的元素 #創(chuàng)建樹(shù)的函數(shù)代碼 def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]#取分類標(biāo)簽(是否放貸:yes or no) # print("classlist:") # print(classList) if classList.count(classList[0]) == len(classList): #如果類別完全相同則停止繼續(xù)劃分 return classList[0] if len(dataSet[0]) == 1: #遍歷完所有特征時(shí)返回出現(xiàn)次數(shù)最多的類標(biāo)簽 return majorityCnt(classList)
    bestFeat = chooseBestFeatureToSplit(dataSet) #選擇最優(yōu)特征 bestFeatLabel = labels[bestFeat]#最優(yōu)特征的標(biāo)簽 #featLabels.append(bestFeatLabel) myTree = {bestFeatLabel:{}}#根據(jù)最優(yōu)特征的標(biāo)簽生成樹(shù) del(labels[bestFeat]) #刪除已經(jīng)使用特征標(biāo)簽 featValues = [example[bestFeat] for example in dataSet] #得到訓(xùn)練集中所有最優(yōu)特征的屬性值 uniqueVals = set(featValues) #去掉重復(fù)的屬性值 for value in uniqueVals: #遍歷特征,創(chuàng)建決策樹(shù)。 subLabels=labels[:]
       myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels) return myTree

遞歸函數(shù)的第一個(gè)停止條件是所有的
類標(biāo)簽完全相同,則直接返回該類標(biāo)簽。遞歸函數(shù)的第二個(gè)停止條件是使用完了所有特征,任然不能將數(shù)據(jù)集劃分成僅包含唯一類別的分組 。由于第二個(gè)條件無(wú)法簡(jiǎn)單地返回唯一的類標(biāo) 簽,這里使用投票表決的函數(shù)挑選出現(xiàn)次數(shù)最多的類別作為返回值

運(yùn)行結(jié)果


由上面建立的決策樹(shù)可知,首先判斷你是否有房子,如果有就可以貸款給你,如果沒(méi)有房子再看你是否有工作,如果既沒(méi)有房子也沒(méi)有工作,就不貸款給你,如果有沒(méi)有房子,但有工作,也貸款給你

3.使用 Matplotlib 注解繪制樹(shù)形圖

使用Matplotlib的注解功能繪制樹(shù)形圖,它可以對(duì)文字著色并提供多種形狀以供選擇, 而且我們還可以反轉(zhuǎn)箭頭,將它指向文本框而不是數(shù)據(jù)點(diǎn)。
#獲取決策樹(shù)葉子結(jié)點(diǎn)的數(shù)目 def getNumLeafs(myTree):
    numLeafs = 0 #初始化葉子 firstStr = next(iter(myTree)) #python3中myTree.keys()返回的是dict_keys,不在是list,所以不能使用myTree.keys()[0]的方法獲取結(jié)點(diǎn)屬性,可以使用list(myTree.keys())[0] secondDict = myTree[firstStr] #獲取下一組字典 for key in secondDict.keys(): if type(secondDict[key]).__name__==’dict’: #測(cè)試該結(jié)點(diǎn)是否為字典,如果不是字典,代表此結(jié)點(diǎn)為葉子結(jié)點(diǎn) numLeafs += getNumLeafs(secondDict[key]) else:   numLeafs +=1 return numLeafs #獲取決策樹(shù)的層數(shù) def getTreeDepth(myTree):
    maxDepth = 0 #初始化決策樹(shù)深度 firstStr = next(iter(myTree)) #python3中myTree.keys()返回的是dict_keys,不在是list,所以不能使用myTree.keys()[0]的方法獲取結(jié)點(diǎn)屬性,可以使用list(myTree.keys())[0] secondDict = myTree[firstStr] #獲取下一個(gè)字典 for key in secondDict.keys(): if type(secondDict[key]).__name__==’dict’: #測(cè)試該結(jié)點(diǎn)是否為字典,如果不是字典,代表此結(jié)點(diǎn)為葉子結(jié)點(diǎn) thisDepth = 1 + getTreeDepth(secondDict[key]) else:   thisDepth = 1 if thisDepth > maxDepth: maxDepth = thisDepth #更新層數(shù) return maxDepth #繪制結(jié)點(diǎn) def plotNode(nodeTxt, centerPt, parentPt, nodeType):
    arrow_args = dict(arrowstyle="<-") #定義箭頭格式 #下面的字體僅使用與Mac用戶,如果您是Windows用戶請(qǐng)修改為font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14) font = FontProperties(fname=r’/System/Library/Fonts/Hiragino Sans GB.ttc’, size=14) #設(shè)置中文字體 createPlot.ax1.annotate(nodeTxt, xy=parentPt,  xycoords=’axes fraction’, #繪制結(jié)點(diǎn) xytext=centerPt, textcoords=’axes fraction’,
        va="center", ha="center", bbox=nodeType, arrowprops=arrow_args, fontproperties=font) #標(biāo)注有向邊屬性值 def plotMidText(cntrPt, parentPt, txtString):
    xMid = (parentPt[0]-cntrPt[0])/2.0 + cntrPt[0] #計(jì)算標(biāo)注位置 yMid = (parentPt[1]-cntrPt[1])/2.0 + cntrPt[1]
    createPlot.ax1.text(xMid, yMid, txtString, va="center", ha="center", rotation=30) #繪制決策樹(shù) def plotTree(myTree, parentPt, nodeTxt):
    decisionNode = dict(boxstyle="sawtooth", fc="0.8") #設(shè)置結(jié)點(diǎn)格式 leafNode = dict(boxstyle="round4", fc="0.8") #設(shè)置葉結(jié)點(diǎn)格式 numLeafs = getNumLeafs(myTree) #獲取決策樹(shù)葉結(jié)點(diǎn)數(shù)目,決定了樹(shù)的寬度 depth = getTreeDepth(myTree) #獲取決策樹(shù)層數(shù) firstStr = next(iter(myTree)) #下個(gè)字典 cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff) #中心位置 plotMidText(cntrPt, parentPt, nodeTxt) #標(biāo)注有向邊屬性值 plotNode(firstStr, cntrPt, parentPt, decisionNode) #繪制結(jié)點(diǎn) secondDict = myTree[firstStr] #下一個(gè)字典,也就是繼續(xù)繪制子結(jié)點(diǎn) plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD #y偏移 for key in secondDict.keys(): if type(secondDict[key]).__name__==’dict’: #測(cè)試該結(jié)點(diǎn)是否為字典,如果不是字典,代表此結(jié)點(diǎn)為葉子結(jié)點(diǎn) plotTree(secondDict[key],cntrPt,str(key)) #不是葉結(jié)點(diǎn),遞歸調(diào)用繼續(xù)繪制 else: #如果是葉結(jié)點(diǎn),繪制葉結(jié)點(diǎn),并標(biāo)注有向邊屬性值 plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW
            plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)
            plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
    plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD #創(chuàng)建繪制面板 def createPlot(inTree):
    fig = plt.figure(1, facecolor=’white’) #創(chuàng)建fig fig.clf() #清空f(shuō)ig axprops = dict(xticks=[], yticks=[])
    createPlot.ax1 = plt.subplot(111, frameon=False, **axprops) #去掉x、y軸 plotTree.totalW = float(getNumLeafs(inTree)) #獲取決策樹(shù)葉結(jié)點(diǎn)數(shù)目 plotTree.totalD = float(getTreeDepth(inTree)) #獲取決策樹(shù)層數(shù) plotTree.xOff = -0.5/plotTree.totalW; plotTree.yOff = 1.0; #x偏移 plotTree(inTree, (0.5,1.0), ’’) #繪制決策樹(shù) plt.show() #顯示繪制結(jié)果 if __name__ == ’__main__’:
    dataSet, labels = createDataSet() #featLabels = [] myTree = createTree(dataSet, labels) print(myTree)
    createPlot(myTree)

運(yùn)行遇到的錯(cuò)誤:

  • 1.AttributeError:module ’backend_interagg’ has no attribute ’FigureCanvas’
    解決方法:
    在pycharm中打開(kāi)" File --> Settings --> Tools --> Python Scientific ",將"Show plots in toolwindow"去掉勾選,并應(yīng)用。

  • 2.’Annotation’ object has no property ’FontProperties’
    解決方法:
    找了一會(huì)發(fā)現(xiàn)是字體問(wèn)題,因?yàn)槲业碾娔X是Mac系統(tǒng),在字體設(shè)置與Windows有些區(qū)別,讀者可以根據(jù)如下步驟修改:首先在終端輸入open /System/Library/Fonts然后找到一種字體,并復(fù)制其路徑,另外在調(diào)用的時(shí)候FontProperties要寫(xiě)成小寫(xiě),否則也會(huì)報(bào)錯(cuò),如下圖

最終問(wèn)題解決之后,運(yùn)行結(jié)果如下圖

3.使用決策樹(shù)預(yù)測(cè)隱形眼鏡類型

數(shù)據(jù)源
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

代碼實(shí)現(xiàn)

import treePlotter#之前寫(xiě)的構(gòu)建決策樹(shù)和繪制決策樹(shù)的代碼 if __name__ == ’__main__’:
    fr = open(’lenses.txt’)
    lenses = [inst.strip().split(’\t’) for inst in fr.readlines()] #print(lenses) lensesLabels = [’age’, ’prescript’, ’astigmatic’, ’tearRate’]
    lensesTree=treePlotter.createTree(lenses,lensesLabels) print(lensesTree)
    treePlotter.createPlot(lensesTree)

運(yùn)行結(jié)果



  業(yè)務(wù)實(shí)施流程

需求調(diào)研 →

團(tuán)隊(duì)組建和動(dòng)員 →

數(shù)據(jù)初始化 →

調(diào)試完善 →

解決方案和選型 →

硬件網(wǎng)絡(luò)部署 →

系統(tǒng)部署試運(yùn)行 →

系統(tǒng)正式上線 →

合作協(xié)議

系統(tǒng)開(kāi)發(fā)/整合

制作文檔和員工培訓(xùn)

售后服務(wù)

馬上咨詢: 如果您有業(yè)務(wù)方面的問(wèn)題或者需求,歡迎您咨詢!我們帶來(lái)的不僅僅是技術(shù),還有行業(yè)經(jīng)驗(yàn)積累。
QQ: 39764417/308460098     Phone: 13 9800 1 9844 / 135 6887 9550     聯(lián)系人:石先生/雷先生