Tôi đã gặp khó khăn khi hiểu tài liệu về cách thức gọi S3, và lần này nó cắn tôi trở lại.S3 và thứ tự của các lớp
Tôi xin lỗi trước vì đã hỏi nhiều câu hỏi nhưng tất cả đều có liên quan chặt chẽ. Sâu trong trái tim của một tập hợp các hàm phức tạp, tôi tạo ra rất nhiều phù hợp với glmnet
, đặc biệt là các logistic. Bây giờ, tài liệu glmnet
chỉ định giá trị trả lại của nó để có cả hai lớp "glmnet" và (đối với hồi quy logistic) "lognet". Trong thực tế, chúng được xác định theo thứ tự này.
Tuy nhiên, hãy xem kết thúc việc triển khai glmnet
, sau khi cuộc gọi đến (chức năng nội bộ) lognet
, đặt lớp fit
thành "lognet", tôi thấy dòng mã này ngay trước khi trả lại (của biến fit
):
class(fit) = c(class(fit), "glmnet")
Từ đó, tôi sẽ kết luận rằng thứ tự của các lớp là trong thực tế "lognet", "glmnet".
Thật không may, phù hợp tôi đã có, đã có (như doc gợi ý):
> class(myfit)
[1] "glmnet" "lognet"
Vấn đề ở đây là cách phương pháp S3 được cử cho nó, đặc biệt là predict
. Đây là mã cho predict.lognet
:
function (object, newx, s = NULL, type = c("link", "response",
"coefficients", "class", "nonzero"), exact = FALSE, offset,
...)
{
type = match.arg(type)
nfit = NextMethod("predict") #<- supposed to call predict.glmnet, I think
switch(type, response = {
pp = exp(-nfit)
1/(1 + pp)
}, class = ifelse(nfit > 0, 2, 1), nfit)
}
Tôi đã thêm nhận xét để giải thích lý do của tôi. Bây giờ khi tôi gọi dự đoán trên myfit
này với một Datamatrix mới mydata
và type="response"
, như thế này:
predict(myfit, newx=mydata, type="response")
, tôi không, theo các tài liệu, được xác suất dự đoán, nhưng sự kết hợp tuyến tính, mà là chính xác kết quả của việc gọi predict.glmnet
ngay lập tức.
tôi đã cố gắng đảo ngược thứ tự của các lớp học, như vậy:
orgclass<-class(myfit)
class(myfit)<-rev(orgclass)
Và sau đó thực hiện các dự đoán gọi lại: lo and behold: nó hoạt động! Tôi làm nhận được xác suất.
Vì vậy, ở đây đến một số câu hỏi:
- Tôi có ngay trong 'đã học được' mà S3 phương pháp được cử theo thứ tự sự xuất hiện của các lớp?
- Tôi có thể giả định mã số trong
glmnet
sẽ gây ra thứ tự sai để gửi đi chính xácpredict
? - Trong mã của tôi, không có gì là thao túng các lớp học một cách rõ ràng/rõ ràng với kiến thức của tôi. Điều gì có thể khiến đơn đặt hàng đến số thay đổi?
Đối với đầy đủ lợi ích: đây là một số mẫu mã để chơi xung quanh với (như tôi đang làm bản thân mình bây giờ):
library(glmnet)
y<-factor(sample(2, 100, replace=TRUE))
xs<-matrix(runif(100), ncol=1)
colnames(xs)<-"x"
myfit<-glmnet(xs, y, family="binomial")
mydata<-matrix(runif(10), ncol=1)
colnames(mydata)<-"x"
class(myfit)
predict(myfit, newx=mydata, type="response")
class(myfit)<-rev(class(myfit))
class(myfit)
predict(myfit, newx=mydata, type="response")
class(myfit)<-rev(class(myfit))#set it back
class(myfit)
Tùy thuộc vào dữ liệu được tạo ra, sự khác biệt là nhiều hơn hoặc ít rõ ràng (trong tập dữ liệu thực sự của tôi, tôi nhận thấy các giá trị âm trong cái gọi là xác suất, đó là cách tôi đã chọn vấn đề), nhưng bạn thực sự sẽ thấy sự khác biệt.
Cảm ơn mọi đầu vào.
Sửa:
Tôi vừa phát hiện ra sự thật khủng khiếp: hoặc để làm việc trong glmnet 1.5.2 (đó là hiện tại trên máy chủ nơi tôi chạy mã thực tế, kết quả là phù hợp với thứ tự lớp đảo ngược), nhưng mã từ 1.6 yêu cầu thứ tự là "lognet", "glmnet". Tôi chưa kiểm tra những gì xảy ra trong 1.7.
Nhờ @Aaron để nhắc tôi về các khái niệm cơ bản về tin học (bên cạnh 'nếu mọi thứ khác không thành công, hãy khởi động lại': 'kiểm tra phiên bản của bạn'). Tôi đã nhầm tưởng rằng một gói của các vị thần học tập thống kê sẽ được bảo vệ khỏi loại lỗi này), và để @Gavin xác nhận việc tái thiết của tôi về cách thức S3 hoạt động.
Khi tôi chạy mã, tôi nhận được lệnh "" lognet "" glmnet "' sau lệnh gọi 'lớp' đầu tiên, ngược lại với những gì bạn nói. Tôi có glmnet 1.7; bạn có phiên bản nào – Aaron