决策树算法及实现
在計(jì)算機(jī)科學(xué)中,樹(shù)是一種很重要的數(shù)據(jù)結(jié)構(gòu),比如我們最為熟悉的二叉查找樹(shù)(Binary Search Tree),紅黑樹(shù)(Red-Black Tree)等,通過(guò)引入樹(shù)這種數(shù)據(jù)結(jié)構(gòu),我們可以很快地縮小問(wèn)題規(guī)模,實(shí)現(xiàn)高效的查找。
在監(jiān)督學(xué)習(xí)中,面對(duì)樣本中復(fù)雜多樣的特征,選取什么樣的策略可以實(shí)現(xiàn)較高的學(xué)習(xí)效率和較好的分類(lèi)效果一直是科學(xué)家們探索的目標(biāo)。那么,樹(shù)這種結(jié)構(gòu)到底可以如何用于機(jī)器學(xué)習(xí)中呢?我們先從一個(gè)游戲開(kāi)始。
我們應(yīng)該都玩過(guò)或者聽(tīng)過(guò)這么一種游戲:游戲中,出題者寫(xiě)下一個(gè)明星的名字,其他人需要猜出這個(gè)人是誰(shuí)。當(dāng)然,如果游戲規(guī)則僅此而已的話,幾乎是無(wú)法猜出來(lái)的,因?yàn)閱?wèn)題的規(guī)模太大了。為了降低游戲的難度,答題者可以向出題者問(wèn)問(wèn)題,而出題者必須準(zhǔn)確回答是或者否,答題者依據(jù)回答提出下一個(gè)問(wèn)題,如果能夠在指定次數(shù)內(nèi)確定謎底,即為勝出。加入了問(wèn)答規(guī)則之后,我們是否有可能猜出謎底呢?我們先實(shí)驗(yàn)一下,現(xiàn)在我已經(jīng)寫(xiě)下了一個(gè)影視明星的名字,而你和我的問(wèn)答記錄如下:
是男的嗎?Y
是亞洲人嗎?Y
是中國(guó)人嗎?N
是印度人嗎?Y
?……
雖然只有短短四個(gè)問(wèn)題,但是我們已經(jīng)把答案的范圍大大縮小了,那么接下,第5個(gè)問(wèn)題你應(yīng)該如何問(wèn)呢?我相信你應(yīng)該基本可以鎖定答案了,因?yàn)槲铱催^(guò)的印度電影就那么幾部。我們將上面的信息結(jié)構(gòu)化如下圖所示:
在上面的游戲中,我們針對(duì)性的提出問(wèn)題,每一個(gè)問(wèn)題都可以將我們的答案范圍縮小,在提問(wèn)中和回答者有相同知識(shí)背景的前提下,得出答案的難度比我們想象的要小很多。
回到我們最初的問(wèn)題中,如何將樹(shù)結(jié)構(gòu)用于機(jī)器學(xué)習(xí)中?結(jié)合上面的圖,我們可以看出,在每一個(gè)節(jié)點(diǎn),依據(jù)問(wèn)題答案,可以將答案劃分為左右兩個(gè)分支,左分支代表的是Yes,右分支代表的是No,雖然為了簡(jiǎn)化,我們只畫(huà)出了其中的一條路徑,但是也可以明顯看出這是一個(gè)樹(shù)形結(jié)構(gòu),這便是決策樹(shù)的原型。
1.決策樹(shù)算法簡(jiǎn)介
我們面對(duì)的樣本通常具有很多個(gè)特征,正所謂對(duì)事物的判斷不能只從一個(gè)角度,那如何結(jié)合不同的特征呢?決策樹(shù)算法的思想是,先從一個(gè)特征入手,就如同我們上面的游戲中一樣,既然無(wú)法直接分類(lèi),那就先根據(jù)一個(gè)特征進(jìn)行分類(lèi),雖然分類(lèi)結(jié)果達(dá)不到理想效果,但是通過(guò)這次分類(lèi),我們的問(wèn)題規(guī)模變小了,同時(shí)分類(lèi)后的子集相比原來(lái)的樣本集更加易于分類(lèi)了。然后針對(duì)上一次分類(lèi)后的樣本子集,重復(fù)這個(gè)過(guò)程。在理想的情況下,經(jīng)過(guò)多層的決策分類(lèi),我們將得到完全純凈的子集,也就是每一個(gè)子集中的樣本都屬于同一個(gè)分類(lèi)。
比如上圖中,平面坐標(biāo)中的六個(gè)點(diǎn),我們無(wú)法通過(guò)其x坐標(biāo)或者y坐標(biāo)直接就將兩類(lèi)點(diǎn)分開(kāi)。采用決策樹(shù)算法思想:我們先依據(jù)y坐標(biāo)將六個(gè)點(diǎn)劃分為兩個(gè)子類(lèi)(如水平線所示),水平線上面的兩個(gè)點(diǎn)是同一個(gè)分類(lèi),但是水平線之下的四個(gè)點(diǎn)是不純凈的。但是沒(méi)關(guān)系,我們對(duì)這四個(gè)點(diǎn)進(jìn)行再次分類(lèi),這次我們以x左邊分類(lèi)(見(jiàn)圖中的豎線),通過(guò)兩層分類(lèi),我們實(shí)現(xiàn)了對(duì)樣本點(diǎn)的完全分類(lèi)。這樣,我們的決策樹(shù)的偽代碼實(shí)現(xiàn)如下:
if?y?>?a:
????output dot
else:
????if?x?<?b:
??????????output cross
????else:
??????????output?dot
由這個(gè)分類(lèi)的過(guò)程形成一個(gè)樹(shù)形的判決模型,樹(shù)的每一個(gè)非葉子節(jié)點(diǎn)都是一個(gè)特征分割點(diǎn),葉子節(jié)點(diǎn)是最終的決策分類(lèi)。如下圖所示:
將新樣本輸入決策樹(shù)進(jìn)行判決時(shí),就是將樣本在決策樹(shù)上自頂向下,依據(jù)決策樹(shù)的節(jié)點(diǎn)規(guī)則進(jìn)行遍歷,最終落入的葉子節(jié)點(diǎn)就是該樣本所屬的分類(lèi)。
2.決策樹(shù)算法流程
上面我們介紹決策樹(shù)算法的思想,可以簡(jiǎn)單歸納為如下兩點(diǎn):
每次選擇其中一個(gè)特征對(duì)樣本集進(jìn)行分類(lèi)
對(duì)分類(lèi)后的子集遞歸進(jìn)行步驟1
看起來(lái)是不是也太簡(jiǎn)單了呢?實(shí)際上每一個(gè)步驟我們還有很多考慮的。在第一個(gè)步驟中,我們需要考慮的一個(gè)最重要的策略是,選取什么樣的特征可以實(shí)現(xiàn)最好的分類(lèi)效果,而所謂的分類(lèi)效果好壞,必然也需要一個(gè)評(píng)價(jià)的指標(biāo)。在上文中,我們都用純凈來(lái)說(shuō)明分類(lèi)效果好,那何為純凈呢?直觀來(lái)說(shuō)就是集合中樣本所屬類(lèi)別比較集中,最理想的是樣本都屬于同一個(gè)分類(lèi)。樣本集的純度可以用熵來(lái)進(jìn)行衡量。
在信息論中,熵代表了一個(gè)系統(tǒng)的混亂程度,熵越大,說(shuō)明我們的數(shù)據(jù)集純度越低,當(dāng)我們的數(shù)據(jù)集都是同一個(gè)類(lèi)別的時(shí)候,熵為0,熵的計(jì)算公式如下:
其中,P(xi)表示概率,b在此處取2。比如拋硬幣的時(shí)候,正面的概率就是1/2,反面的概率也是1/2,那么這個(gè)過(guò)程的熵為:
可見(jiàn),由于拋硬幣是一個(gè)完全隨機(jī)事件,其結(jié)果正面和反面是等概率的,所以具有很高的熵。假如我們觀察的是硬幣最終飛行的方向,那么硬幣最后往下落的概率是1,往天上飛的概率是0,帶入上面的公式中,可以得到這個(gè)過(guò)程的熵為0,所以,熵越小,結(jié)果的可預(yù)測(cè)性就越強(qiáng)。在決策樹(shù)的生成過(guò)程中,我們的目標(biāo)就是要?jiǎng)澐趾蟮淖蛹衅潇刈钚?#xff0c;這樣后續(xù)的的迭代中,就更容易對(duì)其進(jìn)行分類(lèi)。
既然是遞歸過(guò)程,那么就需要制定遞歸的停止規(guī)則。在兩種情況下我們停止進(jìn)一步對(duì)子集進(jìn)行劃分,其一是劃分已經(jīng)達(dá)到可以理想效果了,另外一種就是進(jìn)一步劃分收效甚微,不值得再繼續(xù)了。用專(zhuān)業(yè)術(shù)語(yǔ)總結(jié)終止條件有以下幾個(gè):
子集的熵達(dá)到閾值
子集規(guī)模夠小
進(jìn)一步劃分的增益小于閾值
其中,條件3中的增益代表的是一次劃分對(duì)數(shù)據(jù)純度的提升效果,也就是劃分以后,熵減少越多,說(shuō)明增益越大,那么這次劃分也就越有價(jià)值,增益的計(jì)算公式如下:
Gain
上述公式可以理解為:計(jì)算這次劃分之后兩個(gè)子集的熵之和相對(duì)劃分之前的熵減少了多少,需要注意的是,計(jì)算子集的熵之和需要乘上各個(gè)子集的權(quán)重,權(quán)重的計(jì)算方法是子集的規(guī)模占分割前父集的比重,比如劃分前熵為e,劃分為子集A和B,大小分別為m和n,熵分別為e1和e2,那么增益就是e - m/(m + n) * e1 - n/(m + n) * e2。
3. 決策樹(shù)算法實(shí)現(xiàn)
有了上述概念,我們就可以開(kāi)始開(kāi)始決策樹(shù)的訓(xùn)練了,訓(xùn)練過(guò)程分為:
選取特征,分割樣本集
計(jì)算增益,如果增益夠大,將分割后的樣本集作為決策樹(shù)的子節(jié)點(diǎn),否則停止分割
遞歸執(zhí)行上兩步
上述步驟是依照ID3的算法思想(依據(jù)信息增益進(jìn)行特征選取和分裂),除此之外還有C4.5以及CART等決策樹(shù)算法。
算法框架如下:
class?DecisionTree(object):
????def fit(self,?X,?y):
????????# 依據(jù)輸入樣本生成決策樹(shù)
????????self.root?=?self._build_tree(X,?y)
?
????def _build_tree(self,?X,?y,?current_depth=0):
????????#1. 選取最佳分割特征,生成左右節(jié)點(diǎn)
????????#2. 針對(duì)左右節(jié)點(diǎn)遞歸生成子樹(shù)
??????
????def predict_value(self,?x,?tree=None):
????????# 將輸入樣本傳入決策樹(shù)中,自頂向下進(jìn)行判定
????????# 到達(dá)葉子節(jié)點(diǎn)即為預(yù)測(cè)值
在上述代碼中,實(shí)現(xiàn)決策樹(shù)的關(guān)鍵是遞歸構(gòu)造子樹(shù)的過(guò)程,為了實(shí)現(xiàn)這個(gè)過(guò)程,我們需要做好三件事:分別是節(jié)點(diǎn)的定義,最佳分割特征的選擇,遞歸生成子樹(shù)。
3.1 節(jié)點(diǎn)定義
決策樹(shù)的目的是用于分類(lèi)預(yù)測(cè),即各個(gè)節(jié)點(diǎn)需要選取輸入樣本的特征,進(jìn)行規(guī)則判定,最終決定樣本歸屬到哪一棵子樹(shù),基于這個(gè)目的,決策樹(shù)的每一個(gè)節(jié)點(diǎn)需要包含以下幾個(gè)關(guān)鍵信息:
判決特征:當(dāng)前節(jié)點(diǎn)針對(duì)哪一個(gè)特征進(jìn)行判決
判決規(guī)則:對(duì)于二類(lèi)問(wèn)題,這個(gè)規(guī)則一般是一個(gè)布爾表達(dá)式
左子樹(shù):判決為T(mén)RUE的樣本
右子樹(shù):判決為FALSE的樣本
決策樹(shù)節(jié)點(diǎn)的定義代碼如下所示:
class?DecisionNode():
????
????def __init__(self,?feature_i=None,?threshold=None,
?????????????????value=None,?true_branch=None,?false_branch=None):
????????self.feature_i?=?feature_i??# 用于測(cè)試的特征對(duì)應(yīng)的索引
????????self.threshold?=?threshold??# 判斷規(guī)則:>=threshold為true
????????self.value?=?value??# 如果是葉子節(jié)點(diǎn),用于保存預(yù)測(cè)結(jié)果
????????self.true_branch?=?true_branch??# 左子樹(shù)
????????self.false_branch?=?false_branch??# 右子樹(shù)
3.2 特征選取
特征選取是構(gòu)造決策樹(shù)最關(guān)鍵的步驟,其目的是選出能夠?qū)崿F(xiàn)分割結(jié)果最純凈的那個(gè)特征,其操作流程的代碼如下:
# 遍歷樣本集中的所有特征,針對(duì)每一個(gè)特征計(jì)算最佳分割點(diǎn)
# 再選取最佳的分割特征
for?feature_i?in?range(n_features):
????# 遍歷集合中某個(gè)特征的所有取值
????for?threshold?in?unique_values:
????????# 以當(dāng)前特征值作為閾值進(jìn)行分割
????????Xy1,?Xy2?=?divide_on_feature(X_y,?feature_i,?threshold)
????????# 計(jì)算分割后的增益
????????gain?=?gain(y,?y1,?y2)
????????# 記錄最佳分割特征,最佳分割閾值
????????if?gain?>?largest_gain:
????????largest_gain?=?gain
????????????best_criteria?=?{
????????????????"feature_i":?feature_i,
????????????????"threshold":?threshold
????????????????}
3.3 節(jié)點(diǎn)分裂
節(jié)點(diǎn)分裂的時(shí)候有兩條處理分支,如果增益夠大,就分裂為左右子樹(shù),如果增益很小,就停止分裂,將這個(gè)節(jié)點(diǎn)直接作為葉子節(jié)點(diǎn)。節(jié)點(diǎn)分裂和Gain(分割后增益)的計(jì)算可以做一個(gè)優(yōu)化,在上一個(gè)步驟中,我們尋找最優(yōu)分割點(diǎn)的時(shí)候其實(shí)就可以將最佳分裂子集和Gain計(jì)算并保存下來(lái),將上一步中的for循環(huán)改寫(xiě)為:
# 以當(dāng)前特征值作為閾值進(jìn)行分割
Xy1,?Xy2?=?divide_on_feature(X_y,?feature_i,?threshold)
# 計(jì)算分割后的熵
gain?=?gain(y,?y1,?y2)
# 記錄最佳分割特征,最佳分割閾值
if?gain?>?largest_gain:
????largest_gain?=?gain
????????best_criteria?=?{
????????"feature_i":?feature_i,
????????"threshold":?threshold?,
????????}
????best_sets?=?{
????????"left":?Xy1,
????????"right":?Xy2,
????????"gain":?gain
????????}
為了防止過(guò)擬合,需要設(shè)置合適的停止條件,比如設(shè)置Gain的閾值,如果Gain比較小,就沒(méi)有必要繼續(xù)進(jìn)行分割,所以接下來(lái),我們就可以依據(jù)gain來(lái)決定分割策略:
if?best_sets["gain"]?>?MIN_GAIN:
????# 對(duì)best_sets["left"]進(jìn)一步構(gòu)造子樹(shù),并作為父節(jié)點(diǎn)的左子樹(shù)
????# 對(duì)best_sets["right"]進(jìn)一步構(gòu)造子樹(shù),并作為父節(jié)點(diǎn)的右子樹(shù)
????...
else:
????# 直接將父節(jié)點(diǎn)作為葉子節(jié)點(diǎn)
????...
下面,我們結(jié)合一組實(shí)驗(yàn)數(shù)據(jù)來(lái)學(xué)習(xí)決策樹(shù)的訓(xùn)練方法。實(shí)驗(yàn)數(shù)據(jù)來(lái)源于這里,下表中的數(shù)據(jù)是一組消費(fèi)調(diào)查結(jié)果,我們訓(xùn)練決策樹(shù)的目的,就是構(gòu)造一個(gè)分類(lèi)算法,使得有新的用戶數(shù)據(jù)時(shí),我們依據(jù)訓(xùn)練結(jié)果去推斷一個(gè)用戶是否購(gòu)買(mǎi)這個(gè)商品:
| 36-55 | master’s | high | single | yes |
| 18-35 | high school | low | single | no |
| 36-55 | master’s | low | single | yes |
| 18-35 | bachelor’s | high | single | no |
| ?< 18 | high school | low | single | yes |
| 18-35 | bachelor’s | high | married | no |
| 36-55 | bachelor’s | low | married | no |
| > 55 | bachelor’s | high | single | yes |
| 36-55 | master’s | low | married | no |
| > 55 | master’s | low | married | yes |
| 36-55 | master’s | high | single | yes |
| > 55 | master’s | high | single | yes |
| 18 | high school | high | single | no |
| 36-55 | master’s | low | single | yes |
| 36-55 | high school | low | single | yes |
| ?< 18 | high school | low | married | yes |
| 18-35 | bachelor’s | high | married | no |
| > 55 | high school | high | married | yes |
| > 55 | bachelor’s | low | single | yes |
| 36-55 | high school | high | married | no |
從表中可以看出,我們一共有20組調(diào)查樣本,每一組樣本包含四個(gè)特征,分別是年齡段,學(xué)歷,收入,婚姻狀況,而最后一列是所屬分類(lèi),在這個(gè)問(wèn)題中就代表是否購(gòu)買(mǎi)了該產(chǎn)品。
監(jiān)督學(xué)習(xí)就是在每一個(gè)樣本都有正確答案的前提下,用算法預(yù)測(cè)結(jié)果,然后根據(jù)預(yù)測(cè)情況的好壞,調(diào)整算法參數(shù)。在決策樹(shù)中,預(yù)測(cè)的過(guò)程就是依據(jù)各個(gè)特征劃分樣本集,評(píng)價(jià)預(yù)測(cè)結(jié)果的好壞標(biāo)準(zhǔn)是劃分結(jié)果的純度。
為了方便處理,我們對(duì)樣本數(shù)據(jù)進(jìn)行了簡(jiǎn)化,將年齡特征按照樣本的特點(diǎn),轉(zhuǎn)化為離散的數(shù)據(jù),比如小于18對(duì)應(yīng)0,18對(duì)應(yīng)1,18-35對(duì)應(yīng)2,36-55對(duì)應(yīng)3,大于55對(duì)應(yīng)4,以此類(lèi)推,同樣其他的特征也一樣最數(shù)字化處理,教育水平分別映射為0(hight school),1(bachelor’s),2(master’s),收入映射為0(low)和1(hight), 婚姻狀況同樣映射為0(single), 1(married),最終處理后的樣本,放到一個(gè)numpy矩陣中,如下所示:
X_y?=?np.array(
????????[[3,?2,?1,?0,?1],
?????????[2,?0,?0,?0,?0],
?????????[3,?2,?0,?0,?1],
?????????[2,?1,?1,?0,?0],
?????????[0,?0,?0,?0,?1],
?????????[2,?1,?1,?1,?0],
?????????[3,?1,?0,?1,?0],
?????????[4,?1,?1,?0,?1],
?????????[3,?2,?0,?1,?0],
?????????[4,?2,?0,?1,?1],
?????????[3,?2,?1,?0,?1],
?????????[4,?2,?1,?0,?1],
?????????[1,?0,?1,?0,?0],
?????????[3,?2,?0,?0,?1],
?????????[3,?0,?0,?0,?1],
?????????[0,?0,?0,?1,?1],
?????????[2,?1,?1,?1,?0],
?????????[4,?0,?1,?1,?1],
?????????[4,?1,?0,?0,?1],
?????????[3,?0,?1,?1,?0]]
????)
4. 新樣本預(yù)測(cè)
依照上面的算法構(gòu)造決策樹(shù),我們將決策樹(shù)打印出來(lái),如下所示:
--?Classification?Tree?--
0?:?4?
???T?->?1
???F?->?3?:?1?
??????T?->?0?:?2?
????????????T?->?0
????????????F?->?1
??????F?->?0?:?3?
????????????T?->?1
????????????F?->?0?:?1?
????????????????????????T?->?0
????????????????????????F?->?1
其中,冒號(hào)前代表選擇的分割特征,冒號(hào)后面代表判別規(guī)則,二者組合起來(lái)就是一個(gè)決策樹(shù)的非葉子節(jié)點(diǎn),每個(gè)非葉子節(jié)點(diǎn)進(jìn)一步分割為分為T(mén)rue和False分支,對(duì)于葉子節(jié)點(diǎn)箭頭后面表示最終分類(lèi),0表示不購(gòu)買(mǎi),1表示購(gòu)買(mǎi)。由于我們的數(shù)據(jù)做過(guò)簡(jiǎn)化,所以上述結(jié)果不太直觀,我們將對(duì)應(yīng)的特征以及判斷規(guī)則翻譯一下:
年齡?:?大于55?
???是?->?購(gòu)買(mǎi)
???否?->?收入?:?高?
??????是?->?年齡?:?大于18?
????????????是?->?不購(gòu)買(mǎi)
????????????否?->?購(gòu)買(mǎi)
??????否?->?年齡?:?大于36?
????????????是?->?購(gòu)買(mǎi)
????????????否?->?年齡?:?大于等于18?
????????????????????????是?->?不購(gòu)買(mǎi)
????????????????????????否?->?購(gòu)買(mǎi)
決策樹(shù)構(gòu)造完之后,我們就可以用來(lái)進(jìn)行新樣本的分類(lèi)了。決策樹(shù)的預(yù)測(cè)過(guò)程十分容易理解,只需要將從根節(jié)點(diǎn)開(kāi)始,按照節(jié)點(diǎn)定義的規(guī)則進(jìn)行判決,選擇對(duì)應(yīng)的子樹(shù),并重復(fù)這個(gè)過(guò)程,直到葉子節(jié)點(diǎn)即可。決策樹(shù)的預(yù)測(cè)功能實(shí)現(xiàn)代碼如下:
def predict_value(self,?x,?tree=None):
????????# 如果當(dāng)前節(jié)點(diǎn)是葉子節(jié)點(diǎn),直接輸出其值
????????if?tree.value?is?not?None:
????????????return?tree.value
????????# 否則將x按照當(dāng)前節(jié)點(diǎn)的規(guī)則進(jìn)行判決
????????# 如果判決為true選擇左子樹(shù),否則選擇右子樹(shù),
????????feature_value?=?x[tree.feature_i]
????????if?feature_value?>=?tree.threshold:
????????????branch?=?tree.true_branch
????????else:
????????????branch?=?tree.false_branch
????????# 在選中的子樹(shù)上遞歸進(jìn)行判斷
????????return?self.predict_value(x,?branch)
5. 總結(jié)
決策樹(shù)是一種簡(jiǎn)單常用的分類(lèi)器,通過(guò)訓(xùn)練好的決策樹(shù)可以實(shí)現(xiàn)對(duì)未知的數(shù)據(jù)進(jìn)行高效分類(lèi)。從我們的例子中也可以看出,決策樹(shù)模型具有較好的可讀性和描述性,有助于輔助人工分析;此外,決策樹(shù)的分類(lèi)效率高,一次構(gòu)建后可以反復(fù)使用,而且每一次預(yù)測(cè)的計(jì)算次數(shù)不超過(guò)決策樹(shù)的深度。
當(dāng)然,決策樹(shù)也有其缺點(diǎn)。對(duì)于連續(xù)的特征,比較難以處理,對(duì)于多分類(lèi)問(wèn)題,計(jì)算量和準(zhǔn)確率都不理想。此外,在實(shí)際應(yīng)用中,由于其最底層葉子節(jié)點(diǎn)是通過(guò)父節(jié)點(diǎn)中的單一規(guī)則生成的,所以通過(guò)手動(dòng)修改樣本特征比較容易欺騙分類(lèi)器,比如在攔擊郵件識(shí)別系統(tǒng)中,用戶可能通過(guò)修改某一個(gè)關(guān)鍵特征,就可以騙過(guò)垃圾郵件識(shí)別系統(tǒng)。從實(shí)現(xiàn)上來(lái)講,由于樹(shù)的生成采用的是遞歸,隨著樣本規(guī)模的增大,計(jì)算量以及內(nèi)存消耗會(huì)變得越來(lái)越大。
此外,過(guò)擬合也是決策樹(shù)面臨的一個(gè)問(wèn)題,完全訓(xùn)練的決策樹(shù)(未進(jìn)行剪紙,未限制Gain的閾值)能夠100%準(zhǔn)確地預(yù)測(cè)訓(xùn)練樣本,因?yàn)槠涫菍?duì)訓(xùn)練樣本的完全擬合,但是,對(duì)與訓(xùn)練樣本以外的樣本,其預(yù)測(cè)效果可能會(huì)不理想,這就是過(guò)擬合。解決決策樹(shù)的過(guò)擬合,除了上文說(shuō)到的通過(guò)設(shè)置Gain的閾值作為停止條件之外,通常還需要對(duì)決策樹(shù)進(jìn)行剪枝,常用的剪枝策略有:
Pessimistic Error Pruning:悲觀錯(cuò)誤剪枝
Minimum Error Pruning:最小誤差剪枝
Cost-Complexity Pruning:代價(jià)復(fù)雜剪枝
?Error-Based Pruning:基于錯(cuò)誤的剪枝,即對(duì)每一個(gè)節(jié)點(diǎn),都用一組測(cè)試數(shù)據(jù)集進(jìn)行測(cè)試,如果分裂之后,能夠降低錯(cuò)誤率,再繼續(xù)分裂為兩棵子樹(shù),否則直接作為葉子節(jié)點(diǎn)。
Critical Value Pruning:關(guān)鍵值剪枝,這就是上文中提到的設(shè)置Gain的閾值作為停止條件。
我們以最簡(jiǎn)單的方式展示了ID3決策樹(shù)的實(shí)現(xiàn)方式,如果想要了解不同類(lèi)型的決策樹(shù)的差別,可以參考(https://www.quora.com/What-are-the-differences-between-ID3-C4-5-and-CART)。
另外,關(guān)于各種機(jī)器學(xué)習(xí)算法的實(shí)現(xiàn),強(qiáng)烈推薦參考Github倉(cāng)庫(kù)ML-From-Scratch,下載代碼之后,通過(guò)pip install -r requirements.txt安裝依賴(lài)庫(kù)即可運(yùn)行代碼。
來(lái)源:?ZPPenny
www.jianshu.com/p/c4d0837e9439
總結(jié)
- 上一篇: 程序员必知的 Python 陷阱与缺陷列
- 下一篇: 循环递归,相互结合,释放数据的价值