2016-04-25 10 views
5

У меня есть функция ядра следующим образом:Как экстраполировать за пределы x точек, переданных в `ksmooth`?

x <- 1:100 
y <- rnorm(100, mean=(x/2000)^2) 
plot(x,y) 
kernel <- ksmooth(x,y, kernel="normal", bandwidth=10) 
print(kernel$y) 

Если я пытаюсь предсказать в точке за пределами диапазона значений х, это даст мне NaN, потому что он пытается экстраполировать за пределы данных:

x <- 1:100 
y <- rnorm(100, mean=(x/2000)^2) 
plot(x,y) 
kernel <- ksmooth(x,y, kernel="normal", bandwidth=10, x.points=c(130)) 
print(kernel$y) 

> print(kernel$y) 
[1] NA 

Даже когда я изменяю range.x не сдвинуться с места:

x <- 1:100 
y <- rnorm(100, mean=(x/2000)^2) 
plot(x,y) 
kernel <- ksmooth(x,y, kernel="normal", bandwidth=10, range.x=c(1,200) , x.points=c(130)) 
print(kernel$y) 

> print(kernel$y) 
[1] NA 

Как получить ksmooth функция экстраполировать за пределы данных? Я знаю, что это плохая идея в теории, но на практике эта проблема возникает постоянно.

+0

Я полагаю, что вопрос стороны: * Что делает 'range.x'? * В документации, по-видимому, указывается, что это« диапазон точки, которые должны быть охвачены на выходе ». Но, похоже, это не влияет на результат здесь? – Hunle

+1

Вместо этого вы решили использовать bkde2D {KernSmooth}. По умолчанию это экстраполирует ширину полосы в 1,5 раза в каждом направлении. Экстраполируйте еще на свой страх и убедитесь, что вы понимаете, что вы делаете, и это ограничения. Если вам действительно нужно экстраполировать, то, возможно, вам стоит подумать о том, чтобы подгонять данные к модели, которая имеет некоторое отношение к реальности и формирует более разумную основу для экстраполяции. – dww

+0

Я попробую. Проблема в том, что действительно сложно выполнить какую-либо кросс-валидность k-folds, когда нет экстраполяции, потому что в любое время, когда я раскалываю k-й склад в поезд и тест, некоторые из тестовых примеров неизбежно выходят за пределы диапазона примеры обучения. Я единственный, кто разочарован этим? – Hunle

ответ

2

Чтобы ответить на ваш вопрос, смотрите код ksmooth, range.x используется только в том случае, если x.points не предоставляется, чтобы объяснить, почему вы его не видите. Давайте посмотрим на код в ksmooth:

function (x, y, kernel = c("box", "normal"), bandwidth = 0.5, 
    range.x = range(x), n.points = max(100L, length(x)), x.points) 
{ 
    if (missing(y) || is.null(y)) 
     stop("numeric y must be supplied.\nFor density estimation use density()") 
    kernel <- match.arg(kernel) 
    krn <- switch(kernel, box = 1L, normal = 2L) 
    x.points <- if (missing(x.points)) 
     seq.int(range.x[1L], range.x[2L], length.out = n.points) 
    else { 
     n.points <- length(x.points) 
     sort(x.points) 
    } 
    ord <- order(x) 
    .Call(C_ksmooth, x[ord], y[ord], x.points, krn, bandwidth) 
} 

Из этого мы видим, что нам нужно, чтобы не обеспечить x.points, чтобы убедиться, что range.x используется. Если вы запустите:

x <- 1:100 
y <- rnorm(100, mean=(x/2000)^2) 
plot(x,y) 
kernel <- ksmooth(x,y, kernel="normal", bandwidth=10, range.x=c(1,200)) 
plot(kernel$x, kernel$y) 

Теперь вы увидите, что ваше ядро ​​оценивается выше 100 (хотя и не до 200). Увеличение параметра полосы пропускания позволяет вам еще больше удалиться от 100.