第3章
決策樹和随機森林
決策樹和随機森林是一種可以增加應用程式功能的強大技術。我們将介紹一些概念和代碼,希望有助于你快速掌握并運作。
在本章中,我們将涉及以下主題:
- 通過大量代碼示例展示如何向應用程式添加強大的功能
- 決策樹
- 随機森林
技術要求
你需要在系統中安裝Microsoft Visual Studio。你可能還需要參考開源SharpLearning架構的GitHub代碼庫,位址為
https://github.com/mdabros/SharpLearning。
請觀看視訊,學習如何編碼:
http://bit.ly/201Lbhr3.1 決策樹
決策樹可以用于分類和回歸。決策樹以“是/否、真/假”的方式回答連續的問題。根據這些回答,決策樹按照預定的路徑實作它的目标。決策樹是有向無環圖的一個變種。最後,利用整個資料集和所有特征建構決策樹。
圖3-1展示了一個決策樹的例子。你可能不了解決策樹,但是你肯定知道這個過程。有人要甜甜圈嗎?
如你所見,決策樹的流程為自上而下式,直到獲得具體的結果。樹根是資料集拆分的初始決策點。決策樹根據每個節點上的分割标準來分割資料集。最常用的兩個分割标準是“基尼不純度”和“資訊增益”。
圖3-2所示為決策樹的另一種描述,雖然沒有好吃的甜甜圈!
到目前為止,決策樹的深度表示已經提出了許多問題。這是樹所能達到的最深層次(可詢問問題的總數),雖然在某些分支上,提出較少的問題也能獲得一些結果。例如,如圖3-2所示,提出1個問題之後就可以得到一些結果,有些結果在2個問題之後才能得到。是以,該決策樹的深度為2。

3.1.1 決策樹的優點
以下是使用決策樹的一些優點:
- 便于說明。
- 簡明、無須加以說明的可視化。
- 便于複制。
- 能處理數字和分類資料。
- 針對大資料集性能良好。
- 速度通常較快。
- 樹的深度位置便于顯示重要特性,樹的深度可展現重要性。
3.1.2 決策樹的缺點
以下是使用決策樹的一些缺點:
- 每個節點上,算法需要做出正确選擇。一個節點上的最佳選擇不一定是整棵樹的最佳選擇。
- 如果一棵樹層級較深,就容易過度拟合。
- 決策樹會記憶訓練集的資料,範化能力不強。
3.1.3 何時應該使用決策樹
以下是一些關于何時使用決策樹的例子:
- 當你想要一個簡單且可解釋的模型時。
- 當你的模型應該是非參數時。
- 當你不用擔心特征選擇時。
3.2 随機森林
在前面我們已經讨論過決策樹,接下來讨論随機森林。基本上,随機森林是決策樹的集合。在随機森林中,随機選擇總行數和特征數的一小部分來進行訓練。然後在該子集上建構決策樹。該集合會将結果聚合成單個結果。
随機森林也可以減少偏差和方差。它們是如何做到的?通過對不同資料樣本進行訓練,或者通過使用特征的随機子集。讓我們來舉例說明,假設我們有30個特征,随機森林可能隻使用其中的10個特征,這會導緻20個特征不被使用,但是這20個特性中的某些可能很重要。請記住,随機森林是決策樹的集合。是以,在每個決策樹中,如果我們使用10個特征,随着時間的推移,大多數(如果不是全部的話)特征都會因為平均法則被包含在内。是以,正是這種包含有助于控制因偏差和方差而産生的誤差。
對于大型資料集,決策樹的數量可能會大幅增加,有時會增長到數萬個甚至更多,這取決于你使用的特征數量,是以你需要仔細考慮性能問題。
随機森林的示意圖如圖3-3所示。
3.2.1 随機森林的優點
以下是使用随機森林的一些優點:
- 比單個決策樹更強大。
- 随機森林包含許多決策樹,是以能夠限制過度拟合和誤差。
- 深度資訊顯示了哪些特征有助于分類或回歸,以及它們的相對重要性。
- 可用于回歸和分類。
- 預設參數就足夠了。
- 可快速訓練。
3.2.2 随機森林的缺點
以下是使用随機森林的一些缺點:
- 為了提高速度,随機森林需要并行進行。
- 一旦訓練完成,預測可能會變得很慢。
- 需要更多決策樹才能更準确,這可能導緻模型的速度變慢。
3.2.3 何時應該使用随機森林
以下是一些何時使用随機森林的例子:
- 當模型解釋不是最重要的标準,解釋不像決策樹那麼簡單時。
- 當模型精度最為重要時。
- 當需要強大的分類、回歸和特征選擇分析時。
- 防止過度拟合。
- 圖像分類。
- 推薦引擎。
3.3 SharpLearning
現在,讓我們将注意力轉向一個不可思議的開源軟體包SharpLearning。SharpLearning是一種卓越的機器學習架構,可以讓人們學習機器學習的許多方面,包括前面幾節描述的決策樹和随機森林。在深入了解一些代碼示例和示例應用程式之前,讓我們先花幾分鐘了解一些知識。
3.3.1 術語
本章将會涉及以下術語:
- 學習器:這裡指機器學習算法。
- 模型:這裡指機器學習模型。
- 超參數:這些是用來調整和調節(希望如此)機器學習模型的參數。
- 目标:這些目标通常稱為因變量,用符号y表示,是嘗試模組化的值。
- 觀察值:這些是特征矩陣,包含目前目标的所有資訊,用符号x表示。
在大多數示例中,我們将重點關注SharpLearning的兩個名稱空間:
基于此,我們開始深入了解SharpLearning,并向你展示一些關于它如何工作的概念。
3.3.2 加載和儲存模型
SharpLearning非常便于将模型加載和儲存到磁盤中。這是機器學習庫中非常重要的一部分,SharpLearning是最容易實作的部分。
SharpLearning中的所有模型都有儲存和加載函數。這些函數為我們完成儲存和加載模型的繁重工作。
例如,我們将一個學習模型儲存到磁盤中:
如果我們想重新加載這個模型,隻需調用加載的函數:
加載和儲存資料模型非常簡單。你也可以使用序列化形式儲存模型。我們将需要在XML和二進制格式之間進行選擇。SharpLearning的另一個非常好的設計特征是,序列化模型允許我們序列化到IPredictorModel接口。如果每個模型都與接口相符,那麼更換模型将變得更加容易。采取如下方式來完成相關操作:
表3-1為即時訓練誤差和測試誤差。
當報告模型的性能時,即使訓練誤差較低,也應該始終使用測試誤差,因為這評估了模型概括新資料誤差的程度。
現在介紹超參數。超參數是影響機器學習算法學習過程的參數。你可以通過調整超參數來調整流程,進而提高性能和可靠性。與此同時,你也可以調整不正确的參數,獲得一些非預期操作的結果。讓我們來看看錯誤地調整超參數後可能會發生的一些情況:
- 如果模型過于複雜,可能出現所謂的高方差,或過度拟合。
- 如果模型過于簡單,可能出現所謂的高偏差,或低度拟合。
對于那些沒有手動調過參數的人來說(幾乎在實踐中都會發生這樣的過程)可能會占用相當多的時間。随着模型超參數的數量增加,調整時間和工作量也随之增加。解決這一問題的最佳方法是使用優化器,讓它為你完成工作。為此,SharpLearning可以給你帶來巨大的幫助,因為有許多優化器可供使用。下面列出了其中的一些優化器:
- 網格搜尋
- 随機搜尋
- 粒子群(我們将在第7章中的7.3節“用粒子群優化算法代替後向傳播”中讨論)
- 貝葉斯優化
- 全局有界下山單純形法
讓我們舉例說明。
建立一個學習器并使用預設參數,盡可能使用好的參數。一旦我們找到參數并建立了學習器,就需要建立模型。然後我們将預測訓練和測試集。完成前述所有步驟後,我們将測量測試集上的誤差并記錄下來:
表3-2所示為測試集誤差。
完成該部分後,就确定了基準。我們用随機搜尋優化器來調整超參數,看是否能得到更好的結果。為此,需要建立超參數的界限,這樣優化器就能知道該如何調整。做法如下:
你注意到我們用對數變換計算學習率了嗎?你知道我們為什麼這麼做嗎?答案是:確定在值的整個範圍内分布更加平均。最小值和最大值之間範圍差異較大(0.02 -> 0.2),是以對數變換是最好的方式。
現在需要一個驗證集幫助我們衡量模型在優化過程中對未知資料的概括程度。是以,我們需要進一步拆分訓練資料。在優化過程中我們将不使用目前的測試集。如果不這樣做,在最終誤差估計上可能存在顯著偏差,這不是我們想要的結果:
優化器還需要一個目标函數。該函數将采用雙數組作為輸入(包括超參數集),并傳回一個包含驗證誤差和相應超參數集的優化結果:
一旦定義了objective函數,我們就可以建立并運作優化器以找到最佳參數集。從運作優化器30次疊代開始,嘗試30組不同的超參數:
一旦運作,優化器就應該能找到一組最佳的超參數。讓我們看看具體情況:
- 樹:277
- 學習率:0.035
- 最大樹深度:15
- 子樣品率:0.838
- 特征拆分:4
現在我們獲得了一組在驗證集測量過的最佳超參數,可以用這些參數建立一個學習器,并用整個資料集學習一個新模型:
獲得最後一組完整的超參數後,把這些參數傳遞給學習器,這樣能夠顯著減少測試誤差。而手動操作将會耗費我們大量的時間。表3-3所示為測量誤差比較。
3.4 示例代碼和應用程式
在接下來的幾節中,我們将看到一段缺少完整注釋的代碼示例。它是純C#代碼,應該能便于所有人了解。
讓我們快速了解一下如何用SharpLearning預測觀察值。下面展示為一個完整的沒有注釋的代碼示例:
3.4.1 儲存模型
下面的代碼示例将向你展示儲存模型有多麼容易:
3.4.2 均方差回歸名額
均方差(MSE)是測量平均誤差的名額。更具體地說,它能夠衡量估計值和期望值之間的平均差距。均方差通常為非負數,接近零将更好。通過SharpLearning計算誤差名額非常容易,如以下代碼所示:
3.4.3 F1分數
在讨論F1分數前,必須先讨論準确率和召回率。
準确率是正确預測的正觀察值與總預測的正觀察值的比率。打個不恰當的比方是:所有說要來的人中,有多少人來了?
召回率(敏感度)是正确預測的正觀察值與總觀察值的比率。
F1分數是準确率與召回率的權重平均值。
下面是如何用SharpLearning計算F1分數:
3.4.4 優化
以下是如何用粒子群優化器傳回最優結果函數的示例:
以下是如何用網格搜尋優化器通過嘗試所提供參數的所有組合進行優化的代碼示例:
以下是如何用随機搜尋優化器,在給定的最小值和最大值之間随機初始化參數。最終傳回最優結果函數的結果:
3.4.5 示例應用程式1
掌握了前面的知識後,我們開始編寫第一個示例應用程式。該程式本身非常簡單,旨在用最少的代碼在應用程式中實作這些技術。為了直覺呈現,圖3-4是程式的輸出結果。
代碼
以下是我們的示例程式代碼,并輸出前面的分析結果。正如你所見,代碼非常簡單,這些都是我們之前已經浏覽過的代碼(以之前更簡潔)。我們将盡量減少注釋,讓你更專注代碼本身。這個樣本将讀入我們的資料,将其解析為觀察值和目标樣本,然後用1000棵樹建立一個學習器。随後我們将用學習器學習并建立模型。完成後,我們将計算出均方差,并在螢幕上顯示出來:
3.4.6 示例應用程式2—葡萄酒品質
在接下來的應用程式中,我們将根據建立的模型,運用所學知識來确定葡萄酒最重要的特征。圖3-5是完成後的輸出結果。
以下是應用程式的代碼。首先我們将資料加載并解析為觀察值和目标樣本集。由于這是一個回歸樣本,我們将把資料樣本按7 : 3分割,70%用于訓練,30%用于測試。我們從這些資料中建立了随機森林學習器和模型。随後,計算出訓練誤差和測試誤差,并按特征重要性進行排序,如模型所發現的情況:
3.5 小結
在本章中,我們學習了決策樹和随機森林。我們還學習了如何使用開源架構Sharp-Learning,并将架構強大的功能添加到應用程式中。在下一章中,我們将學習面部和運動檢測,并向你展示如何利用這一激動人心的技術開發應用程式!下章中,你會見到我的寵物—法國鬥牛犬,它會出現在大部分示例中。