Cet article sur Adaboost donne quelques suggestions et code (page 17) pour étendre les modèles à 2 classes aux problèmes de classe K. Je voudrais généraliser ce code, de sorte que je puisse facilement brancher différents modèles à 2 classes et comparer les résultats. Étant donné que la plupart des modèles de classification ont une interface de formule et une predict
méthode, certains de ces éléments devraient être relativement faciles. Malheureusement, je n'ai pas trouvé de moyen standard d'extraire les probabilités de classe des modèles à 2 classes, donc chaque modèle nécessitera un code personnalisé.
Voici une fonction que j'ai écrite pour décomposer un problème de classe K en problèmes de 2 classes et renvoyer des modèles 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)
}
Voici une méthode de prédiction que j'ai écrite pour itérer sur chaque modèle et faire des prédictions:
predict.oneVsAll <- function(object, newX=object$info$X, ...) {
stopifnot(class(object)=='oneVsAll')
lapply(object$models, function(x) {
predict(x, newX, ...)
})
}
Et enfin, voici une fonction permettant de normaliser une data.frame
des probabilités prédites et de classer les cas. Notez qu'il vous appartient de construire la colonne K data.frame
des probabilités à partir de chaque modèle, car il n'existe pas de méthode unifiée pour extraire les probabilités de classe d'un modèle à 2 classes:
classify <- function(dat) {
out <- dat/rowSums(dat)
out$Class <- apply(dat, 1, function(x) names(dat)[which.max(x)])
out
}
Voici un exemple d'utilisation 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
Voici un exemple d'utilisation lda
(je sais que lda peut gérer plusieurs classes, mais ce n'est qu'un exemple):
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
Ces fonctions devraient fonctionner pour tout modèle à 2 classes avec une interface de formule et une predict
méthode. Notez que vous devez séparer manuellement les composants X et Y, ce qui est un peu moche, mais écrire une interface de formule me dépasse pour le moment.
Cette approche a-t-elle un sens pour tout le monde? Existe-t-il un moyen de l'améliorer ou existe-t-il un package existant pour résoudre ce problème?
car
, ou l'un des*lab
paquets) aurait fourni une fonction comme la vôtre. Désolé, je ne peux pas aider. J'ai lu un peu sur le fonctionnement de k-way SVM et il semble que c'était plus compliqué que je ne l'aurais pensé.predict
méthode.Réponses:
Une façon de s'améliorer consiste à utiliser l' approche «pondérée toutes les paires» qui est censée être meilleure que «une contre toutes» tout en étant évolutive.
Comme pour les packages existants,
glmnet
prend en charge le logit multinomial (régularisé) qui peut être utilisé comme classificateur multi-classe.la source
glmnet
inclut unemultinomial
fonction de perte. Je me demande si cette fonction de perte pourrait être utilisée dans d'autres algorithmes en R, tels queada
ougbm
?ada
soit "réservé" à une fonction de perte spécifique (exponentielle), mais on pourrait étendre un autre boosting méthode basée sur la prise en charge de la fonction de perte multinomiale - par exemple, voir la page 360 des éléments de l'apprentissage statistique pour plus de détails sur le GBM multi-classes - K arbres binaires sont construits pour chaque itération de boosting où K est le nombre de classes (un seul arbre par itération) est nécessaire dans le cas binaire).