У цьому документі про Adaboost наведено кілька пропозицій та код (стор. 17) щодо поширення 2-класових моделей на проблеми K-класу. Я хотів би узагальнити цей код таким чином, щоб я міг легко підключити різні моделі 2 класу та порівняти результати. Оскільки більшість моделей класифікації мають інтерфейс формули та predict
метод, деякі з них повинні бути відносно легкими. На жаль, я не знайшов стандартного способу вилучення ймовірностей класу з 2-класових моделей, тому для кожної моделі потрібен певний спеціальний код.
Ось функція, яку я написав, щоб розділити проблему K-класу на проблеми 2-го класу та повернути K-моделі:
oneVsAll <- function(X,Y,FUN,...) {
models <- lapply(unique(Y), function(x) {
name <- as.character(x)
.Target <- factor(ifelse(Y==name,name,'other'), levels=c(name, 'other'))
dat <- data.frame(.Target, X)
model <- FUN(.Target~., data=dat, ...)
return(model)
})
names(models) <- unique(Y)
info <- list(X=X, Y=Y, classes=unique(Y))
out <- list(models=models, info=info)
class(out) <- 'oneVsAll'
return(out)
}
Ось метод прогнозування, який я написав, щоб переглядати кожну модель і робити прогнози:
predict.oneVsAll <- function(object, newX=object$info$X, ...) {
stopifnot(class(object)=='oneVsAll')
lapply(object$models, function(x) {
predict(x, newX, ...)
})
}
І, нарешті, ось функція повернути нормалізувати data.frame
передбачувані ймовірності та класифікувати випадки. Зауважте, що вам належить побудувати K-стовпчик data.frame
ймовірностей з кожної моделі, оскільки не існує єдиного способу вилучення ймовірностей класу з 2-класової моделі:
classify <- function(dat) {
out <- dat/rowSums(dat)
out$Class <- apply(dat, 1, function(x) names(dat)[which.max(x)])
out
}
Ось приклад використання adaboost
:
library(ada)
library(caret)
X <- iris[,-5]
Y <- iris[,5]
myModels <- oneVsAll(X, Y, ada)
preds <- predict(myModels, X, type='probs')
preds <- data.frame(lapply(preds, function(x) x[,2])) #Make a data.frame of probs
preds <- classify(preds)
>confusionMatrix(preds$Class, Y)
Confusion Matrix and Statistics
Reference
Prediction setosa versicolor virginica
setosa 50 0 0
versicolor 0 47 2
virginica 0 3 48
Ось приклад використання lda
(я знаю, що lda може обробляти кілька класів, але це лише приклад):
library(MASS)
myModels <- oneVsAll(X, Y, lda)
preds <- predict(myModels, X)
preds <- data.frame(lapply(preds, function(x) x[[2]][,1])) #Make a data.frame of probs
preds <- classify(preds)
>confusionMatrix(preds$Class, Y)
Confusion Matrix and Statistics
Reference
Prediction setosa versicolor virginica
setosa 50 0 0
versicolor 0 39 5
virginica 0 11 45
Ці функції повинні працювати для будь-якої моделі 2 класу з інтерфейсом формули та predict
методом. Зауважте, що вам потрібно вручну розділити компоненти X і Y, що трохи негарно, але написання інтерфейсу формули наразі поза мною.
Чи має сенс цей підхід для всіх? Чи я можу це покращити, чи існує існуючий пакет для вирішення цього питання?
predict
метод.
car
, чи один із*lab
пакунків) забезпечив би функцію, як ваш. Вибачте, я не можу допомогти. Я трохи прочитав про те, як працює SV-спосіб, і здається, що це було складніше, ніж я міг подумати.