R внедрить функцию в функцию

Я пытаюсь написать функцию, которая будет выполнять k-кратную перекрестную проверку модели логистической регрессии с использованием разных пороговых значений. Под порогами я подразумеваю, с какой вероятностью выходные данные модели превращаются в прогноз 1 или 0. Например, используя порог 0,4, вероятность 0,42 будет закодирована как прогноз 1.

Чтобы выполнить перекрестную проверку с использованием логистической регрессии, мне нужно создать собственную функцию стоимости (по умолчанию вычисляется MSE) и передать ее функции cv.glm(). Приведенная ниже функция будет работать, если я использую статический порог, но я хочу, чтобы порог менялся в каждом цикле, поэтому я встроил свою функцию стоимости в свой цикл. Я получаю сообщение об ошибке «объект, который я не нашел». Есть ли способ создать новую функцию внутри функции, используя аргументы, не указанные во встроенной функции?

logit.CV<-function(data, model, K, firstThreshold, lastThreshold) {
    error<-NULL

for(i in seq_along(firstThreshold:lastThreshold) {   

    costFunction<-function(y, pred) {
        pred<-ifelse(pred > (i+firstThreshold-1)/10, 1, 0)
        mean(abs(y-pred) > .5) 
    }

error[i]<-cv.glm(amData, logit.mod, cost=costFunction, K=10)$delta[1]

}

print(error)

}

person Woody Harelson    schedule 22.05.2014    source источник
comment
Я бы, вероятно, просто создал свою собственную версию cv.glm, которая использует ... для передачи дополнительных аргументов в функцию cost, а затем каждый раз передает i через цикл.   -  person joran    schedule 23.05.2014


Ответы (1)


Не похоже, что в этом есть что-то изначально неправильное. Этот пример, кажется, работает

runner<-function(f, n) f(n)

for(i in 1:10) {
   pepper<-function(n) {
       rep(n,i)
   }
   print(runner(pepper, letters[i]))
}

Таким образом, у него должно быть что-то конкретное, связанное с тем, как cv.glm вызывает функцию. Как насчет

logit.CV<-function(data, model, K, firstThreshold, lastThreshold) {
    error<-NULL

    getCostFunction<-function(i) {
        function(y, pred) {
            pred<-ifelse(pred > (i+firstThreshold-1)/10, 1, 0)
            mean(abs(y-pred) > .5) 
        }
    }

    for(i in seq_along(firstThreshold:lastThreshold) {   
        error[i] <- cv.glm(amData, logit.mod, cost=getCostFunction(i), K=10)$delta[1]
    }

    print(error)
}

Если это все еще не работает, возможно, вы можете сделать воспроизводимый пример, используя тестовые данные в пакете, чтобы другие могли его запустить и попробовать.

person MrFlick    schedule 22.05.2014