Dieses Dokument zu Adaboost enthält einige Vorschläge und Codes (Seite 17) für die Erweiterung von 2-Klassen-Modellen auf Probleme der K-Klasse. Ich möchte diesen Code so verallgemeinern, dass ich problemlos verschiedene 2-Klassen-Modelle anschließen und die Ergebnisse vergleichen kann. Da die meisten Klassifizierungsmodelle über eine Formelschnittstelle und eine predict
Methode verfügen, sollte ein Teil davon relativ einfach sein. Leider habe ich keine Standardmethode zum Extrahieren von Klassenwahrscheinlichkeiten aus 2-Klassen-Modellen gefunden, sodass für jedes Modell ein benutzerdefinierter Code erforderlich ist.
Hier ist eine Funktion, die ich geschrieben habe, um ein Problem der K-Klasse in Probleme der 2-Klasse aufzuteilen und K-Modelle zurückzugeben:
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)
}
Hier ist eine Vorhersagemethode, die ich geschrieben habe, um jedes Modell zu durchlaufen und Vorhersagen zu treffen:
predict.oneVsAll <- function(object, newX=object$info$X, ...) {
stopifnot(class(object)=='oneVsAll')
lapply(object$models, function(x) {
predict(x, newX, ...)
})
}
Und schließlich ist hier eine Funktion, um eine data.frame
der vorhergesagten Wahrscheinlichkeiten zu normalisieren und die Fälle zu klassifizieren. Beachten Sie, dass es an Ihnen liegt, die K-Spalte data.frame
der Wahrscheinlichkeiten aus jedem Modell zu erstellen, da es keine einheitliche Möglichkeit gibt, Klassenwahrscheinlichkeiten aus einem 2-Klassen-Modell zu extrahieren:
classify <- function(dat) {
out <- dat/rowSums(dat)
out$Class <- apply(dat, 1, function(x) names(dat)[which.max(x)])
out
}
Hier ist ein Beispiel mit 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
Hier ist ein Beispiel mit lda
(ich weiß, dass lda mehrere Klassen verarbeiten kann, aber dies ist nur ein Beispiel):
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
Diese Funktionen sollten für jedes 2-Klassen-Modell mit einer Formelschnittstelle und einer predict
Methode funktionieren . Beachten Sie, dass Sie die X- und Y-Komponenten manuell aufteilen müssen, was etwas hässlich ist, aber das Schreiben einer Formelschnittstelle ist mir im Moment ein Rätsel.
Ist dieser Ansatz für alle sinnvoll? Gibt es eine Möglichkeit, es zu verbessern, oder gibt es ein vorhandenes Paket, um dieses Problem zu lösen?
car
oder eines der*lab
Pakete) eine Funktion wie Ihre bereitgestellt hätte. Entschuldigung, ich kann nicht helfen. Ich habe ein bisschen darüber gelesen, wie K-Way-SVM funktioniert, und es scheint komplizierter zu sein, als ich gedacht hätte.predict
Methode.Antworten:
Eine Möglichkeit zur Verbesserung besteht darin, den Ansatz "Alle Paare gewichtet" zu verwenden, der angeblich besser als "Eins gegen alle" ist, während er noch skalierbar ist.
glmnet
Unterstützt bei vorhandenen Paketen (reguliertes) multinomiales Logit, das als Klassifikator für mehrere Klassen verwendet werden kann.quelle
glmnet
auch einemultinomial
Verlustfunktion. Ich frage mich, ob diese Verlustfunktion in anderen Algorithmen in R verwendet werden könnte, wieada
odergbm
?ada
ist sie für eine bestimmte (exponentielle) Verlustfunktion "reserviert", aber man könnte eine weitere Erhöhung erweitern -basierte Methode zur Unterstützung der multinomialen Verlustfunktion - siehe z. B. Seite 360 der Elemente des statistischen Lernens für Details zu GBM mit mehreren Klassen - K-Binärbäume werden für jede Boosting-Iteration erstellt, wobei K die Anzahl der Klassen ist (nur ein Baum pro Iteration) wird im binären Fall benötigt).