如何在glm中指定特定的优化方法
How to specify a particular optimization method in glm
在 glm
的文档中,有一个 method
选项,在文档中它说
User-supplied fitting functions can be supplied either as a function
or a character string naming a function, with a function which takes
the same arguments as glm.fit. If specified as a character string it
is looked up from within the stats namespace.
我想使用二项式非负最小二乘优化器,使系数为非负且总和为 1。使用此优化器的一个示例在 SuperLearner
包中,其中包含选项 method = "method.NNLS"
。下面是一个可重现的例子:
library(SuperLearner)
# binary outcome
set.seed(1)
N <- 200
X <- matrix(rnorm(N*10), N, 10)
X <- as.data.frame(X)
Y <- rbinom(N, 1, plogis(.2*X[, 1] + .1*X[, 2] - .2*X[, 3] +
.1*X[, 3]*X[, 4] - .2*abs(X[, 4])))
SL.library <- c("SL.glmnet", "SL.glm", "SL.knn", "SL.mean")
# least squares loss function
test.NNLS <- SuperLearner(Y = Y, X = X, SL.library = SL.library,
verbose = TRUE, method = "method.NNLS", family = binomial())
> test.NNLS
Call:
SuperLearner(Y = Y, X = X, family = binomial(), SL.library = SL.library, method = "method.NNLS",
verbose = TRUE)
Risk Coef
SL.glmnet_All 0.2460486 0.0000000
SL.glm_All 0.2507033 0.2423697
SL.knn_All 0.2508500 0.3493301
SL.mean_All 0.2475494 0.4083002
请注意,Coef
是非负数且总和为 1。有没有办法使用与 glm
相同的优化器?或者使用相同约束的不同优化器?我试过:
glm(Y ~ as.matrix(X), family = "binomial", method = "method.NNLS")
但是没有用。
A 解决此问题的方法(不是唯一方法,可能不是最有效或最紧凑的方法)是对变换后的参数进行一般最大似然估计 space;最常见的此类转换可能是 加法对数比率转换 (例如 compositions::alr()
)。此解决方案使用 bbmle
包,它是 optim()
的包装器;在这种情况下,它实际上并没有比直接使用 optim()
提供太多优势
library(bbmle)
library(compositions)
linkfun <- function(mu) as.numeric(compositions::alr(mu))
invlink <- function(eta) as.numeric(compositions::alrInv(eta))
## negative log-likelihood function: first convert the parameter vector
## from the constrained (alr) space to the unconstrained space, then
## convert the linear predictor from an unconstrained space to the
## constrained (probability, (0,1)) space
lfun <- function(beta) {
-sum(dbinom(Y, size=1,
prob = plogis(as.matrix(X) %*% invlink(beta)),
log=TRUE))
}
npar <- ncol(X)
使用mle2
:
## extra setup for using mle2 with a score function that takes a vector
## parameter
pnm <- paste0("beta", seq(npar))
parnames(lfun) <- pnm
m1 <- mle2(lfun, start = setNames(rep(0, npar-1), pnm[-1]), vecpar = TRUE)
invlink(coef(m1))
## [1] 4.897617e-01 2.221793e-01 1.274830e-05 2.198596e-05 7.541545e-02
## [6] 1.175966e-01 1.590407e-05 4.662563e-02 4.825376e-02 1.170077e-04
或
opt <- optim(par = rep(0, npar-1), fn = lfun, method = "BFGS")
invlink(opt$par)
注释 1
我的模型拟合与您用于生成数据的方法不匹配(这将在公式中编码为 ~ 0 + x1 + x2 + x3 + x3:x4 + abs(x4)
),但您的 SuperLearner
示例也不匹配,所以我没有放心吧。
注释 2
我的猜测(未仔细考虑)是上述方法不会给出与使用SuperLearner
相同的结果;查看代码,SuperLearner
所做的是找到(加权)最小二乘问题的非负解,然后通过将系数向量除以其总和将系数转换为组合 space .这与解决 minimum-deviance/maximum-likelihood 问题不同,参数被限制为非负且总和为 1。如果您想要 SuperLearner
解决方案,它确实可以通过将适当的 method=
参数传递给 glm
来做到这一点,但我看不到如何使用 glm
.
进行约束 MLE 解决方案
在 glm
的文档中,有一个 method
选项,在文档中它说
User-supplied fitting functions can be supplied either as a function or a character string naming a function, with a function which takes the same arguments as glm.fit. If specified as a character string it is looked up from within the stats namespace.
我想使用二项式非负最小二乘优化器,使系数为非负且总和为 1。使用此优化器的一个示例在 SuperLearner
包中,其中包含选项 method = "method.NNLS"
。下面是一个可重现的例子:
library(SuperLearner)
# binary outcome
set.seed(1)
N <- 200
X <- matrix(rnorm(N*10), N, 10)
X <- as.data.frame(X)
Y <- rbinom(N, 1, plogis(.2*X[, 1] + .1*X[, 2] - .2*X[, 3] +
.1*X[, 3]*X[, 4] - .2*abs(X[, 4])))
SL.library <- c("SL.glmnet", "SL.glm", "SL.knn", "SL.mean")
# least squares loss function
test.NNLS <- SuperLearner(Y = Y, X = X, SL.library = SL.library,
verbose = TRUE, method = "method.NNLS", family = binomial())
> test.NNLS
Call:
SuperLearner(Y = Y, X = X, family = binomial(), SL.library = SL.library, method = "method.NNLS",
verbose = TRUE)
Risk Coef
SL.glmnet_All 0.2460486 0.0000000
SL.glm_All 0.2507033 0.2423697
SL.knn_All 0.2508500 0.3493301
SL.mean_All 0.2475494 0.4083002
请注意,Coef
是非负数且总和为 1。有没有办法使用与 glm
相同的优化器?或者使用相同约束的不同优化器?我试过:
glm(Y ~ as.matrix(X), family = "binomial", method = "method.NNLS")
但是没有用。
A 解决此问题的方法(不是唯一方法,可能不是最有效或最紧凑的方法)是对变换后的参数进行一般最大似然估计 space;最常见的此类转换可能是 加法对数比率转换 (例如 compositions::alr()
)。此解决方案使用 bbmle
包,它是 optim()
的包装器;在这种情况下,它实际上并没有比直接使用 optim()
library(bbmle)
library(compositions)
linkfun <- function(mu) as.numeric(compositions::alr(mu))
invlink <- function(eta) as.numeric(compositions::alrInv(eta))
## negative log-likelihood function: first convert the parameter vector
## from the constrained (alr) space to the unconstrained space, then
## convert the linear predictor from an unconstrained space to the
## constrained (probability, (0,1)) space
lfun <- function(beta) {
-sum(dbinom(Y, size=1,
prob = plogis(as.matrix(X) %*% invlink(beta)),
log=TRUE))
}
npar <- ncol(X)
使用mle2
:
## extra setup for using mle2 with a score function that takes a vector
## parameter
pnm <- paste0("beta", seq(npar))
parnames(lfun) <- pnm
m1 <- mle2(lfun, start = setNames(rep(0, npar-1), pnm[-1]), vecpar = TRUE)
invlink(coef(m1))
## [1] 4.897617e-01 2.221793e-01 1.274830e-05 2.198596e-05 7.541545e-02
## [6] 1.175966e-01 1.590407e-05 4.662563e-02 4.825376e-02 1.170077e-04
或
opt <- optim(par = rep(0, npar-1), fn = lfun, method = "BFGS")
invlink(opt$par)
注释 1
我的模型拟合与您用于生成数据的方法不匹配(这将在公式中编码为 ~ 0 + x1 + x2 + x3 + x3:x4 + abs(x4)
),但您的 SuperLearner
示例也不匹配,所以我没有放心吧。
注释 2
我的猜测(未仔细考虑)是上述方法不会给出与使用SuperLearner
相同的结果;查看代码,SuperLearner
所做的是找到(加权)最小二乘问题的非负解,然后通过将系数向量除以其总和将系数转换为组合 space .这与解决 minimum-deviance/maximum-likelihood 问题不同,参数被限制为非负且总和为 1。如果您想要 SuperLearner
解决方案,它确实可以通过将适当的 method=
参数传递给 glm
来做到这一点,但我看不到如何使用 glm
.