2011-12-07 29 views
3

有誰知道R randomForest包用來解決分類關係的機制是什麼?即當樹最終在兩個或更多類中得到相同的投票時?R randomForest vote vote tie break

該文件稱領帶被隨機打破。但是,當您在一組數據上訓練模型,然後使用一組驗證數據對該模型進行多次評分時,綁定的類別決策不是50/50。

cnum = vector("integer",1000) 
for (i in 1:length(cnum)){ 
    cnum[i] = (as.integer(predict(model,val_x[bad_ind[[1]],]))) 
} 
cls = unique(cnum) 
for (i in 1:length(cls)){ 
    print(length(which(cnum == cls[i]))) 
} 

其中model是隨機森林對象和bad_ind只是一個指數已經追平類票的特徵向量的列表。在我的測試用例中,使用上面的代碼,兩個綁定類之間的分佈接近90/10。

此外,建議使用奇數棵樹通常不會與第三課拉動一些投票而將其他兩個班級並列在一起。

這些rf樹的投票結果應該不是50/50嗎?

更新: 它很難提供一個例如由於一種訓練森林,但下面的代碼(遺憾的斜率)的隨機性質應最終產生的例子是,林不能確定一個明確的贏家。當關系破裂時,我的測試運行顯示66%/ 33%的分佈 - 我預計這是50%/ 50%。

library(randomForest) 
x1 = runif(200,-4,4) 
x2 = runif(200,-4,4) 
x3 = runif(1000,-4,4) 
x4 = runif(1000,-4,4) 
y1 = dnorm(x1,mean=0,sd=1) 
y2 = dnorm(x2,mean=0,sd=1) 
y3 = dnorm(x3,mean=0,sd=1) 
y4 = dnorm(x4,mean=0,sd=1) 
train = data.frame("v1"=y1,"v2"=y2) 
val = data.frame("v1"=y3,"v2"=y4) 
tlab = vector("integer",length(y1)) 
tlab_ind = sample(1:length(y1),length(y1)/2) 
tlab[tlab_ind]= 1 
tlab[-tlab_ind] = 2 
tlabf = factor(tlab) 
vlab = vector("integer",length(y3)) 
vlab_ind = sample(1:length(y3),length(y3)/2) 
vlab[vlab_ind]= 1 
vlab[-vlab_ind] = 2 
vlabf = factor(vlab) 
mm <- randomForest(x=train,y=tlabf,ntree=100) 
out1 <- predict(mm,val) 
out2 <- predict(mm,val) 
out3 <- predict(mm,val) 
outv1 <- predict(mm,val,norm.votes=FALSE,type="vote") 
outv2 <- predict(mm,val,norm.votes=FALSE,type="vote") 
outv3 <- predict(mm,val,norm.votes=FALSE,type="vote") 

(max(as.integer(out1)-as.integer(out2)));(min(as.integer(out1)-as.integer(out2))) 
(max(as.integer(out2)-as.integer(out3)));(min(as.integer(out2)-as.integer(out3))) 
(max(as.integer(out1)-as.integer(out3)));(min(as.integer(out1)-as.integer(out3))) 

bad_ind = vector("list",0) 
for (i in 1:length(out1)) { 
#for (i in 1:100) { 
    if (out1[[i]] != out2[[i]]){ 
    print(paste(i,out1[[i]],out2[[i]],sep = "; ")) 
    bad_ind = append(bad_ind,i) 
    } 
} 

for (j in 1:length(bad_ind)) { 
    cnum = vector("integer",1000) 
    for (i in 1:length(cnum)) { 
    cnum[[i]] = as.integer(predict(mm,val[bad_ind[[j]],])) 
    } 
    cls = unique(cnum) 
    perc_vals = vector("integer",length(cls)) 
    for (i in 1:length(cls)){ 
    perc_vals[[i]] = length(which(cnum == cls[i])) 
    } 
    cat("for feature vector ",bad_ind[[j]]," the class distrbution is: ",perc_vals[[1]]/sum(perc_vals),"/",perc_vals[[2]]/sum(perc_vals),"\n") 
} 

更新: 本應固定在隨機森林的4.6-3版本。

+0

你能提供一個可重現的小例子來證明這種行爲嗎? – joran

+0

代碼的最後部分在bad_ind行之後出現錯誤... – Benjamin

+0

您能告訴我錯誤在哪裏嗎?我只是添加了'library(randomForest)'行(在頂部),但是對於我而言,在R的新實例上剪切和粘貼代碼從頭到尾運行。 – Nate

回答

1

這應該被固定在4.6版本-3的randomForest。

1

如果沒有一個完整的例子,它是很難說,如果這是唯一的錯,但你上面包含的代碼一個明確的問題是,你沒有複製模型擬合步 - 僅預測步驟。當你適合的型號任意搭配打破的選擇完成的,所以如果你不重做這一部分,你predict()通話將繼續給同一類的概率較高/票。

試試這個例子,相反,這證明了正確的期望行爲:

library(randomForest) 
df = data.frame(class=factor(rep(1:2, each=5)), X1=rep(c(1,3), each=5), X2=rep(c(2,3), each=5)) 
fitTie <- function(df) { 
    df.rf <- randomForest(class ~ ., data=df) 
    predict(df.rf, newdata=data.frame(X1=1, X2=3), type='vote')[1] 
} 
> df 
    class X1 X2 
1  1 1 2 
2  1 1 2 
3  1 1 2 
4  1 1 2 
5  1 1 2 
6  2 3 3 
7  2 3 3 
8  2 3 3 
9  2 3 3 
10  2 3 3 

> mean(replicate(10000, fitTie(df))) 
[1] 0.49989 
+0

感謝您的迴應,但我認爲我們正在談論兩種不同的發行版。我故意不再訓練射頻模型。根據定義,rf不是確定性的。但是,最終的模型應該是完全確定性的 - 除了隨機森林沒有明確贏家的情況之外。這是我感興趣的情況。randomForest文檔說這種情況是通過隨機選擇來處理的。假設這是一個統一的分佈,它應該結束50/50。在某些實驗中,處理此案件的方式可能會影響最終的準確性。 – Nate

1

我認爲這是發生,因爲你有這樣的少數關係。與翻轉硬幣10次相同的問題,您不能保證在5頭5尾時捲起。

在下面的情況1中,關係被均勻地分開,每個類1:1。情況2,3:6。

> out1[out1 != out2] 
52 109 144 197 314 609 939 950 
    2 2 1 2 2 1 1 1 

> out1[out1 != out3] 
52 144 146 253 314 479 609 841 939 
    2 1 2 2 2 2 1 2 1 

更改爲一個更大的數據集:

x1 = runif(2000,-4,4) 
x2 = runif(2000,-4,4) 
x3 = runif(10000,-4,4) 
x4 = runif(10000,-4,4) 

我得到:

> sum(out1[out1 != out2] == 1) 
[1] 39 
> sum(out1[out1 != out2] == 2) 
[1] 41 

> sum(out1[out1 != out3] == 1) 
[1] 30 
> sum(out1[out1 != out3] == 2) 
[1] 31 

如預期,除非我誤解你的代碼。


編輯

哦,我明白了。您正在重新運行有關係的箱子,並且預計它們會被打破50/50,即:sum(cnum == 1)約等於sum(cnum == 2)。您可以測試使用這種方法要快得多:

> for (j in 1:length(bad_ind)) { 
+ mydata= data.frame("v1"=0, "v2"=0) 
+ mydata[rep(1:1000000),] = val[bad_ind[[j]],] 
+ outpred = predict(mm,mydata) 
+ print(sum(outpred==1)/sum(outpred==2)) 
+ } 
[1] 0.5007849 
[1] 0.5003278 
[1] 0.4998868 
[1] 0.4995651 

看來你是對的,這是打破贊成2類的關係兩倍,經常1班。

+0

您正在查看第一類和第二類之間的分佈 - 以及哪些具有相同的樹形投票。我更感興趣的是當你從單一預測中翻轉出來的特徵向量時發生的情況。隨機選擇應該是50/50,我在這個實驗66/33中看到 - 在我的實際數據80/20和90/10中。所以,我想知道選擇的基礎是哪一個特徵向量在多個類中具有相同數量的樹投票。在我的代碼中,「貓」行應該是50/50(我認爲),但不是(基於1000個樣本)。 – Nate

+0

我無法執行代碼的那部分,但嘗試更多樣本。我很確定我們都在做同樣的事情。 – Benjamin