2016-04-21 40 views
5

Ecco il codice mi sono imbattutosmooth.spline(): modello adattato non corrisponde gradi specificato dall'utente di libertà

fun <- function(x) {1 + 3*sin(4*pi*x-pi)} 
set.seed(1) 
num.samples <- 1000 
x <- runif(num.samples) 
y <- fun(x) + rnorm(num.samples) * 1.5 
fit <- smooth.spline(x, y, all.knots=TRUE, df=3) 

Nonostante df=3, quando ho controllato il modello adattato, l'uscita era

Call: 
smooth.spline(x = x, y = y, df = 3, all.knots = TRUE) 
Smoothing Parameter spar= 1.499954 lambda= 0.002508571 (26 iterations) 
Equivalent Degrees of Freedom (Df): 9.86422 

Qualcuno potrebbe aiutarmi? Grazie!

+0

Hai considerato la possibilità che i gradi di libertà che fornisci siano un obiettivo che l'algoritmo tenta di ottimizzare verso (tra gli altri criteri) e che è semplicemente il più vicino possibile all'algoritmo? – joran

risposta

4

Nota che da R-3.4.0 (2017-04-21), smooth.spline è possibile accettare la specifica diretta di λ mediante un argomento appena aggiunto lambda. Ma sarà ancora convertito in quello interno spar durante la stima. Quindi la seguente risposta non è influenzata.


Smoothing parametro λ/spar si trova nel centro di controllo levigatezza

scorrevolezza è controllata dal parametro lisciatura λ. smooth.spline() utilizza un parametro smoothing interna spar anziché λ:

spar = s0 + 0.0601 * log(λ) 

Tale logaritmo trasformata è necessaria per fare minimizzazione vincolata, come GCV/CV. L'utente può specificare spar per specificare indirettamente λ. Quando spar cresce in modo lineare, λ crescerà in modo esponenziale. Pertanto, raramente è necessario utilizzare un valore grande spar.

Il grado di libertà df, è definita, in termini di λ:

edf

dove X è la matrice modello con base B-spline e S è la matrice penalità.

Si può avere un controllo sulle loro relazioni con il set di dati: abbozzo

spar <- seq(1, 2.5, by = 0.1) 
a <- sapply(spar, function (spar_i) unlist(smooth.spline(x, y, all.knots=TRUE, spar = spar_i)[c("df","lambda")])) 

Let df ~ spar, λ ~ spar e log(λ) ~ spar:

par(mfrow = c(1,3)) 
plot(spar, a[1, ], type = "b", main = "df ~ spar", 
    xlab = "spar", ylab = "df") 
plot(spar, a[2, ], type = "b", main = "lambda ~ spar", 
    xlab = "spar", ylab = "lambda") 
plot(spar, log(a[2,]), type = "b", main = "log(lambda) ~ spar", 
    xlab = "spar", ylab = "log(lambda)") 

plot

nota la crescita radicale λ con spar, la relazione lineare tra log(λ) e spar e la relazione relativamente liscia tra df e spar.


smooth.spline() iterazioni montaggio per spar

Se specifichiamo manualmente il valore di spar, come quello che abbiamo fatto nel sapply(), non iterazioni di montaggio è fatto per la selezione spar; altrimenti il ​​numero smooth.spline() necessita di iterare attraverso un numero di valori spar. Se abbiamo

  • specificare cv = TRUE/FALSE, le iterazioni di montaggio hanno lo scopo di minimizzare il punteggio CV/GCV;
  • specificare df = mydf, le iterazioni di montaggio hanno lo scopo di minimizzare (df(spar) - mydf)^2.

Ridurre a icona GCV è facile da seguire. Non ci interessa il punteggio GCV, ma ci interessa il corrispondente spar. Al contrario, quando si minimizza lo (df(spar) - mydf)^2, spesso ci preoccupiamo del valore df al termine dell'iterazione piuttosto che dello spar! Ma tenendo presente che questo è un problema di minimizzazione, non ci è mai garantito che l'ultimo df corrisponda al nostro valore target mydf.


Perché mettere df = 3, ma ottenere df = 9.864?

La fine di iterazione, potrebbe o implica colpire un minimo, o raggiungere la ricerca di confine, o raggiungendo il numero massimo di iterazioni.

Siamo lontani dal limite massimo di iterazioni (predefinito 500); eppure non raggiungiamo il minimo. Bene, potremmo raggiungere il confine.

Non concentrarsi su df, pensare a spar.

smooth.spline(x, y, all.knots=TRUE, df=3)$spar # 1.4999 

Secondo ?smooth.spline, per impostazione predefinita, smooth.spline() ricerche spar tra [-1.5, 1.5]. Ad esempio, quando si inserisce df = 3, la minimizzazione termina al limite della ricerca, invece di battere df = 3.

Dai un'occhiata al nostro grafico della relazione tra df e spar, ancora. Dalla figura, sembra che abbiamo bisogno di qualche valore spar vicino a 2 per ottenere df = 3. uso control.spar argomento

Let:

fit <- smooth.spline(x, y, all.knots=TRUE, df=3, control.spar = list(high = 2.5)) 
# Smoothing Parameter spar= 1.859066 lambda= 0.9855336 (14 iterations) 
# Equivalent Degrees of Freedom (Df): 3.000305 

Ora si vede, si finisce con df = 3. E abbiamo bisogno di un spar = 1.86.


un suggerimento migliore: Non usare all.knots = TRUE

sguardo, si dispone di dati 1000. Con all.knots = TRUE userai 1000 parametri.Desiderare finire con df = 3 implica che 997 di 1000 parametri sono soppressi. Immagina quanto è grande un di cui hai bisogno!

Provare a utilizzare la spline di regressione penalizzata. Soppressione 200 parametri per 3 è sicuramente molto più facile:

fit <- smooth.spline(x, y, nknots = 200, df=3) ## using 200 knots 
# Smoothing Parameter spar= 1.317883 lambda= 0.9853648 (16 iterations) 
# Equivalent Degrees of Freedom (Df): 3.000386 

Ora, si finisce con df = 3 senza spar controllo.