2017-01-15 20 views
4

Я хотел бы перекрестить проверку модели GAM с помощью каретки. Моя модель GAM имеет двоичную исходную переменную, изотропную гладкую координаты широты и долготы, а затем линейные предиктора. Типичный синтаксис при использовании mgcv является:Комплект Caret - перекрестная проверка GAM с плавным и линейным предикторами

gam1 <- gam(y ~ s(lat , long) + x1 + x2, family = binomial(logit)) 

Я не совсем уверен, как определить эту модель с помощью функции поезда в каретке. Это мой синтаксис более или менее:

cv <- train(y ~ lat + long + x1 + x2, 
      data = data, 
      method = "gam", 
      family = "binomial", 
      trControl = trainControl(method = "LOOCV", number=1, repeats=), 
      tuneGrid = data.frame(method = "GCV.Cp", select = FALSE)) 

Проблема заключается в том, что я только хочу, лат и долго быть сглажены и x1 и x2 должны рассматриваться как линейная.

Спасибо!

+0

согласен с @ 李哲源 ZheyuanLi но не 'каретка :: train' принимает регресс или сглаживающий сплайн функции в аргументе формулы? –

+0

Я не вижу никаких трудностей с использованием сплайнов или полиномиальных функций в аргументе формулы для 'train', когда' method = "glm" '. –

ответ

4

Очень интересно видеть, что кто-то использует mgcv снаружи mgcv. После небольшого исследования я здесь, чтобы расстроить вас: использование mgcv с caret - плохая идея, по крайней мере, с текущей поддержкой от caret.

Давайте мне задать вам несколько основных вопросов, если вы используете caret:

  1. Как вы можете указать количество узлов, а также сплайн базисный класс для гладкой функции?
  2. Как вы можете указать 2D гладкую функцию?
  3. Как вы можете указать сплайн продукта сплайна с te или ti?
  4. Как вы можете настроить параметры сглаживания?

Если вы хотите знать, что 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)) 
      ## Intercept family if passed in 
      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) линию? Эта линия является ключом, тогда как другие строки - это просто рутинная конструкция модельного вызова. Итак, давайте иметь чек с тем, что GAM формула caret строит:

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   x   z   a   b 
#1 -0.30258559 0.8966972 0.1478457 0.07721866 0.3871130 
#2 -0.59518832 0.2655087 0.6588776 0.13853856 0.8718050 
#3 -0.06978648 0.3721239 0.1850700 0.04752457 0.9671970 
#4 -0.17002059 0.5728534 0.9543781 0.03391887 0.8669163 
#5 0.55452069 0.9082078 0.8978485 0.91608902 0.4377153 
#6 -0.17763650 0.2016819 0.9436971 0.84020039 0.1919378 

Таким образом, мы стремимся, чтобы соответствовать модели: 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 и т.д.

+0

Спасибо, все хорошие моменты. Да, если я хотел бы сравнить адаптивные с tp для сглаживания, я не вижу, как это сделать в каретке. Поэтому я предполагаю, что должен быть способ жесткого кодирования перекрестной проверки, но это выходит за рамки моих навыков. Может ли кто-нибудь указать на какой-нибудь код, где я могу это сделать? Thanks –

+0

Понравилось, спасибо. Новенький тут :) –

 Смежные вопросы

  • Нет связанных вопросов^_^