現實生活中的數據集中的樣本通常在某系屬性上是缺失的,如果屬性值缺失的樣本數量比較少,我們可以直接簡單粗暴的把不完備的樣本刪除掉,但是如果有大量的樣本都有屬性值的缺失,那么就不能簡單地刪除,因為這樣刪除了大量的樣本,對於機器學習模型而言損失了大量有用的信息,訓練出來的模型性能會受到影響。這篇博客就來介紹在決策樹中是如何處理屬性值有缺失的樣本的,本篇博客使用的數據集如下(數據集來自周志華《機器學習》):
在決策樹中處理含有缺失值的樣本的時候,需要解決兩個問題:
如何在屬性值缺失的情況下進行划分屬性的選擇?(比如“色澤”這個屬性有的樣本在該屬性上的值是缺失的,那么該如何計算“色澤”的信息增益?)
給定划分屬性,若樣本在該屬性上的值是缺失的,那么該如何對這個樣本進行划分?(即到底把這個樣本划分到哪個結點里?)
下面就來介紹如何解決這兩個問題:
比較發現,“紋理”在所有屬性中的信息增益值最大,因此,“紋理”被選為划分屬性,用於對根節點進行划分。划分結果為:“紋理=稍糊”分支:{7,9,13,14,17},“紋理=清晰”分支:{1,2,3,4,5,6,15},“紋理=模糊”分支:{11,12,16}。如下圖所示:
那么問題來了,編號為{8,10}的樣本在“紋理”這個屬性上是缺失的,該被划分到哪個分支里?前面講過了,這兩個樣本會同時進入到三個分支里,只不過進入到每個分支后權重會被調整(前面也說過,在剛開始時每個樣本的權重都初始化為1)。編號為8的樣本進入到三個分支里后,權重分別調整為5/15,7/15 和 3/15;編號為10的樣本同樣的操作和權重。因此,經過第一次划分后的決策樹如下圖所示:
我們都知道構造決策樹的過程是一個遞歸過程,原來不打算繼續介紹遞歸過程了,但是因為權重發生了變化,所以繼續介紹下遞歸過程。接下來,遞歸執行“紋理=稍糊”這個分支,樣本集D = {7,8,9,10,13,14,17},共7個樣本。如下圖所示:
下面來看具體的計算過程:
對比能夠發現屬性“敲聲”的星系增益值最大,因此選擇“敲聲”作為划分屬性,划分后的決策樹如下圖所示:
接下來對分支{敲聲 = 沉悶}即結點{9,14,17}進行划分,根據博客決策樹(一)介紹的三種遞歸返回情形,結點{9,14,17}因為包含的樣本全部屬於同一類別,因此無需划分,直接把結點{9,14,17}標記為葉結點,如下圖所示:
根據遞歸過程,接下來對分支“敲聲 = 濁響”即結點{7,8,13}進行划分,計算過程和上面一樣,雖然我也算過了,但是不再貼出來了,需要注意的是樣本的權重是1/3。計算完比較能夠知道屬性“臍部”的信息增益值最大,因此選擇“臍部”作為划分屬性,划分完的決策樹如下圖所示:
接下來,繼續,對於結點{13},因為就一個樣本了,直接把該結點標記為葉結點,類別為“壞瓜”;遞歸到結點{7,8},因為樣本類別相同,所以也標記為葉結點,類別為“好瓜”;遞歸到結點“臍部=平坦”,因為這個結點不包含任何樣本為空集,因此,把該結點標記為葉結點,類別設置為父節點中多數類的類別,即為“好瓜”。因此“紋理=稍糊”這顆子樹構造完畢,如下圖所示:
接下來,只需遞歸的重復上述過程即可,即能訓練出一顆完整的決策樹,最終的決策樹如下圖所示(該圖片來自西瓜書):
以上介紹了決策樹在訓練階段是如何處理有缺失值的樣本的,從而構造出一顆樹。當我們構造完一棵樹后,有新的樣本過來就可以對新的樣本進行分類了,那么問題來了,如果測試樣本屬性也有缺失值那要怎么辦?
如果有專門處理缺失值的分支,就走這個分支。
用這篇論文提到的方法來確定屬性a的最有可能取值,然后走相應的分支。
從屬性a最常用的分支走
同時探查所有的分支,並組合他們的結果來得到類別對應的概率,(取概率最大的類別)
將最有可能的類別賦給該樣本。
上面的這么多方法只是提一下,C4.5中采用的方法是:測試樣本在該屬性值上有缺失值,那么就同時探查(計算)所有分支,然后算每個類別的概率,取概率最大的類別賦值給該樣本。好像這個方法並不怎么好用語言描述,我們直接看例子吧,相信你看完例子就立刻明白了,由於這是今天(19年4月9號)新添加的內容,上面西瓜書上的例子當時計算的權重沒有保留下來,因此這里直接引用Quinlan在著作《C4.5: Programs For Machine Learning》里舉的例子(在該書的p31-p32),先看數據集:
注意,編號12的樣本屬性outlook上有缺失值,我們基於上面介紹的構造決策樹的方法來構造一顆決策樹(C4.5用信息增益率,除此之外,構造方法與上述方法一致),構造出來的決策樹為:
上圖中,紅色數字表示樣本編號,括號內的值表示樣本12的權重。葉結點中的數值(N/E),比如no(3.38/0.38)表示這個葉子節點被標記為no也就是don't play,3.38=1+1+0.38,編號1,2的樣本沒有缺失值,權重為1進來的,編號12進入到這個葉結點時權重為0.38。
如果,此時我們有一條樣本:outlook=sunny, temperature=70, humidity=?, windy=false 能夠看出這條樣本的屬性humidity是缺失的,那么構建好的決策怎么對這個樣本分類?
首先這個樣本的outlook為sunny,肯定會進入到“humidity”這個節點里,因為該樣本humidity屬性值缺失,兩個分支都有可能進入:
如果humidity<=75,則類別為play。
如果humidity>75,don't play的概率為3/3.38=88.7%,play的概率為0.38/3.38=11.3%。
大家肯定有一點疑惑,就是上面humidity>75里,明明葉結點的label為no啊,那應該是don't play啊,怎么還有don't play和paly的概率,這是Quinlan的定義,上面的(N/E)中,N,E的定義分別是:
N表示該葉節點中所包含的總樣本數(總權重更恰當點)
E表示與該葉節點的類別不同的樣本數(權重),比如上面第二個葉結點的label為no(dont play),包含的樣本數為1,2,8,12(0.38),這里編號12的樣本類別為play,因此與該葉結點的類別不同,所以這葉結點會產生11.3%的概率為play。
那么根據上面介紹的,此時同時探查(計算)所有分支,然后算每個類別的概率,取概率最大的類別賦值給該樣本。這里humidity下就有兩個分支,<=75 => yes 和 >75 =>no。下面分別計算這兩個類別的概率:
yes(play):2.0/5.38 * 100% + 3.38/5.38 * 11.3% = 44.27%
no(don't play): 3.38/5.38 * 88.7% = 55.73%
因此no的概率更大,所以該測試樣本的類別被指派為no,即don't play。