2016-11-15 1 views
1

xgboost 모델 트리에서 확률을 생성하는 방법을 알아 내려고 predict 함수에서 얻을 수있는 것과 일치시킵니다.xgboost 모델에서 예측을 수동으로 작성하는 방법

먼저 난에

baseTree <- xgb.model.dt.tree(model = XX) 

Leafs <- filter(baseTree, Feature == 'Leaf') 
Branches <- filter(baseTree, Feature != 'Leaf') 

Branches$Feature = var.names[as.numeric(Branches$Feature) + 1] 

FullRules = rep(NA, nrow(Leafs)) 


AllRules <- foreach(i = 1:nrow(Leafs), .combine = 'rbind') %do% { 

    theLeaf = Leafs[i,] 
    theNode = theLeaf$Node 
    theID = theLeaf$ID 

    count = 1 

    RuleText = '' 
    while(theNode != 0){ 

    FF <- filter(Branches, Yes == theID | No == theID | Missing == theID) 
    isYes = FF$Yes == theID 
    isNo = FF$No == theID 
    isMissing = FF$Missing == theID 

    FullRules[i] = ifelse(isYes & isMissing 
     , paste0("(", FF$Feature, " < ", FF$Split, " | is.na(", FF$Feature, "))") 
     , NA) 
    FullRules[i] = ifelse(isNo & isMissing 
     , paste0("(", FF$Feature, " >= ", FF$Split, " | is.na(", FF$Feature, "))") 
     , FullRules[i]) 
    FullRules[i] = ifelse(isYes & !isMissing 
     , paste0(FF$Feature, " < ", FF$Split) 
     , FullRules[i]) 
    FullRules[i] = ifelse(isNo & !isMissing 
     , paste0(FF$Feature, " >= ", FF$Split) 
     , FullRules[i]) 
    FullRules[i] = ifelse(isMissing & !isYes & !isNo 
     , paste0("is.na(", FF$Feature, ")") 
     , FullRules[i]) 

    if(count == 1){ 
     RuleText = FullRules[i] 
    } else{ 
     RuleText = paste0(RuleText, " & ", FullRules[i]) 
    } 

    theNode = FF$Node 
    theID = FF$ID 
    count = count + 1 
    } 

    data.frame(
    Leafs[i,] 
    ,RuleText 
) 

} 

가 지금은 1 개 행을 골라 특정 잎이 발생할 것이라고 모든 규칙을 구축하는 몇 가지 코드를 작성하고 시도 그리고 모델

library(xgboost) 
#install.packages("ModelMetrics") 
library(ModelMetrics) 

set.seed(100) 

# - Extreme gbm 
y = as.integer(testDF$y) 

x = testDF[,-which(names(testDF) %in% c('y'))] 
var.names <- names(x) 
x = as.matrix(x) 
x = matrix(as.numeric(x),nrow(x),ncol(x)) 

nround = 10 

XX <- xgboost(param=param, data = x, label = y, nrounds=nround, missing = NA) 

를 구축 확률에 맞춰라. 이 경우 일치합니다. 루프가 진행되고이 특정 고객에 대해 충족 된 모든 규칙에 대해 TRUE로 표시됩니다. 그런 다음 해당 행까지 필터링하고이를 합하여 logodds 추정치를 얻을 수 있습니다. 그런 다음 이들을 확률로 변환합니다.

TT <- testDF[25,] 

ff <- foreach(i = 1:nrow(AllRules), .combine = 'rbind') %do% { 
    TT %>% transmute_(
    Tree = as.character(AllRules$RuleText[i]) 
    , Quality = AllRules$Quality[i]) 
} 


predict(XX, as.matrix(TT[,var.names])) 
#[1] 0.05571342 

filter(ff, Tree) %>% 
    summarise(
    Q1 = sum(sqrt(Quality^2)) 
    # ,Q2 = sum(sqrt(Quality^2)) 
    , Prob1 = exp(Q1)/(1+exp(Q1)) 
    , Prob2 = 1-Prob1 
    ) 
#  Q1  Prob1  Prob2 
#1 2.830209 0.9442866 0.0557134 

그러나이 경우에는 예측 기능과 일치하지 않습니다 ...

TT <- testDF[17,] 

ff <- foreach(i = 1:nrow(AllRules), .combine = 'rbind') %do% { 
    TT %>% transmute_(
    Tree = as.character(AllRules$RuleText[i]) 
    , Quality = AllRules$Quality[i]) 
} 


predict(XX, as.matrix(TT[,var.names])) 
#[1] 0.1386877 

filter(ff, Tree) %>% 
    summarise(
    Q1 = sum(sqrt(Quality^2)) 
    # ,Q2 = sum(sqrt(Quality^2)) 
    , Prob1 = exp(Q1)/(1+exp(Q1)) 
    , Prob2 = 1-Prob1 
    ) 
#  Q1 Prob1 Prob2 
#1 1.967608 0.877354 0.122646 

답변

1

당신은 단지 사람에 대한 내에 개별 잎의 값을 요약하는 데 필요한 예측을 생성하려면 각 부스터

filter(ff, Tree) %>% 
    summarise(
    Q1 = sum(Quality) 
    , Prob1 = exp(Q1)/(1+exp(Q1)) 
    , Prob2 = 1-Prob1 
    )