caret 에서 PPV (positive predictive value)로 학습하기

caret 패키지는 분류(classification)에서는 기본적으로 accuracy를 기준으로 이용한다. 별다른 다른 기준을 제시하지 않는다면 accuracy가 높은 쪽으로 모델을 튜닝한다는 뜻이다.

그렇다면 다른 지표를 기준으로 삼아야 할 경우에는 어떻게 할 수 있을까? 지금 분석 중인 자료에서는 PPV를 기준으로 삼는 것이 필요하다. 그래서 관련 자료를 검색하여 보았다. 검색으로 알 수 있는 것은 학습 과정에서 PPV 수치를 제공하면 된다는 것이다.

여기에 적힌대로 하면 정말로 PPV가 높은 쪽으로 모델이 튜닝된다. 단, 하나 주의해야 할 부분이 있다. 본인이 분석해야 하는 자료에서 Positive 항목을 제대로 지정해 주어야 한다. 위 페이지 내용대로 한다면 참값의 기준은 해당 항목의 첫 번째가 기준이 된다. 나의 자료는 neg 와 pos 로 되어 있다. pos는 알파벳 순으로 2번째이다. 그렇기 때문에 이럴 고려하여 PPV를 계산하도록 해야 한다.

PPV = function(data, lev = NULL, model = NULL) {
    value = posPredValue(data$pred, 
                         data$obs, 
                         positive = lev[which(lev == 'pos')]
                        )
    c(PPV = value)
  }

자료의 형식을 data$pred나 data$obs로 변경해야 할 필요는 없다. 수정해야 하는 부분은 positive 부분이다. 본인의 자료에 맞추어서 정확한 숫자로 입력해 주면 된다.

fitControl = trainControl(method='repeatedcv', number = 10, repeats = 100, summaryFunction = PPV)

trainControl 에서도 앞서 만든 PPV를 이용할 것이라고 summaryFunction 을 이용해서 정의한다.

caret::train(true_positive ~ ., method = 'rpart', trControl = fitControl, data = trainset, metric = 'PPV')

train 과정에서도 metric을 이용해서 PPV를 이용할 것이라고 적어둔다.