機器學習九大算法---隨機森林
轉載自:http://www.zilhua.com/629.html
1. 隨機森林使用背景
1.1 隨機森林定義
隨機森林是一種比較新的機器學習模型。經典的機器學習模型是神經網絡,有半個多世紀的歷史了。神經網絡預測精確,但是計算量很大。上世紀八十年代Breiman等人發明分類樹的算法(Breiman et al. 1984),通過反復二分數據進行分類或回歸,計算量大大降低。2001年Breiman把分類樹組合成隨機森林(Breiman 2001a),即在變量(列)的使用和數據(行)的使用上進行隨機化,生成很多分類樹,再匯總分類樹的結果。隨機森林在運算量沒有顯著提高的前提下提高了預測精度。隨機森林對多元公線性不敏感,結果對缺失數據和非平衡的數據比較穩健,可以很好地預測多達幾千個解釋變量的作用(Breiman 2001b),被譽為當前最好的算法之一(Iverson et al. 2008)。
隨機森林顧名思義,是用隨機的方式建立一個森林,森林里面有很多的決策樹組成,隨機森林的每一棵決策樹之間是沒有關聯的。在得到森林之后,當有一個新的輸入樣本進入的時候,就讓森林中的每一棵決策樹分別進行一下判斷,看看這個樣本應該屬於哪一類(對於分類算法),然后看看哪一類被選擇最多,就預測這個樣本為那一類。
1.2 隨機森林優點
隨機森林是一個最近比較火的算法,它有很多的優點:
a. 在數據集上表現良好,兩個隨機性的引入,使得隨機森林不容易陷入過擬合
b. 在當前的很多數據集上,相對其他算法有着很大的優勢,兩個隨機性的引入,使得隨機森林具有很好的抗噪聲能力
c. 它能夠處理很高維度(feature很多)的數據,並且不用做特征選擇,對數據集的適應能力強:既能處理離散型數據,也能處理連續型數據,數據集無需規范化
d. 可生成一個Proximities=(pij)矩陣,用於度量樣本之間的相似性: pij=aij/N, aij表示樣本i和j出現在隨機森林中同一個葉子結點的次數,N隨機森林中樹的顆數
e. 在創建隨機森林的時候,對generlization error使用的是無偏估計
f. 訓練速度快,可以得到變量重要性排序(兩種:基於OOB誤分率的增加量和基於分裂時的GINI下降量
g. 在訓練過程中,能夠檢測到feature間的互相影響
h. 容易做成並行化方法
i. 實現比較簡單
1.3 隨機森林應用范圍
隨機森林主要應用於回歸和分類。本文主要探討基於隨機森林的分類問題。隨機森林和使用決策樹作為基本分類器的(bagging)有些類似。以決策樹為基本模型的bagging在每次bootstrap放回抽樣之后,產生一棵決策樹,抽多少樣本就生成多少棵樹,在生成這些樹的時候沒有進行更多的干預。而隨機森林也是進行bootstrap抽樣,但它與bagging的區別是:在生成每棵樹的時候,每個節點變量都僅僅在隨機選出的少數變量中產生。因此,不但樣本是隨機的,連每個節點變量(Features)的產生都是隨機的。
許多研究表明, 組合分類器比單一分類器的分類效果好,隨機森林(random forest)是一種利用多個分類樹對數據進行判別與分類的方法,它在對數據進行分類的同時,還可以給出各個變量(基因)的重要性評分,評估各個變量在分類中所起的作用。
2. 隨機森林方法理論介紹
2.1 隨機森林基本原理
隨機森林由LeoBreiman(2001)提出,它通過自助法(bootstrap)重采樣技術,從原始訓練樣本集N中有放回地重復隨機抽取k個樣本生成新的訓練樣本集合,然后根據自助樣本集生成k個分類樹組成隨機森林,新數據的分類結果按分類樹投票多少形成的分數而定。其實質是對決策樹算法的一種改進,將多個決策樹合並在一起,每棵樹的建立依賴於一個獨立抽取的樣品,森林中的每棵樹具有相同的分布,分類誤差取決於每一棵樹的分類能力和它們之間的相關性。特征選擇采用隨機的方法去分裂每一個節點,然后比較不同情況下產生的誤差。能夠檢測到的內在估計誤差、分類能力和相關性決定選擇特征的數目。單棵樹的分
類能力可能很小,但在隨機產生大量的決策樹后,一個測試樣品可以通過每一棵樹的分類結果經統計后選擇最可能的分類。
2.2 隨機森林算法
2.2.1 決策樹
決策樹(decision tree)是一個樹結構(可以是二叉樹或非二叉樹)。其每個非葉節點表示一個特征屬性上的測試,每個分支代表這個特征屬性在某個值域上的輸出,而每個葉節點存放一個類別。使用決策樹進行決策的過程就是從根節點開始,測試待分類項中相應的特征屬性,並按照其值選擇輸出分支,直到到達葉子節點,將葉子節點存放的類別作為決策結果。
隨機森林是用隨機的方式建立一個森林,森林里面有很多的決策樹組成,隨機森林的每一棵決策樹之間是沒有關聯的。在得到森林之后,當有一個新的輸入樣本進入的時候,就讓森林中的每一棵決策樹分別進行一下判斷,看看這個樣本應該屬於哪一類,然后看看哪一類被選擇最多,就預測這個樣本為那一類。
在建立每一棵決策樹的過程中,有兩點需要注意采樣與完全分裂。首先是兩個隨機采樣的過程,random forest對輸入的數據要進行行、列的采樣。對於行采樣,采用有放回的方式,也就是在采樣得到的樣本集合中,可能有重復的樣本。假設輸入樣本為N個,那么采樣的樣本也為N個。這樣使得在訓練的時候,每一棵樹的輸入樣本都不是全部的樣本,使得相對不容易出現over-fitting。然后進行列采樣,從M個feature中,選擇m個(m << M)。之后就是對采樣之后的數據使用完全分裂的方式建立出決策樹,這樣決策樹的某一個葉子節點要么是無法繼續分裂的,要么里面的所有樣本的都是指向的同一個分類。一般很多的決策樹算法都一個重要的步驟——剪枝,但是這里不這樣干,由於之前的兩個隨機采樣的過程保證了隨機性,所以就算不剪枝,也不會出現over-fitting。
決策樹中分裂屬性的兩個選擇度量:
1)信息增益
隨機森林模型任意樣本分類的期望信息:
a) I(s1,s2,……,sm)=
∑Pi log2(pi)(i=1..m)
其中,數據集為S,m為S的分類數目,Pi≈|Si/|S|,Ci為某分類標號,Pi為任意樣本屬於Ci的概率,si為分類Ci上的樣本數
b) I(s1,s2,……,sm)越小,s1,s2,……,sm就越有序(越純),分類效果就越好。
c) 由屬性A划分為子集的熵:
A為屬性,具有V個不同的取值, S被A 划分為V 個子集s1,s2,……,sv,sij是子集sj中類Ci的樣本數。E(A)= ∑(s1j+ ……+smj)/s * I(s1j,……,smj)
d) 信息增益:Gain(A)= I(s1,s2,……,sm)
E(A)
e) 分裂屬性選擇規則:選擇具有最大信息增益的屬性為分裂屬性
2)基尼指數
a) 集合T包含N個類別的記錄,那么其Gini指標就是pj 類別j出現的頻率
b) 如果集合T分成m部分 N1 , N2 ,…, Nm 。那么這個分割的Gini就是
c)分裂屬性選擇規則:選擇具有最小Ginisplit的屬性為分裂屬性(對於每個屬性都要遍歷所有可能的分割方法)。
2.2.3 隨機森林模型的注意點
設有N個樣本,每個樣本有M個features,決策樹們其實都是隨機地接受n個樣本(對行隨機取樣)的m個feature(對列進行隨機取樣),每顆決策樹的m個feature相同。每顆決策樹其實都是對特定的數據進行學習歸納出分類方法,而隨機取樣可以保證有重復樣本被不同決策樹分類,這樣就可以對不同決策樹的分類能力做個評價。
2.2.4隨機森林實現過程
隨機森林中的每一棵分類樹為二叉樹,其生成遵循自頂向下的遞歸分裂原則,即從根節點開始依次對訓練集進行划分;在二叉樹中,根節點包含全部訓練數據, 按照節點
純度最小原則,分裂為左節點和右節點,它們分別包含訓練數據的一個子集,按照同樣的規則節點繼續分裂,直到滿足分支停止規則而停止生長。若節點n上的分類數據全部來自於同一類別,則此節點的
純度I(n)=0,
純度度量方法是Gini准則,即假設P(Xj)是節點n上屬於Xj 類樣本個數占訓練。
具體實現過程如下:
(1)原始訓練集為N,應用bootstrap法有放回地隨機抽取k個新的自助樣本集,並由此構建k棵分類樹,每次未被抽到的樣本組成了k個袋外數據;
(2)設有mall個變量,則在每一棵樹的每個節點處隨機抽取mtry個變量(mtry n mall),然后在mtry中選擇一個最具有分類能力的變量,變量分類的閾值通過檢查每一個分類點確定;
(3)每棵樹最大限度地生長, 不做任何修剪;
(4)將生成的多棵分類樹組成隨機森林,用隨機森林分類器對新的數據進行判別與分類,分類結果按樹分類器的投票多少而定。
3. 隨機森林應用
由於R中早就出現randomForest包了,本文主要討論R中隨機森林的應用。兩個主要函數比較重要:randomForest用來構建隨機森林模型,predict()使用訓練后的隨機森林對新數據進行預測。
3.1目標
通過隨機森林的算法,根據一些特征,例如花瓣的長,寬,花萼的長寬。來預測植株的種類。
3.2 准備的數據集
iris數據集,是R語言自帶的數據集。
R 源代碼:
3.4 一些重要參數說明
randomForest()對訓練集的數據進行處理,生成決策樹
iris.rf=randomForest(Species~.,iris[ind==1,],ntree=50,nPerm=10,mtry=3,proximity=TRUE,importance=TRUE)
Species~.:代表需要預測的列,species是列的名稱。
iris[ind==1,]:生成決策樹的訓練集
ntree:生成決策樹的數目
nperm:計算importance時的重復次數
mtry:選擇的分裂屬性的個數
proximity=TRUE:表示生成臨近矩陣
importance=TRUE:輸出分裂屬性的重要性
predict()
iris.pred=predict( iris.rf,iris[ind==2,] )
iris.rf:表示生成的隨機森林模型
iris[ind==2,] :進行預測的測試集
3.5預測結果