Mở rộng các mô hình 2 lớp cho các vấn đề đa lớp


11

Bài viết này trên Adaboost đưa ra một số gợi ý và mã (trang 17) để mở rộng các mô hình 2 lớp cho các vấn đề của lớp K. Tôi muốn khái quát mã này, để tôi có thể dễ dàng cắm vào các mô hình 2 lớp khác nhau và so sánh kết quả. Bởi vì hầu hết các mô hình phân loại có giao diện công thức và predictphương thức, một số điều này sẽ tương đối dễ dàng. Thật không may, tôi đã không tìm thấy một cách tiêu chuẩn để trích xuất xác suất của lớp từ các mô hình 2 lớp, vì vậy mỗi mô hình sẽ yêu cầu một số mã tùy chỉnh.

Đây là một chức năng tôi đã viết để chia nhỏ vấn đề của lớp K thành các vấn đề 2 lớp và trả về các mô hình 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)
}

Đây là một phương pháp dự đoán mà tôi đã viết để lặp lại qua từng mô hình và đưa ra dự đoán:

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

Và cuối cùng, đây là một chức năng để bình thường hóa một data.framexác suất dự đoán và phân loại các trường hợp. Lưu ý rằng tùy thuộc vào bạn để xây dựng cột K data.framexác suất từ ​​mỗi mô hình, vì không có cách thống nhất để trích xuất xác suất của lớp từ mô hình 2 lớp:

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

Đây là một ví dụ sử dụng 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

Dưới đây là một ví dụ sử dụng lda(tôi biết lda có thể xử lý nhiều lớp, nhưng đây chỉ là một ví dụ):

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

Các hàm này sẽ hoạt động cho bất kỳ mô hình 2 lớp nào với giao diện công thức và predictphương thức. Lưu ý rằng bạn phải tự tách các thành phần X và Y, điều này hơi xấu, nhưng việc viết giao diện công thức là vượt quá tôi vào lúc này.

Liệu cách tiếp cận này có ý nghĩa với tất cả mọi người? Có cách nào tôi có thể cải thiện nó, hoặc có một gói hiện có để giải quyết vấn đề này không?


2
Ồ, cho đến khi bạn hỏi và tôi đã xem, tôi đã chắc chắn rằng một số gói (như car, hoặc một trong các *labgói) sẽ cung cấp một chức năng như của bạn. Xin lỗi tôi không thể giúp. Tôi đã đọc một chút về cách hoạt động của SVM k-way và có vẻ như nó phức tạp hơn tôi nghĩ.
Wayne

1
@Wayne: Tôi cũng vậy! Tôi chắc chắn sẽ có một số chức năng chung sẽ làm điều này, miễn là mô hình có một predictphương thức.
Zach

Câu trả lời:


1

Một cách để cải thiện là sử dụng phương pháp "tất cả các cặp có trọng số" được cho là tốt hơn so với "một so với tất cả" trong khi vẫn có thể mở rộng.

Đối với các gói hiện có, glmnetlogit đa phương hỗ trợ (chính quy) có thể được sử dụng như một trình phân loại nhiều lớp.


Tôi biết nhiều gói trong R hỗ trợ phân loại nhiều lớp (như glmnet, rừng ngẫu nhiên, kernlab, rpart, nnet, v.v.). Tôi tò mò hơn về việc mở rộng các gói phân loại nhị phân (ví dụ gbm) cho các vấn đề đa lớp. Tôi sẽ xem xét "trọng số tất cả các cặp."
Zach

Ngoài ra, thật thú vị glmnetbao gồm multinomialchức năng mất. Tôi tự hỏi nếu hàm mất này có thể được sử dụng trong các thuật toán khác trong R, chẳng hạn như adahay gbm?
Zach

Có, một số phương pháp có thể được mở rộng để hỗ trợ chức năng mất đa cực. Ví dụ, hồi quy logistic kernel được mở rộng theo cách đó tại đây: Books.nips.cc/ con / files / nn1414 / A1313.pdf Theo như biết adalà "dành riêng" cho một hàm mất (theo cấp số nhân) cụ thể, nhưng người ta có thể mở rộng một mức tăng khác Phương pháp dựa trên để hỗ trợ chức năng mất đa phương thức - ví dụ: xem trang 360 của Yếu tố học thống kê để biết chi tiết về GBM đa lớp - Cây nhị phân K được xây dựng cho mỗi lần lặp tăng cường trong đó K là số lớp (chỉ một cây trên mỗi lần lặp là cần thiết trong trường hợp nhị phân).
Yevgeny
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.