predict
по-прежнему требует, чтобы все переменные, используемые в вашей модели, были представлены в newdata
, но вы можете передать некоторые произвольные значения, например 0
s, в те ковариаты, которых у вас нет, а затем использовать type = "terms"
и terms = name_of_the_wanted_smooth_term
для продолжения. Использовать
sapply(gm2$smooth, "[[", "label")
#[1] "s(lon,lat)" "s(I(b.depth^0.5))" "s(c.dist)"
#[4] "s(temp.20m)"
чтобы проверить, какие гладкие члены есть в вашей модели.
## new spatial locations to predict
newdat <- read.table(text = "lon lat
1 -3.00 44
4 -2.75 44
7 -2.50 44
10 -2.25 44
13 -2.00 44
16 -1.75 44")
## "garbage" values, just to pass the variable names checking in `predict.gam`
newdat[c("b.depth", "c.dist", "temp.20m", "log.net.area")] <- 0
## prediction on the link scale
pred_link <- predict(gm2, newdata = newdat, type = "terms", terms = "s(lon,lat)")
# s(lon,lat)
#1 -1.9881967
#4 -1.9137971
#7 -1.6365945
#10 -1.1247837
#13 -0.7910023
#16 -0.7234683
#attr(,"constant")
#(Intercept)
# 2.553535
## simplify to vector
pred_link <- attr(pred_link, "constant") + rowSums(pred_link)
#[1] 0.5653381 0.6397377 0.9169403 1.4287511 1.7625325 1.8300665
## prediction on the response scale
pred_response <- gm2$family$linkinv(pred_link)
#[1] 1.760043 1.895983 2.501625 4.173484 5.827176 6.234301
Обычно я не использую predict.gam
, если хочу сделать прогноз для определенного гладкого термина. Логика predict.gam
заключается в том, чтобы сначала сделать прогноз для всех терминов, то есть так же, как вы делаете type = "terms"
. потом
- если
type = "link"
, сделать rowSums
для всех прогнозов по срокам плюс перехват (возможно, с offset
);
- если
type = "terms"
и "terms"
или "exclude"
не указаны, вернуть результат как есть;
- если
type = "terms"
и вы указали "terms"
и/или "exclude"
, выполняется некоторая постобработка, чтобы удалить термины, которые вам не нужны, и дать вам только те, которые вам нужны.
Таким образом, predict.gam
всегда будет выполнять вычисления для всех терминов, даже если вам нужен только один термин.
Зная неэффективность этого, я сделаю следующее:
sm <- gm2$smooth[[1]] ## extract smooth construction info for `s(lon,lat)`
Xp <- PredictMat(sm, newdat) ## predictor matrix
b <- gm2$coefficients[with(sm, first.para:last.para)] ## coefficients for this term
pred_link <- c(Xp %*% b) + gm2$coef[[1]] ## this term + intercept
#[1] 0.5653381 0.6397377 0.9169403 1.4287511 1.7625325 1.8300665
pred_response <- gm2$family$linkinv(pred_link)
#[1] 1.760043 1.895983 2.501625 4.173484 5.827176 6.234301
Видите ли, мы получаем тот же результат.
Не будет ли результат зависеть от значения, присвоенного ковариатам (здесь 0)?
Некоторое предсказание мусора будет сделано для этих значений мусора, но predict.gam
отбрасывает их в конце.
Спасибо, вы правы. Я не совсем уверен, что понимаю, почему тогда есть возможность добавлять значения ковариатов в новых местах.
Сопровождение кода, насколько я понимаю, очень сложно для такого большого пакета, как mgcv
. Код необходимо значительно изменить, если вы хотите, чтобы он соответствовал потребностям каждого пользователя. Очевидно, что описанная здесь логика predict.gam
будет неэффективной, когда люди вроде вас просто хотят, чтобы она предсказывала определенное сглаживание. И теоретически, если это так, проверка имен переменных в newdata
может игнорировать те термины, которые не нужны пользователям. Но это требует значительного изменения predict.gam
и потенциально может привести к множеству ошибок из-за изменений кода. Кроме того, вы должны отправить журнал изменений в CRAN, и CRAN может просто не обрадоваться такому радикальному изменению.
Саймон однажды поделился своими чувствами: Многие говорят мне, что я должен писать mgcv
так или так, но я просто не могу. Да, посочувствуйте такому автору/сопровождающему пакета, как он.
Спасибо за ответ об обновлении. Однако я не понимаю, почему прогнозы не зависят от значений ковариат в новых местах.
Это будет зависеть от того, предоставите ли вы значения ковариатов для b.depth
, c.dist
, temp.20m
, log.net.area
. Но так как у вас нет их в новых местах, прогноз состоит в том, чтобы предположить, что эти эффекты будут 0
.
Хорошо, спасибо, теперь я вижу! Итак, правильно ли было бы сказать, что в отсутствие значений ковариат в новых местах я только предсказываю реакцию на основе пространственной автокорреляции остатков?
Вы только предсказываете пространственное поле/гладкое. В подходе GAM пространственное поле моделируется как часть среднего, а не как дисперсия-ковариация (как в кригинге), поэтому я думаю, что ваше использование «остатков» здесь неверно.
Да, ты прав. Просто чтобы понять, что делает этот код: правильно ли будет сказать, что я предсказываю, как отклик меняется в пространстве, но не его фактические значения в новых местах (поскольку для этого мне понадобятся значения ковариат в этих местах)?
Правильный. Вы можете попробовать predict.gam
с terms = "s(lon,lat)"
или без него, чтобы помочь вам переварить вывод. Посмотрите, как она меняется, когда вы меняете значения мусора, передаваемые другим ковариатам.
## a possible set of garbage values for covariates
newdat[c("b.depth", "c.dist", "temp.20m", "log.net.area")] <- 0
predict(gm2, newdat, type = "terms")
# s(lon,lat) s(I(b.depth^0.5)) s(c.dist) s(temp.20m)
#1 -1.9881967 -1.05514 0.4739174 -1.466549
#4 -1.9137971 -1.05514 0.4739174 -1.466549
#7 -1.6365945 -1.05514 0.4739174 -1.466549
#10 -1.1247837 -1.05514 0.4739174 -1.466549
#13 -0.7910023 -1.05514 0.4739174 -1.466549
#16 -0.7234683 -1.05514 0.4739174 -1.466549
#attr(,"constant")
#(Intercept)
# 2.553535
predict(gm2, newdat, type = "terms", terms = "s(lon,lat)")
# s(lon,lat)
#1 -1.9881967
#4 -1.9137971
#7 -1.6365945
#10 -1.1247837
#13 -0.7910023
#16 -0.7234683
#attr(,"constant")
#(Intercept)
# 2.553535
## another possible set of garbage values for covariates
newdat[c("b.depth", "c.dist", "temp.20m", "log.net.area")] <- 1
# s(lon,lat) s(I(b.depth^0.5)) s(c.dist) s(temp.20m)
#1 -1.9881967 -0.9858522 -0.3749018 -1.269878
#4 -1.9137971 -0.9858522 -0.3749018 -1.269878
#7 -1.6365945 -0.9858522 -0.3749018 -1.269878
#10 -1.1247837 -0.9858522 -0.3749018 -1.269878
#13 -0.7910023 -0.9858522 -0.3749018 -1.269878
#16 -0.7234683 -0.9858522 -0.3749018 -1.269878
#attr(,"constant")
#(Intercept)
# 2.553535
predict(gm2, newdat, type = "terms", terms = "s(lon,lat)")
# s(lon,lat)
#1 -1.9881967
#4 -1.9137971
#7 -1.6365945
#10 -1.1247837
#13 -0.7910023
#16 -0.7234683
#attr(,"constant")
#(Intercept)
# 2.553535
person
Zheyuan Li
schedule
01.08.2018