決策樹的一般流程
檢測數(shù)據(jù)集中的每個子項是否屬于同一個分類
if so return 類標簽 Else
? 尋找劃分數(shù)據(jù)集的最好特征
??? 劃分數(shù)據(jù)集
?? 創(chuàng)建分支 節(jié)點
from math import log import operator #生成樣本數(shù)據(jù)集 def createDataSet(): dataSet = [[1,1,'yes'], [1,1,'yes'], [1,0,'no'], [0,1,'no'], [0,1,'no']] labels = ['no surfacing','flipper'] return dataSet,labels # 計算香農(nóng)熵 香農(nóng) 大神必須要膜拜啊,信息界的根目錄人物啊 # no surfacing 指的是 不浮出水面能否生存 1 標識 是 0 指的是否 # flipper 指的是是否有腳 # yes no指的是否是魚類 def calcShannonEnt(dataSet): numEntries = len(dataSet) # 用上面的createDataSet dataSet 這個值就是5 #定義標簽字典 labelCounts = {} # 為所有可能的分類創(chuàng)建字典 for featVec in dataSet: currentLabel = featVec[-1] #這個-1指的是去取最后一個維度 對應數(shù)據(jù)dataSet 這里取的是yes和no if currentLabel not in labelCounts.keys(): # 如果當前分類標簽不在 標簽字典中 labelCounts[currentLabel] = 0 # 其他情況 分類標簽分類加1 labelCounts[currentLabel] += 1 #定義香農(nóng)熵 以2為底數(shù)求對數(shù) shannonEnt = 0.0 for key in labelCounts: #計算 yes 或者No 出現(xiàn)的概率 pro = float(labelCounts[key])/numEntries # 計算香農(nóng)熵 shannonEnt -= pro*log(pro,2) return shannonEnt #dataSet是待劃分的數(shù)據(jù)集, 劃分數(shù)據(jù)集的特征 axis 特征的返回值value #最后是創(chuàng)建了一個新的列表對象 def splitDataSet(dataSet, axis , value): # 創(chuàng)建新list對象 retDataSet = [] for featVec in dataSet: if featVec[axis] == value: reducedFeatVec = featVec[:axis] reducedFeatVec.extend(featVec[axis+1:]) retDataSet.append(reducedFeatVec) return retDataSet # 選擇最好的特征值進行數(shù)據(jù)集劃分 def chooseBestFeatureToSplit(dataSet): # len(dataSet[0])是計算這一行有多少列,即有多少個特征值 numFeatures = len(dataSet[0])-1 # -1 是最后一個特征值就不要記錄在內(nèi)了,算baseEntrop的時候已經(jīng)算了最后一個特征值yes no baseEntropy = calcShannonEnt(dataSet) bestInfoGain = 0.0 bestFeature = -1 for i in range(numFeatures): #創(chuàng)建唯一的分類標簽列表 也就是說提取dataSet每一行第i個值 就提取dat featList = [example[i] for example in dataSet] # 取出有幾種特征值 uniqueVals = set(featList) newEntropy = 0.0 for value in uniqueVals: #創(chuàng)建特征值的子數(shù)據(jù)集 subDataSet = splitDataSet(dataSet,i, value) #計算該特征值數(shù)據(jù)對總數(shù)在數(shù)據(jù)對總數(shù)出現(xiàn)的概率 pro = len(subDataSet)/float(len(dataSet)) #計算分割出來的子集香農(nóng)熵 newEntropy += pro*calcShannonEnt(subDataSet) #計算信息增益 得到最好的特征值 這個理論是這樣的g(D,A) = H(D)-H(D/A) infoGain = baseEntropy-newEntropy #取出最大的信息增益,此時特征值最大 if(infoGain >bestInfoGain): bestInfoGain = infoGain bestFeature = i return bestFeature ''' #構建決策樹是根據(jù)特征值的消耗來計算的,如果后面的特征值已經(jīng)全部用完了 但是還沒有分出結果,這個時候就需要使用多數(shù)表決方式計算節(jié)點分類 最后返回最大的分類 ''' def majorityCnt(classList): # 分類的字典 classCount = {} for vote in range(classList): #如果不在 分類字典中 if vote not in classCount.keys(): classCount[vote] = 0 classCount[vote] += 1 # 根據(jù)出現(xiàn)的次數(shù)大到小排序 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) return sortedClassCount[0][0] #創(chuàng)建決策樹 def createTree(dataSet, labels): # 獲取數(shù)據(jù)樣本每組最后一組的特征值 這里是yes,no classList = [example[-1] for example in dataSet] # 如果說這個classList 全部都是 yes 或者全部是no 那肯定子返回yes 或者no if(classList.count(classList[0]) == len(classList)): return classList[0] #如果遍歷完所有的特征返回出現(xiàn)次數(shù)最多的 #是用消耗特征值的方式進行構造決策樹的,每次會消掉一個特征值 if len(dataSet[0]) == 1: return majorityCnt(classList) #選擇最好的特征值 bestFeat = chooseBestFeatureToSplit(dataSet) bestFeatLabel = labels[bestFeat] myTree = {bestFeatLabel:{}} # 刪除labels中的一特征值 del(labels[bestFeat]) #找到特征值那一列 featValues = [example[bestFeat] for example in dataSet] uniqueVals = set(featValues) for value in uniqueVals: # labels列表的賦值 subLabels = labels[:] myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels) return myTree dataSet,lables = createDataSet() shannonEnt= calcShannonEnt(dataSet) my = createTree(dataSet,lables) print(my)
總結
以上所述是小編給大家介紹的Python3.0 實現(xiàn)決策樹算法的流程,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
