2-sınıf modelleri çok-sınıflı problemlere genişletme


11

Adaboost'taki bu çalışma , 2 sınıf modellerin K sınıfı sorunlara genişletilmesi için bazı öneriler ve kodlar (sayfa 17) sunmaktadır. Bu kodu genelleştirmek istiyorum, böylece kolayca farklı 2 sınıf modelleri takabilir ve sonuçları karşılaştırabilirim. Çoğu sınıflandırma modeli bir formül arayüzüne ve bir predictyönteme sahip olduğundan, bunların bazıları nispeten kolay olmalıdır. Ne yazık ki, 2 sınıf modellerden sınıf olasılıklarını çıkarmanın standart bir yolunu bulamadım, bu yüzden her model bazı özel kodlar gerektirecektir.

İşte bir K-sınıfı problemini 2-sınıf problemlerine ayırmak ve K modellerini döndürmek için yazdığım bir fonksiyon:

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)
}

İşte her model üzerinde yineleme yapmak ve tahminler yapmak için yazdığım bir tahmin yöntemi:

predict.oneVsAll <- function(object, newX=object$info$X, ...) {
    stopifnot(class(object)=='oneVsAll')
    lapply(object$models, function(x) {
        predict(x, newX, ...)
    })
}

Ve son olarak, data.frametahmin edilen olasılıkları bir normalize etme ve vakaları sınıflandırma işlevi . data.frameİki sınıflı bir modelden sınıf olasılıklarını elde etmenin birleşik bir yolu olmadığından, her modelden olasılıkların K sütununu oluşturmanın size bağlı olduğunu unutmayın :

classify <- function(dat) {
    out <- dat/rowSums(dat)
    out$Class <- apply(dat, 1, function(x) names(dat)[which.max(x)])
    out
}

İşte bir örnek 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

İşte bir örnek lda(Ben lda birden çok sınıf işleyebilir biliyorum, ama bu sadece bir örnek):

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

Bu işlevler, formül arabirimi ve predictyöntemi olan her 2 sınıf model için çalışmalıdır . Biraz çirkin olan X ve Y bileşenlerini manuel olarak ayırmanız gerektiğini unutmayın, ancak şu anda bir formül arayüzü yazmak benim dışımda.

Bu yaklaşım herkese mantıklı geliyor mu? Bunu geliştirebilmemin bir yolu var mı veya bu sorunu çözmek için mevcut bir paket var mı?


2
Vay canına, siz sorduktan ve ben bakana kadar, bazı paketlerin ( carveya *labpaketlerden biri gibi) sizinki gibi bir işlev sağlayacağından emin olabilirdim. Üzgünüm yardım edemem. K-yönlü SVM'nin nasıl çalıştığı hakkında biraz okudum ve düşündüğümden daha karmaşık gibi görünüyor.
Wayne

1
@Wayne: Ben de! Modelin bir predictyöntemi olması şartıyla, bunu yapacak bazı genel işlevlerin olacağından emindim .
Zach

Yanıtlar:


1

Geliştirmenin bir yolu , hala ölçeklenebilirken "herkese karşı birinden" daha iyi olduğu düşünülen "tüm çiftlerin ağırlıklı" yaklaşımını kullanmaktır .

Mevcut paketlere gelince, glmnetçok sınıflı bir sınıflandırıcı olarak kullanılabilen (normalleştirilmiş) çok terimli logit'i destekler.


R'de çok sınıflı sınıflandırmayı (glmnet, rastgele ormanlar, kernlab, rpart, nnet, vb.) Destekleyen birçok paketin farkındayım. İkili sınıflandırma paketlerini (örn. Gbm) çoklu sınıf sorunlarına genişletme konusunda daha çok merak ediyorum. "Tüm çiftleri ağırlıklı" olarak inceleyeceğim.
Zach

Ayrıca, glmnetbir multinomialkayıp fonksiyonu içeren ilginçtir . Bu kayıp fonksiyonunun R gibi diğer algoritmalarda kullanılabileceğini, adaveya gbm?
Zach

Evet, bazı yöntemler multinomiyal kayıp fonksiyonunu desteklemek için genişletilebilir. Örneğin, çekirdek lojistik regresyonu şu şekilde genişletilir: books.nips.cc/papers/files/nips14/AA13.pdf Bilindiği kadarıyla, adabelirli bir (üstel) kayıp fonksiyonu için "ayrılmış", ancak biri başka bir güçlendirmeyi uzatabilir sınıflı kayıp işlevini desteklemek için temelli yöntem - örneğin, çok sınıflı GBM ile ilgili ayrıntılar için İstatistiksel Öğrenme Unsurları'nın 360. sayfasına bakın - K ikili ağaçları, K'nin sınıf sayısı olduğu her yineleme yinelemesi için oluşturulur (yineleme başına sadece bir ağaç) ikili durumda gereklidir).
Yevgeny
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.