看到有人在mgcv
之外使用它非常有趣。经过一番研究,我来告诉你一个令人沮丧的消息:当前版本的caret
对mgcv
的支持不太好,所以在caret
中使用mgcv
是个坏主意。
如果你正在使用caret
,让我问你几个基本问题:
- 如何指定平滑函数的节点数和样条基类?
- 如何指定二维平滑函数?
- 如何使用
te
或ti
指定张量积样条?
- 如何微调平滑参数?
如果你想知道caret::train
在使用method = "gam"
时在做什么,请查看其拟合例程:
getModelInfo(model = "gam", regex = FALSE)$gam$fit
function(x, y, wts, param, lev, last, classProbs, ...) {
dat <- if(is.data.frame(x)) x else as.data.frame(x)
modForm <- caret:::smootherFormula(x)
if(is.factor(y)) {
dat$.outcome <- ifelse(y == lev[1], 0, 1)
dist <- binomial()
} else {
dat$.outcome <- y
dist <- gaussian()
}
modelArgs <- list(formula = modForm,
data = dat,
select = param$select,
method = as.character(param$method))
theDots <- list(...)
if(!any(names(theDots) == "family")) modelArgs$family <- dist
modelArgs <- c(modelArgs, theDots)
out <- do.call(getFromNamespace("gam", "mgcv"), modelArgs)
out
}
你看到了 modForm <- caret:::smootherFormula(x)
这一行吗?这行是关键,其他行只是模型调用的例行构造。因此,让我们来检查一下 caret
构造的 GAM 公式:
caret:::smootherFormula
function (data, smoother = "s", cut = 10, df = 0, span = 0.5,
degree = 1, y = ".outcome")
{
nzv <- nearZeroVar(data)
if (length(nzv) > 0)
data <- data[, -nzv, drop = FALSE]
numValues <- sort(apply(data, 2, function(x) length(unique(x))))
prefix <- rep("", ncol(data))
suffix <- rep("", ncol(data))
prefix[numValues > cut] <- paste(smoother, "(", sep = "")
if (smoother == "s") {
suffix[numValues > cut] <- if (df == 0)
")"
else paste(", df=", df, ")", sep = "")
}
if (smoother == "lo") {
suffix[numValues > cut] <- paste(", span=", span, ",degree=",
degree, ")", sep = "")
}
if (smoother == "rcs") {
suffix[numValues > cut] <- ")"
}
rhs <- paste(prefix, names(numValues), suffix, sep = "")
rhs <- paste(rhs, collapse = "+")
form <- as.formula(paste(y, rhs, sep = "~"))
form
}
简而言之,它创建了加法的、一元的平滑曲线。这是GAM最初提出时的经典形式。
为此,您在mgcv
上失去了大量控制权,如先前所列。
为了验证这一点,让我构建一个类似于您情况的示例:
set.seed(0)
dat <- gamSim(eg = 2, scale = 0.2)$data[1:3]
dat$a <- runif(400)
dat$b <- runif(400)
dat$y <- with(dat, y + 0.3 * a - 0.7 * b)
因此,我们的目标是拟合模型:y ~ s(x, z) + a + b
。数据y
是高斯分布的,但这并不重要,它不会影响caret
如何使用mgcv
。
cv <- train(y ~ x + z + a + b, data = dat, method = "gam", family = "gaussian",
trControl = trainControl(method = "LOOCV", number=1, repeats=1),
tuneGrid = data.frame(method = "GCV.Cp", select = FALSE))
您可以提取最终模型:
fit <- cv[[11]]
那么它使用的是什么公式?
fit$formula
#.outcome ~ s(x) + s(z) + s(a) + s(b)
看到了吗?除了是“可加的、单变量的”之外,它还将 mgcv::s
的所有内容都保留为默认值:默认bs = "tp"
,默认k = 10
等等。
caret::train
函数在其公式参数中是否接受回归或平滑样条函数呢? - IRTFMmethod="glm"
时,在公式参数中使用样条或多项式函数,我没有发现任何困难。 - IRTFM