Функция выдает NA при увеличении размера данных - PullRequest
0 голосов
/ 15 марта 2019

Я реализую свою функцию в R и пытаюсь по результатам определить, соответствует ли она ожиданиям.Функция, которую я пытаюсь оценить:

enter image description here

Функция работает нормально, пока я не увеличу размер своей матрицы данных (например, она работает для N =10, но не тогда, когда N = 12, и пример будет опубликован ниже.)

Я уверен, что что-то связано с моей реализацией или проблемами с переполнением.

# Generate Sample Data
gen.sample <- function(n){
  x <- runif(n,min = -5,max = 5)
  y <- ifelse(x < 0,-1,1)
  return(data.frame(x,y))
}

# Objective function L_D
obj_fun <- function(X,y,alpha){
  N <- length(X) 
  inner.product <- numeric(N)
  for(i in 1:N){
    for(k in 1:N){
      inner.product[k] <- alpha[i]*alpha[k]*
        y[i]*y[k]*(t(as.numeric(X[i]))%*%as.numeric(X[k]))
    }
  }
  L_D <- sum(alpha) - 0.5*sum(inner.product)
  return(L_D)
}

# L_D works when N = 10
set.seed(4997)
options(digits = 4,scipen = -4)
N = 10
sample.data <- gen.sample(n=N)
X.data <- sample.data$x
y.vec <- sample.data$y

alpha.vector <- matrix(rep(c(-5,-4,-3,-2,-1,0,1,2,3,4,5),11*N),ncol = 11, nrow = N, byrow = TRUE)
for(j in 1:N){
  alpha.vector[j,2] <- rnorm(1,5,5)
}

for(i in 1:N){
  print(obj_fun(X = X.data, y = y.vec, alpha =  alpha.vector[i,]))
}

# It produces all NA when N = 12

set.seed(4997)
options(digits = 4,scipen = -4)
N = 12
sample.data <- gen.sample(n=N)
X.data <- sample.data$x
y.vec <- sample.data$y

alpha.vector <- matrix(rep(c(-5,-4,-3,-2,-1,0,1,2,3,4,5),11*N),ncol = 11, nrow = N, byrow = TRUE)
for(j in 1:N){
  alpha.vector[j,2] <- rnorm(1,5,5)
}

for(i in 1:N){
  print(obj_fun(X = X.data, y = y.vec, alpha =  alpha.vector[i,]))
}
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA
[1] NA

Чтопойдет не так?Я не вижу проблемы.

Любая помощь будет отличной!

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Проблема в этом цикле в obj_fun и связана с тем, что вы используете для alpha:

for(i in 1:N){
    for(k in 1:N){
      inner.product[k] <- alpha[i]*alpha[k]*...
    }
  }

Две вещи:

(1) вы устанавливаете N=12, но вы звоните obj_fun(..., alpha=alpha.vector[i,]), где alpha.vector[i,] - вектор длины 11. Цикл, который я вставил выше, пытается получить доступ к alpha[i], когда i=N, то есть NA, потому что в alpha

нет 12-го элемента

(2) Обратите внимание, что происходит, когда вы проходите через двойной цикл: когда i=1 и k=1, вы присваиваете значение inner.product[1]. Затем i=1 и k=2, и вы присваиваете значение inner.product[2]. Это хорошо, пока i не изменится так, чтобы i=2. Когда i=2 и k=1, вы перезаписываете inner.product[1], назначая ему новое значение. Это продолжается до i=N и k=N, когда вы перезаписываете inner.product[k] для всех k, но на этот раз с NA, потому что вы выполняете вычисления, включающие alpha[i] и alpha[k], которые, как только что объяснили в (1) выше оба "снаружи" равны alpha. Таким образом, все inner.product полно NA.


Редактировать: основываясь на математическом уравнении, которое вы добавили в свой вопрос, и указании на то, что alpha, x и y - все векторы длины n, я считаю, что эта функция будет делать то, что вы хотите:

newfun <- function(x, y, alpha) {
    axy <- alpha*x*y
    sum(alpha) - 0.5*sum(outer(axy, axy, "*"))
}
0 голосов
/ 15 марта 2019

Попробуйте:

set.seed(4997)
options(digits = 4,scipen = -4)
N = 12
sample.data <- gen.sample(n=N)
X.data <- sample.data$x
y.vec <- sample.data$y

    alpha.vector <- matrix(rep(c(-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6),13*N),ncol = 13, nrow = N, byrow = TRUE)
    for(j in 1:N){
      alpha.vector[j,2] <- rnorm(1,5,5)
    }

for(i in 1:N){
  print(obj_fun(X = X.data, y = y.vec, alpha =  alpha.vector[i,]))
}

Проблема здесь:

obj_fun <- function(X,y,alpha){

  N <- length(X) 
  inner.product <- numeric(N)
  for(i in 1:N){
    for(k in 1:N){
      inner.product[k] <- alpha[i]*alpha[k]*
        y[i]*y[k]*(t(as.numeric(X[i]))%*%as.numeric(X[k]))
    }
  }
  L_D <- sum(alpha) - 0.5*sum(inner.product)
  return(L_D)
}

Эта функция работает от 1 до 12, но alpha не имеет элемента 12 или 11!

Кстати: этот циклический способ выполнения вашего кода можно улучшить, используя apply семейство и другие изменения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...