【機器學習筆記之二】決策樹的python實現

來源:互聯網
上載者:User

標籤:family   cart   splay   技術分享   ogr   ipy   _id   pap   one   

本文結構:
  1. 是什嗎?
  2. 有什麼演算法?
  3. 數學原理?
  4. 編碼實現演算法?
1. 是什嗎?

簡單地理解,就是根據一些 feature 進行分類,每個節點提一個問題,通過判斷,將資料分為幾類,再繼續提問。這些問題是根據已有資料學習出來的,再投入新資料的時候,就可以根據這棵樹上的問題,將資料劃分到合適的葉子上。


2. 有什麼演算法?

常用的幾種決策樹演算法有ID3、C4.5、CART:

ID3:選擇資訊熵增益最大的feature作為node,實現對資料的歸納分類。
C4.5:是ID3的一個改進,比ID3準確率高且快,可以處理連續值和有缺失值的feature。
CART:使用基尼指數的劃分準則,通過在每個步驟最大限度降低不純潔度,CART能夠處理孤立點以及能夠對空缺值進行處理。

3. 數學原理?ID3: Iterative Dichotomiser 3

參考


下面這個資料集,可以同時被上面兩顆樹表示,結果是一樣的,而我們更傾向於選擇簡單的樹。
那麼怎樣做才能使得學習到的樹是最簡單的呢?


下面是 ID3( Iterative Dichotomiser 3 )的演算法:


例如下面資料集,哪個是最好的 Attribute?


用熵Entropy來衡量:
E(S) 是資料集S的熵
i 指每個結果,即 No,Yes的機率


E越大意味著資訊越混亂,我們的目標是要讓E最小。
E在0-1之間,如果P+的機率在0.5, 此時E最大,這時候說明資訊對我們沒有明確的意義,對分類沒有協助。


但是我們不僅僅想要變數的E最小,還想要這棵樹是 well organized。
所以用到 Gain:資訊增益


意思是如果我後面要用這個變數的話,它的E會減少多少。


例如下面的資料集:


  1. 先計算四個feature的熵E,及其分支的熵,然後用Gain的公式計算資訊增益。


  2. 再選擇Gain最大的特徵是 outlook。

  3. 第一層選擇出來後,各個分支再繼續選擇下一層,計算Gain最大的,例如分支 sunny 的下一層節點是 humidity。


詳細的計算步驟可以參考這篇博文。

C4.5

參考

ID3有個局限是對於有大量資料的feature過于敏感,C4.5是它的一個改進,通過選擇最大的資訊增益率 gain ratio 來選擇節點。而且它可以處理連續的和有缺失值的資料。


P’ (j/p) is the proportion of elements present at the position p, taking the value of j-th test.

例如 outlook 作為第一層節點後,它有 3 個分支,分別有 5,4,5 條資料,則 SplitInfo(5,4,5) = -5/14log(5,14)-4/14log(4,14)-5/14(5,14) ,其中 log(5,14) 即為 log2(5/14)。

下面是一個有連續值和缺失值的例子:


連續值

第一步計算 Gain,除了連續值的 humudity,其他步驟和前文一樣。

要計算 humudity 的 Gain 的話,先把所有值升序排列:
{65, 70, 70, 70, 75, 78, 80, 80, 80, 85, 90, 90, 95, 96}
然後把重複的去掉:
{65, 70, 75, 78, 80, 85, 90, 95, 96}
如所示,按區間計算 Gain,然後選擇最大的 Gain (S, Humidity) = 0.102


因為 Gain(S, Outlook) = 0 .246,所以root還是outlook:


缺失值

處理有缺失值的資料時候,用的公式:


例如 D12 是不知道的。

  1. 計算全集和 outlook 的 info,


  2. 其中幾個分支的熵如下,再計算出 outlook 的 Gain:


比較一下 ID3 和 C4.5 的準確率和時間:

accuracy :


execution time:


4. 編碼實現演算法?

代碼可以看《機器學習實戰》這本書和這篇部落格。

完整代碼可以在 github 上查看。

接下來以 C4.5 的代碼為例:

1. 定義資料:

 1 def createDataSet(): 2     dataSet = [[0, 0, 0, 0, ‘N‘],  3                [0, 0, 0, 1, ‘N‘],  4                [1, 0, 0, 0, ‘Y‘],  5                [2, 1, 0, 0, ‘Y‘],  6                [2, 2, 1, 0, ‘Y‘],  7                [2, 2, 1, 1, ‘N‘],  8                [1, 2, 1, 1, ‘Y‘]] 9     labels = [‘outlook‘, ‘temperature‘, ‘humidity‘, ‘windy‘]10     return dataSet, labels

2. 計算熵:

 1 def calcShannonEnt(dataSet): 2     numEntries = len(dataSet) 3     labelCounts = {} 4     for featVec in dataSet: 5         currentLabel = featVec[-1] 6         if currentLabel not in labelCounts.keys(): 7             labelCounts[currentLabel] = 0 8         labelCounts[currentLabel] += 1      # 數每一類各多少個, {‘Y‘: 4, ‘N‘: 3} 9     shannonEnt = 0.010     for key in labelCounts:11         prob = float(labelCounts[key])/numEntries12         shannonEnt -= prob * log(prob, 2)13     return shannonEnt

3. 選擇最大的gain ratio對應的feature:

 1 def chooseBestFeatureToSplit(dataSet): 2     numFeatures = len(dataSet[0]) - 1                 #feature個數 3     baseEntropy = calcShannonEnt(dataSet)             #整個dataset的熵 4     bestInfoGainRatio = 0.0 5     bestFeature = -1 6     for i in range(numFeatures): 7         featList = [example[i] for example in dataSet]  #每個feature的list 8         uniqueVals = set(featList)                      #每個list的唯一值集合                  9         newEntropy = 0.010         splitInfo = 0.011         for value in uniqueVals:12             subDataSet = splitDataSet(dataSet, i, value)  #每個唯一值對應的剩餘feature的組成子集13             prob = len(subDataSet)/float(len(dataSet))14             newEntropy += prob * calcShannonEnt(subDataSet)15             splitInfo += -prob * log(prob, 2)16         infoGain = baseEntropy - newEntropy              #這個feature的infoGain17         if (splitInfo == 0): # fix the overflow bug18             continue19         infoGainRatio = infoGain / splitInfo             #這個feature的infoGainRatio      20         if (infoGainRatio > bestInfoGainRatio):          #選擇最大的gain ratio21             bestInfoGainRatio = infoGainRatio22             bestFeature = i                              #選擇最大的gain ratio對應的feature23     return bestFeature

4. 劃分資料,為下一層計算準備:

1 def splitDataSet(dataSet, axis, value):2     retDataSet = []3     for featVec in dataSet:4         if featVec[axis] == value:                      #只看當第i列的值=value時的item5             reduceFeatVec = featVec[:axis]              #featVec的第i列給除去6             reduceFeatVec.extend(featVec[axis+1:])7             retDataSet.append(reduceFeatVec)            8     return retDataSet

5. 多重字典構建樹:

 1 def createTree(dataSet, labels): 2     classList = [example[-1] for example in dataSet]         # [‘N‘, ‘N‘, ‘Y‘, ‘Y‘, ‘Y‘, ‘N‘, ‘Y‘] 3     if classList.count(classList[0]) == len(classList): 4         # classList所有元素都相等,即類別完全相同,停止劃分 5         return classList[0]                                  #splitDataSet(dataSet, 0, 0)此時全是N,返回N 6     if len(dataSet[0]) == 1:                                 #[0, 0, 0, 0, ‘N‘]  7         # 遍曆完所有特徵時返回出現次數最多的 8         return majorityCnt(classList) 9     bestFeat = chooseBestFeatureToSplit(dataSet)             #0-> 2   10         # 選擇最大的gain ratio對應的feature11     bestFeatLabel = labels[bestFeat]                         #outlook -> windy     12     myTree = {bestFeatLabel:{}}                   13         #多重字典構建樹{‘outlook‘: {0: ‘N‘14     del(labels[bestFeat])                                    #[‘temperature‘, ‘humidity‘, ‘windy‘] -> [‘temperature‘, ‘humidity‘]        15     featValues = [example[bestFeat] for example in dataSet]  #[0, 0, 1, 2, 2, 2, 1]     16     uniqueVals = set(featValues)17     for value in uniqueVals:18         subLabels = labels[:]                                #[‘temperature‘, ‘humidity‘, ‘windy‘]19         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)20             # 劃分資料,為下一層計算準備21     return myTree

 

6. 可視化決策樹的結果:

dataSet, labels = createDataSet()labels_tmp = labels[:]desicionTree = createTree(dataSet, labels_tmp)treePlotter.createPlot(desicionTree)

 

 



【機器學習筆記之二】決策樹的python實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.