原本仍是想像之前同樣,繼續學習《 Python數據挖掘入門與實踐 》的第三章「決策樹」,可是這本書上來就直接給我懟了一大串代碼,對於決策樹
基本上沒有什麼介紹,可直接把我給弄懵逼了,主要我只聽過決策樹尚未認真的瞭解過它。node
這一章節主要是對決策樹作一個介紹,在下一個章節,將使用決策樹來進行預測分類 。算法
Decision Tree是一類較爲常見的機器學習的方法。它既能夠做爲分類算法,也能夠做爲迴歸算法。dom
如何來介紹決策樹,這裏舉一個例子:在大學,你找女友的時候,心目中順序應該是這樣的(僅僅是舉一個例子):機器學習
爲了更好的表示上面的這一些問題,咱們能夠將其畫成一張樹狀圖以下所示:工具
上面的這棵樹就是咱們找女友的決策過程,圓角矩形表明了判斷條件,橢圓形表明了決策結果。經過性別,年齡,專業這幾個屬性,最終咱們得出了最終的決策。而這棵樹也就被稱之爲決策樹。post
你們經過上圖會發現有3個東西:性能
在一棵決策樹中,包含了一個根節點
,多個內部節點(判斷條件)
和若干個葉子節點
。先說葉子節點,在決策樹中,葉子節點對應了決策結果,決策結果能夠有多種類型(圖中是yes和no,也能夠爲1,2,3)。內部節點和根節點對應的都是屬性測試
,只不過前後順序不一樣。學習
總的來講,決策樹體現的是一種「分而治之」的思想,測試
那麼這裏就有一個問題,誰來當根節點?誰又來當中間的節點?前後順序又是怎樣的?(這裏先不說算法流程,從簡單開始提及,而後再說算法流程)spa
首先咱們須要明白根節點和中間節點是不一樣的,一個是統領全局的開始包含全部的樣本。一個是負責局部的決策,而且隨着決策樹的不斷的進行決策,所包含的樣本逐漸屬於同一個類別,即節點的「純度」愈來愈高。
那麼,咱們如何來尋找合適根節點(也就是屬性)呢?靠感受?靠感受固然不行,咱們須要一個具體的數值來決定,很幸運,香農幫助咱們作到了。
「信息熵」(information entropy):能夠度量樣本集合中的「純度」。 在信息世界,熵越高,表示蘊含越多的信息,熵越低,則信息越少。 而根節點須要包含因此的樣本,則根結點的熵最大
。
設樣本集合爲\(D\),第\(k\)類樣本所佔比例爲\(p_k(k = 1,2,3,……n)\),則集合\(D\)的信息熵爲:
\[ Ent(D) = - \sum_{k=1}^{n}p_klog_2p_k\\ Ent(D)越大,則D的純度越小,也就是說集合D越混亂。 \]
如今,咱們已經知道一個集合\(D\)中的信息熵是多少,那麼咱們如何來進行劃分呢?首先,咱們須要明確一個劃分的標準(也就是目標),咱們固然但願劃分以後,劃分以後的集合的熵愈來愈小,也就是劃分後的集合愈來愈純,這裏咱們引入信息增益這個概念。
下面是西瓜書中對信息增益的定義:
假設離散屬性\(a\)有\(V\)個可能的取值\(\{a^1,a^2,a^3……a^V\}\),若以屬性\(a\)對樣本進行劃分,則有V個分支,其中第\(v\)個分支包含了\(D\)中在屬性\(a\)上取值爲\(a^v\)的樣本,記爲\(D^v\)。咱們能夠計算出\(D^v\)的信息熵,而後考慮到不一樣分支結點的樣本數不一樣,給分支結點賦予權重\(\frac{|D^v|}{|D|}\),樣本數愈多,則影響力越大,則能夠計算出屬性\(a\)對樣本集\(D\)進行劃分的「信息增益」:
\[ Gain(D,a) = Ent(D) - \sum_{v=1}^V\frac{|D^v|}{|D|}Ent(D^v) \]
通常來講,信息增益越大,則表明劃分後的集合越「純」,也就是說使用\(a\)屬性來劃分的效果最好,那麼咱們就可使用\(a\)屬性來進行劃分。ID3算法就是使用信息增益來做爲標準劃分屬性的。
下面是來自《西瓜書》的決策樹生成算法流程:
決策樹生成是一個遞歸的過程,在下面3中狀況中,遞歸會返回:
算法可能不是那麼的形象好理解,下面將以實際的例子來展現。
在最上面上面的找女友的例子並非特別的好,屬性太少。這裏以西瓜書中的🍉來進行舉例。這個屬性仍是挺多的。
在上圖中,屬性的集合是{色澤,根蒂,敲聲,紋理,臍部,觸感}
(目前不考慮編號這個屬性),分類的集合是{是,否}
,一共有17個樣本。
首先讓咱們來及計算集合\(D\)的熵值。在集合\(D\)中,好瓜(是)佔\(p_1 = \frac{8}{17}\),壞瓜(否)佔\(p_1 = \frac{9}{17}\),因此集合\(D\)的熵爲:
\[ Ent(D) = -\sum_{k=1}^2p_klog_2p_k = -(\frac{8}{17}log_2\frac{8}{17} + \frac{9}{17}log_2\frac{9}{17}) = 0.998 \]
以色澤做爲劃分標準,能夠獲得3個子集:
\[ D^1(色澤=青綠) = \{1,4,6,10,13,17\} \\ 在D^1中p_1 = \frac{3}{6},p_2=\frac{3}{6}\\ D^2(色澤=烏黑) = \{2,3,7,8,9,15\}\\ 在D^2中p_1 = \frac{4}{6},p_2=\frac{2}{6}\\ D^3(色澤=淺白) = \{5,11,12,14,16\}\\ 在D^2中p_1 = \frac{1}{5},p_2=\frac{4}{5} \\ 其中集合中的數字表明表格中的編號 \]
咱們能夠得到\(D^1,D^2,D^3\)的信息熵:
\[ Ent(D^1)=-(\frac{3}{6}log_2\frac{3}{6}+\frac{3}{6}log_2\frac{3}{6}) = 1.00 \\ Ent(D^2)=-(\frac{4}{6}log_2\frac{4}{6}+\frac{2}{6}log_2\frac{2}{6}) = 0.918 \\ Ent(D^3)=-(\frac{1}{5}log_2\frac{1}{5}+\frac{4}{5}log_2\frac{4}{5}) = 0.722 \\ \]
所以色澤
的信息增益爲:
\[ \begin{equation} \begin{aligned} Gain(D,色澤) &= Ent(D) - \sum_{v=1}^3\frac{|D^v|}{|D|}Ent(D^v)\\ &= 0.99 - (\frac{6}{17}\times 1.00 + \frac{6}{17}\times0.918 +\frac{5}{17}\times0.722) \\ &= 0.109 \end{aligned} \end{equation} \]
同理能夠獲得:
\[ \begin{equation} \begin{split} & Gain(D,根蒂) = 0.143;Gain(D,敲聲) = 0.141;\\ & Gain(D,紋理) = 0.381;Gain(D,臍部) = 0.289; \\ & Gain(D,觸感) = 0.006;Gain(D,色澤)=0.109; \end{split} \end{equation} \]
經過計算能夠獲得,紋理的信息增益最大,所以他被選爲劃分的屬性以下圖:
而後以紋理是「清晰爲例」,該集合\(D^1=\{1,2,3,4,5,6,8,10,15\}\),可用的屬性集合爲{ 色澤,根蒂,敲聲,臍部, 觸感}。所以,基於\(D^1\)又能夠計算出各個屬性的信息增益:
\[ \begin{equation} \begin{split} & Gain(D^1,色澤) = 0.043;Gain(D^1,根蒂) = 0.458;\\ &Gain(D^1,敲聲) = 0.331; Gain(D^1,觸感) = 0.458;\\ &Gain(D^1,臍部)=0.458; \end{split} \end{equation} \]
所以咱們能夠在「根蒂」,「觸感」,「臍部」中任意選擇其中一個做爲劃分屬性。最終獲得如下的決策樹:
經過上面的這些步驟,咱們就獲得了一顆關於西瓜的好壞的決策樹。ID3算法就是用信息增益做爲劃分標準。
上面的例子來自西瓜書,以及計算的結果也來自西瓜書。
在這裏有一個問題,\(Gain(D,屬性)\)越大,就必定可以做爲劃分標準嗎?假如它是一個無用的屬性呢?好比上圖中編號
這個屬性,若是在上面咱們選擇編號做爲根節點,那麼第一次劃分就可以獲得17個集合,每個集合只有1個樣本,\(Gain(D,編號)\)一定可以達到最大值。可是咱們知道,編號這個屬性在這裏是毫無做用的。若是將這個問題進行泛化,若是一個屬性在分類
中起到的做用給很小(也就是它對分類的影響很小),那麼咱們應該怎麼考慮呢?
這裏咱們可使用增益率
來做爲劃分的標準,定義以下
\[ \begin{equation} \begin{split} &Gain\_ratio(D,a) = \frac{Gain(D,a)}{IV(a)} \\ &其中\\ &IV(a) = -\sum_{v=1}^V\frac{D^v}{D}log_2\frac{D^v}{D} \end{split} \end{equation} \]
\(IV(a)\)稱之爲屬性\(a\)的固有值
(intrinsic value),屬性\(a\)的可能取值越多(劃分的\(D^v\)的集合越多),\(IV(a)\)就會越大。若像編號同樣進行劃分(每個劃分的集合中只有一個樣本),隨着編號的增多,\(IV(a)\)的取值以下圖:
其中著名的C4.5算法就是使用增益率
來劃分屬性。
除了這種解決方案,還有一種解決方法,基尼指數
做爲劃分標準,CART
決策樹使用這種方法。
前面咱們使用信息熵來表示集合的純度,這裏咱們使用基尼值
來表示:
設樣本集合爲\(D\),第\(k\)類樣本所佔比例爲\(p_k(k = 1,2,3,……n)\)
\[ \begin{equation} \begin{aligned} Gini(D) &= \sum_{k=1}^{|n|}\sum_{k'\neq k}p_kp_{k'}\\ &=1 - \sum_{k=1}^{|n|}p_k^2 \end{aligned} \end{equation} \]
\(Gini(D)\) 反映了從數據集中隨機抽取兩個樣本,其類別標記不一致的機率。所以, $Gini(D) $越大,則數據集越複雜,純度越低。
一樣,屬性\(a\)的基尼指數定義爲:
\[ Gini\_index(D,a) = \sum_{v=1}^V\frac{D^v}{D}Gini({D^v}) \]
所以,在咱們選擇合適的屬性進行劃分的時候,選擇劃分後基尼指數較小的屬性做爲劃分標準便可。
這個時候咱們再來看一看這幅圖,應該就看的懂了吧。
首先,咱們先說一下剪枝的目的——防止「過擬合」。在決策樹的學習過程當中,爲了保證正確性,會不斷的進行劃分,這樣可能會致使對於訓練樣本可以達到一個很好的準確性,可是對於測試集可能就不是很好了,這樣的模型不具有泛化性。下面來舉一個例子:
咱們有以下的數據集:
座標軸的上的每個點表明一個樣本,有\(x,y\)兩種屬性,其中,藍色的點表明類0,橙色的點表明類1。
當咱們使用決策樹進行訓練後,模型對於數據的識別區域以下,在粉紅色區域,其認爲裏面的點爲類0,藍色的區域爲類1:
你們可能發現一個問題,那就是這個區域劃分的太「細緻」了。由於數據是有噪音(noise)的,這樣劃分明顯是不合理的。這裏你們能夠看一看決策樹的圖片:
那麼如何來緩解這種問題呢?其中有一種方法就是去掉一些分支(剪枝)來下降過擬合的風險。
剪枝有兩種方案:
預剪枝是指在決策樹生成過程當中,對每一個結點在劃分前先進行估計,若當前結點的劃分不能帶來決策樹泛化性能提高,則中止劃分並將當前結點標記爲葉結點。
用通俗的話來講,就是若是進行劃分可以帶來更好的結果就進行劃分,不然不進行劃分。首先,咱們定義一個訓練集和一個驗證集以下:(西瓜書中間的例子)
上面一部分是訓練集,下面一部分是測試集。而後讓咱們來對訓練集(記住是訓練集)進行劃分,劃分的規則與上面的同樣。
下面的這幅圖是未剪枝的狀況。
那麼,剪枝是如何進行的呢?
首先,咱們先判斷「臍部」,若是咱們不對「臍部」進行劃分,也就是說這棵決策樹是這樣的:
只有一個好瓜的判斷結果(根據上面的算法流程圖,node節點直接就是葉子節點,其類別由樣本中最多的決定【這裏既能夠是好瓜也能夠是壞瓜,由於數量同樣】)
這樣下來,也就是說不管你什麼瓜過來我都判斷它是好瓜。使用驗證集進行驗證,驗證的精準度爲:\(\frac{3}{7} \times100\% = 42.9\%\)。若是進行劃分呢?
下圖即是進行劃分的狀況,其中被紅色圓圈框出來的部分表示驗證正確。
若是隻劃分「臍部」這個屬性,咱們能夠經過其來劃分好瓜和壞瓜,經過驗證機去測試,咱們能夠獲得劃分後的準確性爲:\(\frac{5}{7}\times100\%=71.4\% > 42.9\%\),因此選擇劃分。
下面即是進行前剪枝後的劃分結果,使用驗證集進行驗證,精度爲\(71.4\%\)
儘管該方案能夠下降過擬合的風險,並在必定程度上可以下降算法的複雜度,但也會帶來欠擬合的風險。由於會出現另一種狀況:有可能當前劃分不能提高泛化能力,可是在此基礎上的後續的劃分也許能夠致使性能顯著提升。
後剪枝則是先從訓練集生成一棵完整的決策樹,而後自底向上地對非葉結點進行考察,若將該結點對應的子樹替換爲葉結點能帶來決策樹泛化性能提高,則將該子樹替換爲葉結點.
後剪枝和前剪枝的不一樣在於後剪枝是在生成決策樹後再進行剪枝。順序是由下到上。
咱們繼續來看這幅圖:
經過驗證集,咱們易獲得該決策樹的識別率爲\(42.9\%\)。
讓咱們從新看一下數據吧,數據集和驗證集以下:
如今讓咱們來進行剪枝吧!!首先先看節點⑥,節點6中包含編號爲\(\{7(好瓜),15(壞瓜)\}\)的訓練樣本,所以咱們將節點⑥變成葉節點並標記爲「好瓜(壞瓜也ok)」。以下所示:
在這種狀況下,驗證集中序號爲\(\{4,8,11,12\}\)驗證正確,精度調高到\(\frac{4}{7} \times 100\%= 57.1\%\),所以能夠進行剪枝。
考慮結點⑤,包含編號爲\(\{6,7,15\}\),將其變成葉節點(標記爲「好瓜」),使用驗證集去驗證,其精度仍爲\(57.1\%\),沒有提升,進行考慮。同理可獲得下面的這副圖片:
最終,該決策樹的精度爲\(71.4\%\)
比較預剪枝和後剪枝,後剪枝保留的分支更多,同時後剪枝的欠擬合的風險很小,泛化性能每每優於預剪枝決策樹,可是顯而易見,訓練的時間要比預剪枝大得多。
什麼是隨機森林呢?隨機森林是一個包含多個決策樹的分類器,由不少決策樹構成,不一樣的決策樹之間沒有關聯。當咱們進行分類任務時,森林中的每一棵決策樹都會分別對樣本進行判斷和分類,每一個決策樹會獲得一個本身的分類結果,決策樹的分類結果中哪個分類最多,那麼隨機森林就會把這個結果當作最終的結果。 (emm,少樹服從多樹)。好像很簡單的樣子,可是這裏有一個問題,那就是隨機森林中有多個決策樹,那麼,咱們如何用已有的數據集去構建這麼多的決策樹呢?
首先咱們要明白,決策樹是不一樣的,那麼訓練決策樹所須要的數據也不一樣。那麼具體該如何選擇呢?既然是隨機森林,那麼它確定是隨機的!!它的隨機有兩層含義:
樣本隨機使用的是Bagging算法(Bootstrap aggregating,引導彙集算法)又稱之爲裝袋算法。算法的流程以下:
給定一個訓練集大小爲\(n\)的訓練集\(D\),Bagging算法從中間隨機的、有放回的選出\(m\)個大小爲\(n'\)的子集\(D_i\)做爲新的訓練集。
ps:經過以上這種取樣獲得的集合\(D_i\)中間可能會有重複的元素(由於是有放回的抽取元素)
若樣本有\(M\)個屬性時,隨機從這\(M\)個屬性中選取出\(m\)個屬性(無放回),知足條件\(m < M\)。
ps:在這種狀況下,\(m\)個屬性中是沒有重複的屬性的。
經過上面的樣本隨機和屬性隨機,咱們就能夠構建出不少棵不一樣的決策樹了,而後組成一個森林,裏面住着熊大和熊二,在一塊兒快樂的生活。
優缺點的整理來自這裏,基本上全部的文章都是這個說法,不一樣的在於文字的多少罷了!
優勢
缺點
決策樹的概念就暫時介紹到這裏了,儘管內容有點多,可是仍是挺好理解的,很相似於人類的思考方式。在下一篇的博客中,將使用scikit-learn工具包,基於決策樹來對數據進行分類。決策樹還有不少知識和算法,可是至少咱們得掌握基本的概念。