日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python實現(xiàn)決策樹C4.5算法詳解(在ID3基礎(chǔ)上改進)

系統(tǒng) 1714 0

一、概論

C4.5主要是在ID3的基礎(chǔ)上改進,ID3選擇(屬性)樹節(jié)點是選擇信息增益值最大的屬性作為節(jié)點。而C4.5引入了新概念“信息增益率”,C4.5是選擇信息增益率最大的屬性作為樹節(jié)點。

二、信息增益

以上公式是求信息增益率(ID3的知識點)

三、信息增益率

python實現(xiàn)決策樹C4.5算法詳解(在ID3基礎(chǔ)上改進)_第1張圖片

信息增益率是在求出信息增益值在除以

例如下面公式為求屬性為“outlook”的 值:

python實現(xiàn)決策樹C4.5算法詳解(在ID3基礎(chǔ)上改進)_第2張圖片

四、C4.5的完整代碼

            
from numpy import *
from scipy import *
from math import log
import operator

#計算給定數(shù)據(jù)的香濃熵:
def calcShannonEnt(dataSet):
 numEntries = len(dataSet) 
 labelCounts = {} #類別字典(類別的名稱為鍵,該類別的個數(shù)為值)
 for featVec in dataSet:
  currentLabel = featVec[-1] 
  if currentLabel not in labelCounts.keys(): #還沒添加到字典里的類型
   labelCounts[currentLabel] = 0;
  labelCounts[currentLabel] += 1;
 shannonEnt = 0.0 
 for key in labelCounts: #求出每種類型的熵
  prob = float(labelCounts[key])/numEntries #每種類型個數(shù)占所有的比值
  shannonEnt -= prob * log(prob, 2)
 return shannonEnt; #返回熵

#按照給定的特征劃分數(shù)據(jù)集
def splitDataSet(dataSet, axis, value):
 retDataSet = [] 
 for featVec in dataSet: #按dataSet矩陣中的第axis列的值等于value的分數(shù)據(jù)集
  if featVec[axis] == value:  #值等于value的,每一行為新的列表(去除第axis個數(shù)據(jù))
   reducedFeatVec = featVec[:axis]
   reducedFeatVec.extend(featVec[axis+1:]) 
   retDataSet.append(reducedFeatVec) 
 return retDataSet #返回分類后的新矩陣

#選擇最好的數(shù)據(jù)集劃分方式
def chooseBestFeatureToSplit(dataSet): 
 numFeatures = len(dataSet[0])-1 #求屬性的個數(shù)
 baseEntropy = calcShannonEnt(dataSet)
 bestInfoGain = 0.0; bestFeature = -1 
 for i in range(numFeatures): #求所有屬性的信息增益
  featList = [example[i] for example in dataSet] 
  uniqueVals = set(featList) #第i列屬性的取值(不同值)數(shù)集合
  newEntropy = 0.0 
  splitInfo = 0.0;
  for value in uniqueVals: #求第i列屬性每個不同值的熵*他們的概率
   subDataSet = splitDataSet(dataSet, i , value) 
   prob = len(subDataSet)/float(len(dataSet)) #求出該值在i列屬性中的概率
   newEntropy += prob * calcShannonEnt(subDataSet) #求i列屬性各值對于的熵求和
   splitInfo -= prob * log(prob, 2);
  infoGain = (baseEntropy - newEntropy) / splitInfo; #求出第i列屬性的信息增益率
  print infoGain; 
  if(infoGain > bestInfoGain): #保存信息增益率最大的信息增益率值以及所在的下表(列值i)
   bestInfoGain = infoGain 
   bestFeature = i 
 return bestFeature 

#找出出現(xiàn)次數(shù)最多的分類名稱
def majorityCnt(classList): 
 classCount = {} 
 for vote in classList: 
  if vote not in classCount.keys(): classCount[vote] = 0 
  classCount[vote] += 1 
 sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgetter(1), reverse=True)
 return sortedClassCount[0][0] 

#創(chuàng)建樹
def createTree(dataSet, labels): 
 classList = [example[-1] for example in dataSet]; #創(chuàng)建需要創(chuàng)建樹的訓練數(shù)據(jù)的結(jié)果列表(例如最外層的列表是[N, N, Y, Y, Y, N, Y])
 if classList.count(classList[0]) == len(classList): #如果所有的訓練數(shù)據(jù)都是屬于一個類別,則返回該類別
  return classList[0]; 
 if (len(dataSet[0]) == 1): #訓練數(shù)據(jù)只給出類別數(shù)據(jù)(沒給任何屬性值數(shù)據(jù)),返回出現(xiàn)次數(shù)最多的分類名稱
  return majorityCnt(classList);

 bestFeat = chooseBestFeatureToSplit(dataSet); #選擇信息增益最大的屬性進行分(返回值是屬性類型列表的下標)
 bestFeatLabel = labels[bestFeat] #根據(jù)下表找屬性名稱當樹的根節(jié)點
 myTree = {bestFeatLabel:{}} #以bestFeatLabel為根節(jié)點建一個空樹
 del(labels[bestFeat]) #從屬性列表中刪掉已經(jīng)被選出來當根節(jié)點的屬性
 featValues = [example[bestFeat] for example in dataSet] #找出該屬性所有訓練數(shù)據(jù)的值(創(chuàng)建列表)
 uniqueVals = set(featValues) #求出該屬性的所有值得集合(集合的元素不能重復)
 for value in uniqueVals: #根據(jù)該屬性的值求樹的各個分支
  subLabels = labels[:] 
  myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels) #根據(jù)各個分支遞歸創(chuàng)建樹
 return myTree #生成的樹

#實用決策樹進行分類
def classify(inputTree, featLabels, testVec): 
 firstStr = inputTree.keys()[0] 
 secondDict = inputTree[firstStr] 
 featIndex = featLabels.index(firstStr) 
 for key in secondDict.keys(): 
  if testVec[featIndex] == key: 
   if type(secondDict[key]).__name__ == 'dict': 
    classLabel = classify(secondDict[key], featLabels, testVec) 
   else: classLabel = secondDict[key] 
 return classLabel 

#讀取數(shù)據(jù)文檔中的訓練數(shù)據(jù)(生成二維列表)
def createTrainData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 labelLine = lines_set[2];
 labels = labelLine.strip().split()
 lines_set = lines_set[4:11]
 dataSet = [];
 for line in lines_set:
  data = line.split();
  dataSet.append(data);
 return dataSet, labels


#讀取數(shù)據(jù)文檔中的測試數(shù)據(jù)(生成二維列表)
def createTestData():
 lines_set = open('../data/ID3/Dataset.txt').readlines()
 lines_set = lines_set[15:22]
 dataSet = [];
 for line in lines_set:
  data = line.strip().split();
  dataSet.append(data);
 return dataSet

myDat, labels = createTrainData() 
myTree = createTree(myDat,labels) 
print myTree
bootList = ['outlook','temperature', 'humidity', 'windy'];
testList = createTestData();
for testData in testList:
 dic = classify(myTree, bootList, testData)
 print dic
          

五、C4.5與ID3的代碼區(qū)別

python實現(xiàn)決策樹C4.5算法詳解(在ID3基礎(chǔ)上改進)_第3張圖片

如上圖,C4.5主要在第52、53行代碼與ID3不同(ID3求的是信息增益,C4.5求的是信息增益率)。

六、訓練、測試數(shù)據(jù)集樣例

            
訓練集:

 outlook temperature humidity windy 
 ---------------------------------------------------------
 sunny  hot    high   false   N
 sunny  hot    high   true   N
 overcast hot    high   false   Y
 rain  mild   high   false   Y
 rain  cool   normal  false   Y
 rain  cool   normal  true   N
 overcast cool   normal  true   Y

測試集
 outlook temperature humidity windy 
 -----------------------------------------------  
 sunny  mild   high   false   
 sunny  cool   normal  false   
 rain   mild   normal  false  
 sunny  mild   normal  true   
 overcast mild   high   true   
 overcast hot    normal  false   
 rain   mild   high   true  
          

以上這篇python實現(xiàn)決策樹C4.5算法詳解(在ID3基礎(chǔ)上改進)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。


更多文章、技術(shù)交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 方山县| 普兰店市| 铜山县| 青浦区| 三台县| 光山县| 木里| 宜君县| 罗甸县| 绥阳县| 芒康县| 九龙县| 茌平县| 新昌县| 佛学| 江津市| 襄城县| 安顺市| 恭城| 高安市| 德钦县| 鄂尔多斯市| 永泰县| 大渡口区| 长岭县| 江永县| 南部县| 若尔盖县| 汉中市| 嘉义市| 英吉沙县| 安宁市| 兴宁市| 百色市| 城口县| 闵行区| 华池县| 泸西县| 无棣县| 天祝| 六枝特区|