我一直無法理解關於如何調用S3方法的文檔,並且這一次它讓我感到困擾。S3和類的順序
我會先問一個以上的問題,但他們都密切相關。在一組複雜功能的核心中,我創建了很多適合的東西,尤其是後勤部分。現在,glmnet
文檔指定其返回值具有「glmnet」和(邏輯迴歸)「lognet」兩個類。實際上,這些按照這個順序指定。
然而,看着glmnet
的執行結束後,調用(內部功能)lognet
,該套fit
後級點對點到「lognet」,我看這行代碼就在返回之前(變量fit
)的:
class(fit) = c(class(fit), "glmnet")
從此,我就得出這樣的結論類的順序,其實是「lognet」,「glmnet」。
不幸的是,我有合適的,只好(如DOC建議):
> class(myfit)
[1] "glmnet" "lognet"
與此問題的方式是S3方法分派它,特別是predict
。這裏的代碼爲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)
}
我已經添加了一條評論來解釋我的推理。現在,當我打電話預測這個myfit
一個新的數據矩陣mydata
和type="response"
,像這樣:
predict(myfit, newx=mydata, type="response")
,我不這樣做,因爲每個文檔,得到的預測概率,但線性組合,這是完全立即致電predict.glmnet
的結果。
我試圖扭轉類的順序,像這樣:
orgclass<-class(myfit)
class(myfit)<-rev(orgclass)
,然後做的預測再打電話:你瞧:它的作品!我做得到概率。
所以,來到這裏的一些問題:
- 我說得對在「已經瞭解到」那 S3方法是爲了類的外觀 出動?
- 我說得對在假設
glmnet
的代碼會導致爲predict
正確調度順序錯誤 ? - 在我的代碼中沒有任何東西 明確/明顯地操縱我的知識類 。 有什麼可能導致訂單變更爲 ?
爲了完整性:這裏的一些示例代碼一起玩(因爲我現在在做我自己):
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)
根據生成的數據,不同的是多了還是不太明顯(在我的真實數據集中,我注意到了所謂概率中的負值,這是我如何挑選問題的方法),但是您的確應該看到差異。
感謝您的任何意見。
編輯:
我剛剛發現了可怕的真相:無論是爲了在glmnet 1.5.2(這是目前在那裏我遇到了實際的代碼,導致配合帶班順序在服務器上工作反過來),但是來自1.6的代碼要求命令是「lognet」,「glmnet」。我還沒有檢查1.7中會發生什麼。
感謝@Aaron提醒我關於信息學的基礎知識(除了'如果一切都失敗了,重新啓動':'檢查你的版本')。我錯誤地認爲統計學習之神的一攬子計劃將免受這種類型的錯誤的影響),以及@Gavin確認我重構S3的工作原理。
當我運行你的代碼時,我在第一個'class'調用之後得到了命令'「lognet」「glmnet」'',這是從你說你得到的東西倒退。我有glmnet 1.7;你有什麼版本? – Aaron