我总是无法理解有关如何调用S3方法的文档,而这次它正在咬我。
我会在前面道歉,提出不止一个问题,但他们都是密切相关的。在一组复杂函数的核心深处,我创建了许多glmnet
拟合,特别是逻辑变量。现在,glmnet
文档指定其返回值以使类“glmnet”和(对于逻辑回归)“lognet”。实际上,这些是按此顺序指定的。
但是,在调用(内部函数)glmnet
之后查看lognet
的实现结束时,将fit
的类设置为“lognet”,我在返回(变量fit
)之前看到了这行代码:
class(fit) = c(class(fit), "glmnet")
由此,我得出结论,类的顺序实际上是“lognet”,“glmnet”。
不幸的是,我曾经拥有过(就像文档建议的那样):
> 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)
然后再次做预测电话:瞧瞧:它有效!我做获得概率。
所以,这里有一些问题:
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)
根据生成的数据,差异或多或少是显而易见的(在我的真实数据集中,我注意到所谓的概率中的负值,这就是我解决问题的方式),但你确实应该看到差异。 / p>
感谢您的任何意见。
修改:
我刚刚发现了一个可怕的事实:无论是在glmnet 1.5.2中运行的命令(在我运行实际代码的服务器上都存在,导致与类顺序相反),但1.6中的代码需要命令为“lognet”,“glmnet”。我还没有检查1.7中会发生什么。
感谢@Aaron提醒我信息学的基础知识(除了'如果所有其他方法都失败了,重启':'检查你的版本')。我错误地认为统计学习之神的包装将受到保护,免受此类错误的影响),并且@Gavin确认我重建S3的工作方式。
答案 0 :(得分:6)
是的,调度顺序是类属性中列出的顺序。在简单的,每天的情况下,是的,第一个声明的类是首先通过方法调度选择的类,并且只有当它找不到该类的方法(或者NextMethod
被调用)时才会继续到第二课,或者没有找到default
方法。
不,我认为你的代码顺序错误是正确的。文档显示错误。目的显然是首先调用predict.lognet()
,使用主力predict.glmnet()
对由 glmnet 拟合的所有类型的套索/弹性网模型进行基本计算,最后做一些后处理那些一般预测。从 glmnet NAMESPACE导出的predict.glmnet()
,而其他方法也许也是如此。
我不确定你为什么认为这个输出:
predict(myfit, newx=mydata, type="response")
错了?我得到一个10行和21列的矩阵,其中列与仅截距模型预测相关,加上20个λ值的预测,在该值处计算了沿套索/弹性网路径的模型系数。这些似乎不是线性组合,而是您所要求的响应比例。
班级顺序没有变化。我认为你误解了代码应该如何工作。文档中有一个错误,因为那里的排序错误。但是代码正在按照我的想法运作。