一張機器自己寫出的流程圖
你已經認識了線性迴歸和邏輯迴歸,它們在資料中畫出一條筆直的分界線。而決策樹走的是一條全然不同、卻極其貼近人類直覺的路:它一連串地問是/否問題。「這位乘客年齡小於10歲嗎?如果是,他坐的是三等艙嗎?如果不是,……」——每一個回答都把你送往一根分支,直到抵達一片葉子,告訴你最終的猜測。這正是你可能會親手畫出來做決策的那張流程圖,只不過這些問題是機器自己琢磨出來的。
它是怎麼挑選這些問題的呢?貪心地,一次挑一個。在每個節點上,它掃描每一個特徵、每一個可能的切分點,選出那個能讓分出的各組盡可能純淨的切分——也就是說,每一組都明顯偏向某一個標籤。衡量這種「雜亂」的一種常見辦法是資訊熵:一個所有樣本答案都相同的節點,熵為零;樹要做的,就是不斷切分,直到不純度降下來。然後它在每個子節點裡重複同樣的事,越鑽越深。
那棵把答案抄下來的樹
麻煩就在這裡。如果你放任一棵樹一直切下去,它不會停手,直到每片葉子都完美純淨——常常是一個孤零零的訓練樣本獨佔一片葉子。到了那一步,這棵樹並沒有*學會*規律,而是把訓練資料背了下來,給每個點都圈出一個量身定製的小盒子。這正是你之前讀到過的過擬合,而且是最純粹的形態:在見過的資料上完美無瑕,在任何新資料上卻錯得令人難堪。
一棵很深的單樹正落在偏差—變異權衡的一個極端:它的偏差極小,變異卻極大。只要改動幾行訓練資料,整棵樹就可能重新塑形,長出截然不同的問題。這種不穩定,正是該讓你提高警惕的症狀——一個會隨資料劇烈改變主意的模型,抓住的是雜訊,而不是訊號。
第一道防線是剪枝:讓樹提早收手(限制它的深度,或要求每片葉子至少容納,比方說,20個樣本),又或者先把它長滿,再剪掉那些在留出資料上不值回票價的枝條。剪枝是用一點點訓練準確率,換來好得多的泛化能力。它確實有幫助——但一棵孤樹,無論修剪得多麼用心,都很難與接下來要登場的東西較量。
群體的智慧:裝袋法
有一個古老的觀察:問一個專家,你可能得到大錯特錯的答案;問一千個,再把答案平均起來,誤差就相互抵消了。一棵高變異的樹,恰恰就是這樣一位手抖的專家。於是,與其費力去穩住一棵樹,我們不如擁抱它的晃動,把許多棵的結果平均起來。這正是集成學習的核心——把許多不完美的模型合成一個更強的整體。
可是,如果我們讓每棵樹都在同一份資料上訓練,那不過是把同一棵樹複製了一千遍——沒有多樣性,也就沒有相互抵消。裝袋法(bagging,即*自助聚合*,bootstrap aggregating)正是用來製造多樣性的。對每一棵樹,它都*有放回地*隨機抽取訓練樣本的一部分——於是有些列出現了兩次,有些則一次也沒出現。這樣每棵樹看到的世界都略有不同,學到的問題也略有不同,犯的錯誤更是各不相同。
接著你把它們聚合起來:分類問題裡,眾樹投票,多數獲勝;迴歸問題裡,你把它們的數值取平均。因為每棵樹的誤差指向隨機、互不相關的方向,它們往往相互抵消——而它們共有的、真實的訊號卻彼此強化。背後的數學溫和卻有力:把許多獨立的估計平均起來,能在不抬高偏差的前提下壓低變異。群體,比其中任何一個聲音都更沉穩。
隨機森林額外的一招
隨機森林就是把裝袋法用在決策樹上,再加上一味巧妙的額外配料。光靠裝袋有一個隱藏的弱點:如果某個特徵特別強勢,幾乎每棵樹都會拿它來做第一刀切分,結果眾樹長得彼此相像——而相像的樹會犯*相關的*錯誤,平均起來效果就差。森林打破了這種從眾行為。
這一招是:在*每一次切分*時,每棵樹都只被允許考慮特徵的一個隨機子集(常見的選法是取特徵總數的平方根)。在某個節點上,一棵樹或許被禁止使用那個最強勢的特徵,於是被逼著去發現第二好、第三好的問題。結果便是一片由真正*各異*的樹組成的森林,它們的誤差遠沒有那麼相關——而正是這種去相關,讓平均的效果好得出奇。
forest = []
for t in range(n_trees):
rows = sample_with_replacement(training_data) # bagging
tree = grow_tree(rows, features_per_split=sqrt(F)) # random features
forest.append(tree)
def predict(x):
votes = [tree.predict(x) for tree in forest]
return majority(votes) # or mean(votes) for regression還有一份可愛的免費贈品:每棵樹自助抽樣時沒被抽中的那些列(即*袋外*樣本),天然就構成了這棵樹的測試集。把森林在這些沒見過的列上的準確率平均一下,幾乎是白白地得到了一個誠實的誤差估計,連單獨劃一份驗證集都省了。
森林何時取勝——以及一句誠實的告誡
隨機森林至今仍是監督式學習中最可靠的主力之一,在面對雜亂的表格資料(混雜著數字與類別的試算表)時,它依然是許多從業者的第一選擇。它幾乎不需要做特徵縮放,對離群點和無關欄位毫不在意,哪怕用上幾百棵樹也很少過擬合,而且開箱即用、幾乎不用調參。在充斥著大多數企業的結構化資料上,一片森林往往能與神經網路打成平手甚至勝出,所需的資料與功夫卻只是後者的零頭。
不過,對它的局限要誠實。森林犧牲掉了單棵樹那份寶貴的可讀性——你拿一張能解釋的流程圖,換來了一個數百成員的委員會。它還不擅長外推:因為每個預測都是訓練葉子的平均,森林永遠輸出不了它見過的範圍之外的值,所以它對平滑的趨勢或真正的預測都很吃力。而對於知覺類資料——圖像、音訊、原始文字——訊號藏在空間或序列結構之中,這條階梯後面要講的深度學習方法便會決定性地領先。