2017-03-03 3 views
-1

randomForest는 블랙 박스로되어 있고 대부분의 사람들은 분류 자의 ROC 곡선에 관심이 있지만 RF의 개별 트리를 검사해야하는 문제에 대해 연구하고 있습니다. 나는 R에 익숙하지 않기 때문에 RF로 생성 된 개별 트리의 ROC 곡선을 그릴 수있는 쉬운 방법은 무엇입니까?트리에서 플롯하는 방법 R에서 randomForest의 ROC 곡선?

+0

포리스트에 1000 마리의 머릿단이있는 경우 시각화가 효과적이지 않습니다. –

+0

참. 시각화 할 나무의 하위 집합을 선택합니다. – MaYa

+0

우리가 당신의 의도를 얻을 수 있도록 약간의 코드를 제공해주십시오. –

답변

1

randomForest 패키지에 의해 생성 된 임의의 포리스트에서 단일 트리에서 ROC 곡선을 생성 할 수 있다고 생각하지 않습니다. 예를 들어 교육 세트를 통해 예측에서 각 트리의 출력에 액세스 할 수 있습니다.

# caret for an example data set 
library(caret) 
library(randomForest) 

data(GermanCredit) 

# use only 50 rows for demonstration 
nrows = 50 

# extract the first 9 columns and 50 rows as training data (column 10 is "Class", the target) 
x = GermanCredit[1:nrows, 1:9] 
y = GermanCredit$Class[1:nrows] 

# build the model 
rf_model = randomForest(x = x, y = y, ntree = 11) 

# Compute the prediction over the training data. Note predict.all = TRUE 
rf_pred = predict(rf_model, newdata = x, predict.all = TRUE, type = "prob") 

당신은 그러나, 단일 트리의 예측은 가장 가능성 레이블

rf_pred$individual 

각 트리의 예측에 액세스 할 수 있습니다. ROC 곡선의 경우 클래스 확률이 필요하므로 결정 임계 값을 변경하면 예상 클래스가 참 및 거짓 양성률을 변경합니다.

내가 알 수있는 한, 적어도 randomForest 패키지에는 레이블 대신 레이블을 출력 할 확률이 없다. getTree()를 사용하여 트리를 검사하면 예측이 바이너리임을 알 수 있습니다. getTree (rf_model, k = 1, labelVar = TRUE)를 사용하면 라벨이 일반 텍스트로 표시됩니다.

그러나 할 수있는 일은 predict.all = TRUE를 통해 개별 예측을 검색 한 다음 전체 포리스트의 하위 집합에서 수동으로 클래스 레이블을 계산하는 것입니다. 그런 다음 ROCR 패키지의 ROC 커브와 같은 ROC 커브를 계산하는 함수를 입력 할 수 있습니다.

편집 : 좋아, 귀하의 의견에 제공 한 링크에서 ROC 곡선을 얻을 수있는 아이디어가 있습니다. 먼저 특정 트리 하나를 추출한 다음 트리에 각 데이터 포인트를 입력하여 각 노드에서의 성공 클래스의 발생 수와 각 노드의 총 데이터 포인트를 계산해야합니다. 비율은 성공 클래스에 대한 노드 확률을 제공합니다. 다음으로, 우리는 유사하게, 즉 각 데이터 포인트를 트리에 입력하지만, 이제는 확률을 기록합니다. 이렇게하면 클래스 probs를 실제 레이블과 비교할 수 있습니다. 코드는 다음과 같습니다.

# libraries we need 
library(randomForest) 
library(ROCR) 

# Set fixed seed for reproducibility 
set.seed(54321) 

# Define function to read out output node of a tree for a given data point 
travelTree = function(tree, data_row) { 
    node = 1 
    while (tree[node, "status"] != -1) { 
     split_value = data_row[, tree[node, "split var"]] 
     if (tree[node, "split point"] > split_value) { 
      node = tree[node, "right daughter"] 
     } else { 
      node = tree[node, "left daughter"] 
     } 
    } 
    return(node) 
} 

# define number of data rows 
nrows = 100 
ntree = 11 

# load example data 
data(GermanCredit) 

# Easier access of variables 
x = GermanCredit[1:nrows, 1:9] 
y = GermanCredit$Class[1:nrows] 

# Build RF model 
rf_model = randomForest(x = x, y = y, ntree = ntree, nodesize = 10) 

# Extract single tree and add variables we need to compute class probs 
single_tree = getTree(rf_model, k = 2, labelVar = TRUE) 
single_tree$"split var" = as.character(single_tree$"split var") 
single_tree$sum_good = 0 
single_tree$sum = 0 
single_tree$pred_prob = 0 


for (zeile in 1:nrow(x)) { 
    out_node = travelTree(single_tree, x[zeile, ]) 
    single_tree$sum_good[out_node] = single_tree$sum_good[out_node] + (y[zeile] == "Good") 
    single_tree$sum[out_node] = single_tree$sum[out_node] + 1 
} 

# Compute class probabilities from count of "Good" data points in each node. 
# Make sure we do not divide by zero 
idcs = single_tree$sum != 0 
single_tree$pred_prob[idcs] = single_tree$sum_good[idcs]/ single_tree$sum[idcs] 

# Compute prediction by inserting again data set into tree, but read out 
# previously computed probs 

single_tree_pred = rep(0, nrow(x)) 

for (zeile in 1:nrow(x)) { 
    out_node = travelTree(single_tree, x[zeile, ]) 
    single_tree_pred[zeile] = single_tree$pred_prob[out_node] 
} 

# Et voila: The ROC curve for single tree! 
plot(performance(prediction(single_tree_pred, y), "tpr", "fpr")) 
+0

이것은 완벽하게 이해할 수 있습니다! 나는 자바 스크립트에서 나무를 읽고 트리 아래로 전체 데이터 집합을 실행하고 [여기]와 같은 점수를 계산하여 잎 노드 확률을 계산합니다 (http://stats.stackexchange.com/questions/105760/how-we-can-draw-an- 결정 트리를위한 곡선 - 곡선/110500 # 110500? newreg = 9ca13b7b43bf4985b9e75a5cc1cb2ae6). 다중 클래스 분류의 경우 나뭇잎의 실제 예측으로 간주되는 것이 확실하지 않습니다. 내가 말한대로 가장 가능성있는 레이블을 사용합니까? 이 잎의 다른 모든 것들은 거짓으로 간주됩니까? 나무의 잎을 가로 질러 점수를 합산하는 방법은 무엇입니까? 대단히 감사합니다. – MaYa

+0

getTree에 의해 주어진 트리 구조를 사용하여 수동으로 데이터의 레이블을 계산할 생각은하지 못했습니다. randomForest 패키지에이 함수가 있다고 생각하지 않지만 실제로 probs를 계산할 수 있습니다. 다중 등급 분류에 대한 경험이 없습니다. 제가 누르면 모든 대분류를 할 것입니다. ROC 곡선의 맥락에서 멀티 클래스는 아무런 의미가 없다. 더 이상 당신을 도울 수 없어서 미안 해요. – Calbers

+0

계속 듣고있는 경우 (아마도 더 이상 관련이 없지만, 완전성을 위해) 임의의 포리스트에서 하나의 트리에서 ROC 커브를 계산하기위한 코드를 추가했습니다. 재미있어! – Calbers