決策樹ID3算法--python實現

參考:html

統計學習方法》第五章決策樹】   http://pan.baidu.com/s/1hrTsczapython

決策樹的python實現     有完整程序    
 

  1 #coding:utf-8
  2 # ID3算法,創建決策樹
  3 import numpy as np
  4 import math
  5 import uniout
  6 '''
  7 #建立數據集
  8 def creatDataSet():
  9     dataSet = np.array([[1,1,'yes'],
 10                         [1,1,'yes'],
 11                         [1,0,'no'],
 12                         [0,1,'no'],
 13                         [0,1,'no']])
 14     features = ['no surfaceing', 'fippers']
 15     return dataSet, features
 16 '''
 17 
 18 #建立數據集
 19 def createDataSet():
 20     dataSet = np.array([['青年', '', '', ''],
 21                   ['青年', '', '', ''],
 22                   ['青年', '', '', ''],
 23                   ['青年', '', '', ''],
 24                   ['青年', '', '', ''],
 25                   ['中年', '', '', ''],
 26                   ['中年', '', '', ''],
 27                   ['中年', '', '', ''],
 28                   ['中年', '', '', ''],
 29                   ['中年', '', '', ''],
 30                   ['老年', '', '', ''],
 31                   ['老年', '', '', ''],
 32                   ['老年', '', '', ''],
 33                   ['老年', '', '', ''],
 34                   ['老年', '', '', '']])
 35     features = ['年齡', '有工做', '有本身房子']
 36     return dataSet, features
 37 
 38 #計算數據集的熵
 39 def calcEntropy(dataSet):
 40     #先算機率
 41     labels = list(dataSet[:,-1])
 42     prob = {}
 43     entropy = 0.0
 44     for label in labels:
 45         prob[label] = (labels.count(label) / float(len(labels)))
 46     for v in prob.values():
 47         entropy = entropy + (-v * math.log(v,2))
 48     return entropy
 49 
 50 #劃分數據集
 51 def splitDataSet(dataSet, i, fc):
 52     subDataSet = []
 53     for j in range(len(dataSet)):
 54         if dataSet[j, i] == str(fc):
 55             sbs = []
 56             sbs.append(dataSet[j, :])
 57             subDataSet.extend(sbs)
 58     subDataSet = np.array(subDataSet)
 59     return np.delete(subDataSet,[i],1)
 60 
 61 #計算信息增益,選擇最好的特徵劃分數據集,即返回最佳特徵下標
 62 def chooseBestFeatureToSplit(dataSet):
 63     labels = list(dataSet[:, -1])
 64     bestInfoGain = 0.0   #最大的信息增益值
 65     bestFeature = -1   #*******
 66     #摘出特徵列和label列
 67     for i in range(dataSet.shape[1]-1):     #
 68         #計算列中,各個分類的機率
 69         prob = {}
 70         featureCoulmnL = list(dataSet[:,i])
 71         for fcl in featureCoulmnL:
 72             prob[fcl] = featureCoulmnL.count(fcl) / float(len(featureCoulmnL))
 73         #計算列中,各個分類的熵
 74         new_entrony = {}    #各個分類的熵
 75         condi_entropy = 0.0   #特徵列的條件熵
 76         featureCoulmn = set(dataSet[:,i])   #特徵列
 77         for fc in featureCoulmn:
 78             subDataSet = splitDataSet(dataSet, i, fc)
 79             prob_fc = len(subDataSet) / float(len(dataSet))
 80             new_entrony[fc] = calcEntropy(subDataSet)   #各個分類的熵
 81             condi_entropy = condi_entropy + prob[fc] * new_entrony[fc]    #特徵列的條件熵
 82         infoGain = calcEntropy(dataSet) - condi_entropy     #計算信息增益
 83         if infoGain > bestInfoGain:
 84             bestInfoGain = infoGain
 85             bestFeature = i
 86     return bestFeature
 87 
 88 #若特徵集features爲空,則T爲單節點,並將數據集D中實例樹最大的類label做爲該節點的類標記,返回T
 89 def majorityLabelCount(labels):
 90     labelCount = {}
 91     for label in labels:
 92         if label not in labelCount.keys():
 93             labelCount[label] = 0
 94         labelCount[label] += 1
 95     return max(labelCount)
 96 
 97 #創建決策樹T
 98 def createDecisionTree(dataSet, features):
 99     labels = list(dataSet[:,-1])
100     #若是數據集中的全部實例都屬於同一類label,則T爲單節點樹,並將類label做爲該結點的類標記,返回T
101     if len(set(labels)) == 1:
102         return labels[0]
103     #若特徵集features爲空,則T爲單節點,並將數據集D中實例樹最大的類label做爲該節點的類標記,返回T
104     if len(dataSet[0]) == 1:
105         return majorityLabelCount(labels)
106     #不然,按ID3算法就計算特徵集中各特徵對數據集D的信息增益,選擇信息增益最大的特徵beatFeature
107     bestFeatureI = chooseBestFeatureToSplit(dataSet)  #最佳特徵的下標
108     bestFeature = features[bestFeatureI]    #最佳特徵
109     decisionTree = {bestFeature:{}} #構建樹,以信息增益最大的特徵beatFeature爲子節點
110     del(features[bestFeatureI])    #該特徵已最爲子節點使用,則刪除,以便接下來繼續構建子樹
111     bestFeatureColumn = set(dataSet[:,bestFeatureI])
112     for bfc in bestFeatureColumn:
113         subFeatures = features[:]
114         decisionTree[bestFeature][bfc] = createDecisionTree(splitDataSet(dataSet, bestFeatureI, bfc), subFeatures)
115     return decisionTree
116 
117 #對測試數據進行分類
118 def classify(testData, features, decisionTree):
119     for key in decisionTree:
120         index = features.index(key)
121         testData_value = testData[index]
122         subTree = decisionTree[key][testData_value]
123         if type(subTree) == dict:
124             result = classify(testData,features,subTree)
125             return result
126         else:
127             return subTree
128 
129 
130 if __name__ == '__main__':
131     dataSet, features = createDataSet()     #建立數據集
132     decisionTree = createDecisionTree(dataSet, features)   #創建決策樹
133     print 'decisonTree:',decisionTree
134 
135     dataSet, features = createDataSet()
136     testData = ['老年', '', '']
137     result = classify(testData, features, decisionTree)  #對測試數據進行分類
138     print '是否給',testData,'貸款:',result

 

相關理論:算法

決策樹app

概念原理機器學習

決策樹是一種非參數的監督學習方法,它主要用於分類和迴歸。決策樹的目的是構造一種模型,使之可以從樣本數據的特徵屬性中,經過學習簡單的決策規則——IF THEN規則,從而預測目標變量的值。性能

決策樹學習步驟:1 特徵選擇 2 決策樹的生成 3 決策樹的修剪學習

那麼如何進行特徵選擇測試

因爲特徵選擇的方法不一樣,衍生出了三種決策樹算法:ID三、C4.五、CARTspa

ID3信息增益.net

熵越大,隨機變量的不肯定性越大。

條件熵H(Y|X)表示在已知隨機變量X的條件下隨機變量Y的不肯定性。

在信息增益中,衡量標準是看特徵可以爲分類系統帶來多少信息,帶來的信息越多,該特徵越重要。對一個特徵而言,系統有它和沒它時信息量將發生變化,而先後信息量的差值就是這個特徵給系統帶來的信息量。所謂信息量,就是熵。

C4.5信息增益比

CART 基尼指數

基尼指數越大,樣本的不肯定性就越大

 

 

三個算法的優缺點

ID3算法

C4.5算法

CART算法(Classification and Regression Tree)

以信息增益爲準則選擇信息增益最大的屬性。
缺點:1)信息增益對可取值數目較多的屬性有所偏好,好比經過ID號可將每一個樣本分紅一類,可是沒有意義。

2)ID3只能對離散屬性的數據集構造決策樹。
鑑於以上缺點,後來出現了C4.5算法。

以信息增益率爲準則選擇屬性;在信息增益的基礎上對屬性有一個懲罰,抑制可取值較多的屬性,加強泛化性能。
其餘優勢

1)在樹的構造過程當中能夠進行剪枝,緩解過擬合;

2)可以對連續屬性進行離散化處理(二分法);

3)可以對缺失值進行處理;
缺點:構造樹的過程須要對數據集進行屢次順序掃描和排序,致使算法低效;
剛纔咱們提到 信息增益對可取值數目較多的屬性有所偏好;而信息增益率對可取值數目較少的屬性有所偏好!OK,二者結合一下就行了!
解決方法:先從候選屬性中找出信息增益高於平均水平的屬性,再從中選擇增益率最高的。而不是你們常說的 直接選擇信息增益率最高的屬性!

顧名思義,能夠進行分類和迴歸,能夠處理離散屬性,也能夠處理連續的。
分類樹使用GINI指數來選擇劃分屬性:在全部候選屬性中,選擇劃分後GINI指數最小的屬性做爲優先劃分屬性。迴歸樹就用最小平方差。

 

ID三、C4.五、CART區別   參考:https://www.zhihu.com/question/27205203?sort=created

相關文章
相關標籤/搜索