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à predict
phươ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.frame
xá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.frame
xá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à predict
phươ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?
predict
phương thức.
car
, hoặc một trong các*lab
gó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ĩ.