В этой статье об Adaboost приведены некоторые предложения и код (стр. 17) для расширения моделей с 2 классами до задач класса K. Я хотел бы обобщить этот код так, чтобы я мог легко подключить различные 2-классовые модели и сравнить результаты. Поскольку большинство моделей классификации имеют интерфейс формулы и predict
метод, некоторые из них должны быть относительно простыми. К сожалению, я не нашел стандартного способа извлечения вероятностей классов из двухклассовых моделей, поэтому для каждой модели потребуется некоторый пользовательский код.
Вот функция, которую я написал, чтобы разбить задачу 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
пакетов) предоставит такую же функцию, как ваша. Извините, я не могу помочь. Я немного читал о том, как работает k-way SVM, и кажется, что это было сложнее, чем я думал.