隨機森林算法-Deep Dive


0-寫在前面

隨機森林,指的是利用多棵樹對樣本進行訓練並預測的一種分類器。該分類器最早由Leo Breiman和Adele Cutler提出。簡單來說,是一種bagging的思想,采用bootstrap,生成多棵樹,CART(Classification And Regression Tree)構成的。對於每棵樹,它們使用的訓練集是從總的訓練集中有放回采樣出來的,這意味着,總的訓練集中的有些樣本可能多次出現在一棵樹的訓練集中,也可能從未出現在一棵樹的訓練集中。對於一個有n行的數據集,out of bag 的概率大概是1/e=1/3。n趨向無窮大的時候,(1-1/n)^n~1/e。

選擇的是The Elements of Statistical Learning 這本教材進行學習。

原因有兩個1.翻了這本書在豆瓣的評論,看到的是評論者對這本書滿滿的敬仰! 2.女神的博客上有這本書的上課筆記(有中文筆記看,才是重點)

1-隨機森林算法特色

因為之前有用過randomForest這個包,所以就先從自己最熟悉的算法開始。

先說說隨機森林有哪些特色,我就簡單翻譯下[1]上面寫的

  1. 在與其它現有的算法相比,其預測准確率很好
  2. 在較大的數據集上計算速度依然很快
  3. 不需要降維,算法本身是采取隨機降維的
  4. 他能處理有缺失值的數據集。算法內部有補缺失值的函數
  5. 能給出變量的重要性
  6. 能處理imbalanced data set
  7. 能給出觀測實例間的相似度矩陣,其實就是proximity啦,繼而能做clustering 和 location outlier
  8. 能對unlabeled data 進行無監督的學習,進行clustering
  9. 生成的森林可以保留,應用在新的數據集上

個人感覺最重要的是1-6。7-9我並沒找到很有說服力的例子能證明隨機森林在這幾方面也很強。

2-根據其特色說一說隨機森林算法

先說4,隨機森林是如何補全缺失值的。主要參考資料[1]、[2]

前提:訓練數據集中label(被解釋變量)一定要有,不然這條觀測實例你為何拿他來學習模型?

randomForest包里,有兩種補全缺失值的方法。

方法一(na.roughfix)簡單粗暴,對於訓練集,同一個class下的數據,如果是分類變量缺失,用眾數補上,如果是連續型變量缺失,用中位數補。

方法二(rfImpute)這個方法計算量大,至於比方法一好壞?不好判斷。他只能補訓練集中的缺失值。是先用na.roughfix補上缺失值,然后構建森林並計算proximity matrix,再回頭看缺失值,如果是分類變量,則用沒有缺失的觀測實例的proximity中的權重進行投票。如果是連續型變量,則用proximity矩陣進行加權平均的方法補缺失值。然后迭代4-5次。這個補缺失值的思想和KNN有些類似。

################ imputation ################
library(kernlab)
library(magrittr)
data(spam)
spam.na <- spam
set.seed(111)
## artificially drop some data values.
for (i in 1:57) spam.na[sample(length(spam[,1]), length(spam[,1])/10), i] <- NA
## calculate missing value ratio for coloumns
missingvalue.ratio <- function(df){
    df <- as.data.frame(df)
    res <- is.na(df)%>%colSums()/length(df[,1])
    return(res)
}
missingvalue.ratio(spam.na)
# na.roughfix impute
spam.roughfix <- na.roughfix(spam.na)
randomForest(type ~ ., data=spam.roughfix)
# in another way
randomForest(type ~ ., data=spam.na, na.action = na.roughfix)
#rfImpute
spam.rfImpute <- rfImpute(type~.,data=spam.na,iter=2,ntree=300)
randomForest(type ~ ., data=spam.rfImpute)

對於7,proximity matrix

這個據說是randomForest中的亮點? [1]中說proximity are one of the most useful tools in random forests,[3]中寫到The proximity matrix can be used to identify structure in the data (see Breiman, 2002) or for unsupervised learning with random forests 。

 

前面的rfImpute就是基於proximity matrix的,proximity matrix其實就是任意兩個觀測實例間的相似度矩陣。原理是如果兩個觀測實例落在同一棵樹的同一個葉子節點的次數越多,則這兩個觀測實例的相似度越高。這個矩陣進行了歸一化,就是除以ntree,你種了多少顆樹。很簡單的思想。

 

library(kernlab)
library(randomForest)
data(spam)
set.seed(1)
rf <- randomForest(type~.
                   ,data=spam
                   ,importance=TRUE
                   ,proximity=FALSE
                   ,ntree=300
                   ,do.trace=20
                   ,na.action=na.omit
                   ,mtry=7
                   ,keep.forest=FALSE)

以上代碼中設置proximity=TRUE就可以得到這個矩陣了。對很大的數據集,請慎用,對於一個有n個觀測值的數據集,他會生成一個n*n的矩陣,spam是4601行,生成4601*4601的矩陣,就是160m在內存中。

對於5.能給出變量的重要性

這里借鑒[3]中的一段代碼,自己改了一下。查看變量重要性,無非就是進行feature selection,降低模型的復雜度的同時獲取較好的預測准確率。

par(mfrow = c(2,2))
for(i in 1:4){
    plot(sort(rf$importance[,i],decreasing =TRUE)%>%head(20)
         ,type='h'
         ,main=paste0(colnames(rf$importance)[i])
         ,xlab='variable'
         ,ylab='importance')
    
    text(sort(rf$importance[,i],decreasing =TRUE)
                    ,labels=names(sort(rf$importance[,i]))%>%head(20)
                       ,pos=1
                       ,cex=0.9)
}

以上代碼能畫出變量重要性的圖,如下。(spam數據集有57個解釋變量,為了能看清圖,變量重要性排名只取前20)

衡量變量重要性的方法有兩種,Decrease GINI 和Decrease Accuracy

Decrease GINI: 引用一篇博客中很好的解釋對於分類問題(將某個樣本划分到某一類),也就是離散變量問題,CART使用Gini值作為評判標准。定義為Gini=1-∑(P(i)*P(i)),P(i)為當前節點上數據集中第i類樣本的比例。例如:分為2類,當前節點上有100個樣本,屬於第一類的樣本有70個,屬於第二類的樣本有30個,則Gini=1-0.7×07-0.3×03=0.42,可以看出,類別分布越平均,Gini值越大,類分布越不均勻,Gini值越小。在尋找最佳的分類特征和閾值時,評判標准為:argmax(Gini-GiniLeft-GiniRight),即尋找最佳的特征f和閾值th,使得當前節點的Gini值減去左子節點的Gini和右子節點的Gini值最大。

對於回歸問題,相對更加簡單,直接使用argmax(Var-VarLeft-VarRight)作為評判標准,即當前節點訓練集的方差Var減去減去左子節點的方差VarLeft和右子節點的方差VarRight值最大。

Decrease Accuracy:抄一下女神的文字

然后隨機改變OOB樣本的第j列:保持其他列不變,對第j列進行隨機的上下置換,得到誤差2。至此,我們可以用誤差1-誤差2來刻畫變量j的重要性。當然這里loss function可以自己定。這里的大致思想就是,如果一個變量j足夠重要,那么改變它會極大的增加測試誤差;反之,如果改變它測試誤差沒有增大,則說明該變量不是那么的重要。(典型的實用主義啊!管用才是真,才不管他什么證明不證明呢!自從開始接觸機器學習的這些算法,我真的是被他們的各種天真爛漫的想法打敗的一塌糊塗,只要直覺上過得去、實際效果看起來比較好就可以了呢,規則真簡單)

對於mtry這個值的設定:

default是sqrt(M),作者建議也試一下sqrt(M)/2,2sqrt(M), 甚至是對於有些數據集,取mtry=1效果也很好。

對於 6.能處理imbalanced data set,Balancing prediction error。

這個是非常重要的一個特點。往往我們的數據集,每個class下的觀測實例個數,總是不那么均等,比如[4]中提到,在反欺詐識別,疾病識別這種數據集中,數據就非常不平衡。

[4]中提到兩種方法處理這種情況,一種是balanced RF,另一種是weighted RF,對於前者采是用分層重抽樣的方法,即對minority class采取up-sampling,對於majority class 進行down-smapling。下面舉例說明(在Cross Validated 這上面找到的一個很好的例子)R package for Weighted Random Forest? classwt option?

make.data = function(obs=5000,vars=6,noise.factor = .2,smallGroupFraction=.01) {
    X = data.frame(replicate(vars,rnorm(obs)))
    yValue = with(X,sin(X1*pi)+sin(X2*pi*2)+rnorm(obs)*noise.factor)
    yQuantile = quantile(yValue,c(smallGroupFraction,.5))
    yClass = apply(sapply(yQuantile,function(x) x<yValue),1,sum)
    yClass = factor(yClass)
    print(table(yClass)) #five classes, first class has 1% prevalence only
    Data=data.frame(X=X,y=yClass)
}
Data = make.data()
# yClass
# 0    1    2 
# 50 2450 2500 
rf1 = randomForest(y~.,Data,ntree=500, sampsize=5000)
# 下面是rf1的結果,可以看出對於yClass==0的預測錯誤率100%,但是總體的預測錯誤率在
# 13.7%左右,如果是做fraud detection,這絕對是不可行的。
        OOB estimate of  error rate: 13.7%
Confusion matrix:
  0    1    2 class.error
0 0   50    0   1.0000000
1 0 2109  341   0.1391837
2 0  294 2206   0.1176000
###########下面用分層抽樣改進###########
rf2 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,500,500),strata=Data$y)
rf3 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,100,100),strata=Data$y)
rf4 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,50,50)  ,strata=Data$y)
###########結果看下來,rf3,rf4效果最好###########
#作者也提到,讓每個class的錯誤率都均等一些,可能會使總體的預測錯誤率上升,這需要權衡

randomForest能進行無監督的學習:

這里稍后再寫

參考資料

[1]Random Forest Classification/Clustering

[2]randomForest manual

[3]Classification and Regression by randomForest

[4]Using Random Forest to Learn Imbalanced Data

#后續閱讀

[1]How to interpret Mean Decrease in Accuracy and Mean Decrease GINI in Random Forest models

[2]http://www.loyhome.com/%E2%89%AA%E7%BB%9F%E8%AE%A1%E5%AD%A6%E4%B9%A0%E7%B2%BE%E8%A6%81the-elements-of-statistical-learning%E2%89%AB%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0%EF%BC%88%E5%8D%81%E5%85%AD%EF%BC%89/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM