前情提要:
通俗地說決策樹算法(一)基礎概念介紹html
上一節,咱們介紹了決策樹的一些基本概念,包括樹的基本知識以及信息熵的相關內容,那麼此次,咱們就經過一個例子,來具體展現決策樹的工做原理,以及信息熵在其中承擔的角色。java
有一點得先說一下,決策樹在優化過程當中,有3個經典的算法,分別是ID3,C4.5,和CART。後面的算法都是基於前面算法的一些不足進行改進的,咱們此次就先講ID3算法,後面會再說說它的不足與改進。算法
衆所周知,早上要不要賴牀是一個很深入的問題。它取決於多個變量,下面就讓咱們看看小明的賴牀習慣吧。spring
季節 | 時間已過 8 點 | 風力狀況 | 要不要賴牀 |
---|---|---|---|
spring | no | breeze | yes |
winter | no | no wind | yes |
autumn | yes | breeze | yes |
winter | no | no wind | yes |
summer | no | breeze | yes |
winter | yes | breeze | yes |
winter | no | gale | yes |
winter | no | no wind | yes |
spring | yes | no wind | no |
summer | yes | gale | no |
summer | no | gale | no |
autumn | yes | breeze | no |
OK,咱們隨機抽了一年中14天小明的賴牀狀況。如今咱們能夠根據這些數據來構建一顆決策樹。編程
能夠發現,數據中有三個屬性會影響到最終的結果,分別是,季節,時間是否過8點,風力狀況。併發
要構建一顆決策樹,首先咱們要找到它的根,按照上一節所說,咱們須要計算每個屬性的信息熵。函數式編程
在計算每個屬性的信息熵以前,咱們須要先根據歷史數據,計算沒有任何屬性影響下的賴牀信息熵。從數據咱們能夠知道,14天中,有賴牀爲8天,不賴牀爲6天。則函數
p(賴牀) = 8 / 12. p(不賴牀) = 6 / 12.
信息熵爲oop
H(賴牀) = -(p(賴牀) * log(p(賴牀)) + p(不賴牀) * log(p(不賴牀))) = 0.89
接下來就能夠來計算每一個屬性的信息熵了,這裏有三個屬性,即季節,是否過早上8點,風力狀況,咱們須要計算三個屬性的每一個屬性在不一樣狀況下,賴牀和不賴牀的機率,以及熵值。性能
說得有點繞,咱們先以風力狀況這一屬性來計算它的信息熵是多少,風力狀況有三種,咱們分別計算三種狀況下的熵值。
風力狀況爲 breeze 時,有 4 / 5 的機率會賴牀,而 1 / 5 的機率不會賴牀,它的熵爲 entropy(breeze) = -(p(breeze,賴牀) * log(p(breeze,賴牀)) + p(breeze,不賴牀) * log(p(breeze,不賴牀))) 0.722。 風力狀況爲 no wind 時,和上面同樣的計算,熵值爲 entropy(no wind) = 0.811 風力狀況爲 gale 時,熵值爲 entropy(gale) = 0.918
最終,風力狀況這一屬性的熵值爲其對應各個值的熵值乘以這些值對應頻率。
H(風力狀況) = 5/12 * entropy(breeze) + 4/12 * entropy(no wind) + 3/12 * entropy(gale) = 0.801
還記得嗎,一開始什麼屬性沒有,賴牀的熵是H(賴牀)=0.89。如今加入風力狀況這一屬性後,賴牀的熵降低到了0.801。這說明信息變得更加清晰,咱們的分類效果愈來愈好。
以一樣的計算方式,咱們能夠求出另外兩個屬性的信息熵:
H(季節) = 0.56 H(是否過 8 點) = 0.748
經過它們的信息熵,咱們能夠計算出每一個屬性的信息增益。沒錯,這裏又出現一個新名詞,信息增益。不過它不難理解,信息增益就是拿上一步的信息熵(這裏就是最原始賴牀狀況的信息熵)減去選定屬性的信息熵,即
信息增益 g(季節) = H(賴牀) - H(季節) = 0.33
這樣咱們就能計算每一個屬性的信息增益,而後選取信息增益最大的那個做爲根節點就好了,在這個例子中,很明顯,信息增益最大的是季節這個屬性。
選完根節點怎麼辦?把每一個節點看成一顆新的樹,挑選剩下的屬性,重複上面的步驟就能夠啦。
當所有都遍歷完以後,一顆完整的樹也就構建出來了,這個例子中,咱們最終構造的樹會是這個樣子的:
在構建決策樹的時候,咱們的指望是構建一顆最矮的決策樹,爲何須要構建最矮呢?這是由於咱們要避免過擬合的狀況。
什麼是過擬合呢,下圖是一個分類問題的小例子,左邊是正常的分類結果,右邊是過擬合的分類結果。
在現實世界中,咱們的數據一般不會很完美,數據集裏面可能會有一些錯誤的數據,或是一些比較奇葩的數據。如上圖中的藍色方塊,正常狀況下咱們是容許必定的偏差,追求的是普適性,就是要適應大多數狀況。但過擬合的時候,會過分追求正確性,致使普適性不好。
剪枝,即減小樹的高度就是爲了解決過擬合,你想一想看,過擬合的狀況下,決策樹是可以對給定樣本中的每個屬性有一個精準的分類的,但太過精準就會致使上面圖中的那種狀況,喪失了普適性。
而剪枝又分兩種方法,預剪枝幹,和後剪枝。這兩種方法其實仍是蠻好理解的,一種是自頂向下,一種是自底向上。咱們分別來看看。
預剪枝其實你能夠想象成是一種自頂向下的方法。在構建過程當中,咱們會設定一個高度,當達構建的樹達到那個高度的時候呢,咱們就中止創建決策樹,這就是預剪枝的基本原理。
後剪枝呢,其實就是一種自底向上的方法。它會先任由決策樹構建完成,構建完成後呢,就會從底部開始,判斷哪些枝幹是應該剪掉的。
注意到預剪枝和後剪枝的最大區別沒有,預剪枝是提早中止,然後剪枝是讓決策樹構建完成的,因此從性能上說,預剪枝是會更塊一些,後剪枝呢則能夠更加精確。
用ID3算法來構建決策樹當然比較簡單,但這個算法卻有一個問題,ID3構建的決策樹會偏袒取值較多的屬性。爲何會有這種現象呢?仍是舉上面的例子,假如咱們加入了一個屬性,日期。一年有365天,若是咱們真的以這個屬性做爲劃分依據的話,那麼每一天會不會賴牀的結果就會很清晰,由於每一天的樣本不多,會顯得一目瞭然。這樣一來信息增益會很大,但會出現上面說的過擬合狀況,你以爲這種狀況能夠泛化到其餘狀況嗎?顯然是不行的!
針對ID3決策樹的這個問題,提出了另外一種算法C4.5構建決策樹。
C4.5決策樹中引入了一個新的概念,以前不是用信息增益來選哪一個屬性來做爲枝幹嗎,如今咱們用增益率來選!
這裏面,IV(a)這個,當屬性可選的值越多(好比一年可取365個日期)的時候,它的值越大。
而IV(a)值越大,增益率顯然更小,這就出現新問題了。C4.5決策樹跟ID3決策樹反過來,它更偏袒屬性可選值少的屬性。這就很麻煩了,那麼有沒有一種更加公正客觀的決策樹算法呢?有的!!
上面說到,ID3決策樹用信息增益做爲屬性選取,C4.5用增益率做爲屬性選取。但它們都有各自的缺陷,因此最終提出了CART,目前sklearn中用到的決策樹算法也是CART。CART決策樹用的是另外一個東西做爲屬性選取的標準,那就是基尼係數。
第一條公式中pk表示的是每一個屬性的可選值,將這些可選值計算後累加。這條公式和信息增益的結果實際上是相似的,當屬性分佈越平均,也就是信息越模糊的時候,基尼係數值會更大,反之則更小。但這種計算方法,每次都只用二分分類的方式進行計算。好比說上面例子中的季節屬性,有春夏秋冬四個可選值(春,夏,秋,冬)。那麼計算春季的時候就會按二分的方式計算(春,(夏,秋,冬))。然後面其餘步驟與ID3相似。經過這種計算,能夠較好得規避ID3決策樹的缺陷。
因此若是用CART算法訓練出來的決策樹,會和咱們上面ID3訓練出來的決策樹有些不同。在下一篇文章就會用sklearn來使用CART算法訓練一顆決策樹,而且會將結果經過畫圖的方式展示。
推薦閱讀:
Scala 函數式編程指南(一) 函數式思想介紹
Actor併發編程模型淺析
大數據存儲的進化史 --從 RAID 到 Hadoop Hdfs
C,java,Python,這些名字背後的江湖!