2015-01-18 2 views
0

일부 데이터에서 함수 w(t)을 만들려고합니다. 데이터를 반복하면서 함수를 만들고 이것을 w(t)에 추가하면됩니다. R이 변수를 평가할 때를 알지 못하기 때문에 발생하는 무한 재귀 문제가 발생합니다. 내가 얻는 오류 메시지는 다음과 같습니다.클로저를 사용하여 R에서 함수 증가 (기존 함수에 클로저를 사용하여 구성된 함수를 재귀 적으로 추가)

Error: evaluation nested too deeply: infinite recursion/ options(expressions=)? Error during wrapup: evaluation nested too deeply: infinite recursion/options(expressions=)?

다음은 Kernalised Perceptron의 예입니다. 나는 선형으로 분리 가능한 데이터를 생성하고 그것을 적합하게하려고 노력한다.

  1. 데이터에서 함수를 만듭니다 : 기능적 또한 내가 기능 kern.perceptron에서 발생 kernel <- FUN(x, ...). 이 호출에서 함수 function(t) (x %*% t)^3 (x는 이어야 함)은으로 계산됩니다. (나는 이것이 내가 떨어질 수있는 곳이라고 생각한다).
  2. 어떻게 올바르게 wHat(t) = wHat(t) + kernel(t) 그러한 기능을 업데이트 할 수 있습니다 추가/기존 기능 wHat

이 기능을 빼기?

prepend.bias <- function(X){ 
    cbind(rep(1, nrow(X)), X) 
} 

pred.perc <- function(X, w, add.bias=FALSE){ 
    X <- as.matrix(X) 
    if (add.bias) X <- prepend.bias(X) 
    sign(X %*% w) 
} 

polyKernel <- function(x, d=2){ 
    # Function that creates a kernel function for a given data point 
    # Expects data point as row matrix 
    function(t){ 
     # expects t as vector or col matrix 
     t <- as.matrix(t) 
     (x %*% t)^d 
    } 
} 

pred.kperc <- function(X, w, add.bias=FALSE){ 
    X <- as.matrix(X) 
    if (add.bias) X <- prepend.bias(X) 
    as.matrix(sign(apply(X, 1, w))) 
} 

kern.perceptron <- function(X, Y, max.epoch=1, verbose=FALSE, 
          FUN=polyKernel, ...) { 
    wHat <- function(t) 0 
    alpha <- numeric(0) 
    X <- prepend.bias(X) 
    bestmistakes <- Inf 
    n <- nrow(X) 
    for (epoch in 1:max.epoch) { 
     improved <- FALSE 
     mistakes <- 0 
     for (i in 1:n) { 
      x <- X[i,,drop=F] 
      yHat <- pred.kperc(x, wHat) 
      if (Y[i] != yHat) { 
       alpha <- c(alpha, Y[i]) 
       wPrev <- wHat 
       kernel <- FUN(x, ...) 
       if (Y[i] == -1){ 
        wHat <- function(t) wPrev(t) - kernel(t) 
       } else{ 
        wHat <- function(t) wPrev(t) + kernel(t) 
       } 

       mistakes <- mistakes + 1 
      } 
      else alpha <- c(alpha, 0) 
     } 
     totmistakes <- sum(Y != pred.kperc(X, wHat)) 
     if (totmistakes < bestmistakes){ 
      bestmistakes <- totmistakes 
      pocket <- wHat 
      improved <- TRUE 
     } 
     if (verbose) { 
      message(paste("\nEpoch:", epoch, "\nMistakes In Loop:", mistakes, 
          "\nCurrent Solution Mistakes:", totmistakes, 
          "\nBest Solution Mistakes:", bestmistakes)) 
      if (!improved) 
       message(paste("WARNING: Epoch", epoch, "No improvement")) 
     } 
    } 
    return(pocket) 
} 

set.seed(10230) 
w <- c(0.3, 0.9, -2) 
X <- gendata(100, 2) 
Y <- pred.perc(X, w, TRUE) 
wHat <- kern.perceptron(X, Y, 10, TRUE, polyKernel, d=3) 
+0

그것은 당신이 실제로 수행 할 작업을 전혀 분명하지 않다 ... 너무 폐쇄하지 않고이 작업을 수행 할 수 있습니다. * data *에서 * function *을 만드는 것은 의미가 없습니다. 함수에 파생 데이터를 적용하려면 해당 함수에 입력 인수를 추가하는 것이 좋습니다. "오류"라는 메시지가 있는지 여부와 상관없이 "작동 중"인 것을 표시하지 않았습니다. –

+0

데이터에서 기능 만들기 : 데이터 'x'는 기능이 무엇인지 정의합니다. 'polyKernel'은 데이터 포인트'x'와 옵션'd'에서 함수를 생성합니다. 예제 코드는 오류를 재현해야하지만 오류 메시지를 추가합니다. – kungfujam

+1

직면 한 문제를 보여주는 * 최소 * 작업 예제를 작성하는 것이 더 도움이됩니다. –

답변

2

나는 당신이 점점 더 깊이 중첩 된 함수 wHat를 createing 때문에이 스택 오버 플로우를 받고 생각합니다. 당신이

register(KernelFun,sign) 

전화

LL <- local({ 
    #initialize list of kernel functions in the closeure 
    funlist = list() 
    #a logical vector indicating whether or not to add or subtract the kernal functio 
    .sign = logical(zero) 


    #register a kernal function and it's sign 
    register <- function(fun,sign,x){ 
     funlist<<-c(funlist,list(fun)) 
     add<<-c(add,sign) 
    } 

    # wHat uses k in the closure without having to pass it as an argument 
    wHat <- function(t){ 

     out = 0 
     for(i in seq(length(.sign)) 
      if (.sign[i]){ 
       out <- out + funlist[[i]](t) 
      } else{ 
       out <- out - funlist[[i]](t) 
      } 
    } 
    list(wHat,register) 
}) 

wHat <- LL$wHat 
register <- LL$register 

다음 커널 인 기능을 등록하고

wHat(t) 

를 호출 할 때 당신이 얻을 : 당신은 같이 폐쇄에 커널 함수의 레지스트리를 유지할 수 registery에서 커널 함수의 합계, 내가 생각하는 것은 당신이 원하는 것입니다.

덧붙여, 당신은

+0

여기에 감사드립니다. 커널 함수를 함께 곱셈하지 않아도 문제를 해결하지는 못합니다. 또한 커널 함수는 데이터 포인트'x'와 클로저'polyKernel'을 사용하여 구성됩니다. – kungfujam

+0

wHat가 커널 함수 – Jthorpe

+0

의 합계가되도록 '기호'를 등록하는 것처럼'x' 값을 등록 할 수 있습니다. 이것은 중첩 기능을 사용하지 않고 원하는 것을 (일련의 커널 함수를 추가하기 위해) 어떻게 할 수 있는지에 대한 모델 일뿐입니다 – Jthorpe

관련 문제