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?
predict
Methode.
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.