2013-06-12 11 views
6

Ho latitudini e longitudini, quindi ho bisogno di ridefinire il kernel RBF in exp (-1/2 || sophere distrance ||^2), il che significa che ho bisogno di riscrivere una funzione del kernel da solo. scrivo il mio kernel come segue:Come personalizzare una funzione del kernel in ksvm del pacchetto kernlab?

round.kernel <- function(x,y){ 
    sigma <- 1 
    #R <- 6371 
    R <- 1 
    a <- (sin((x[1]-y[1])/2))^2+cos(x[1])*cos(y[1])*(sin((x[2]-y[2])/2))^2 
    c <- 2*atan2(sqrt(a),sqrt(1-a)) 
    d <- R*c 
    res <- exp(-d^2/(2*sigma)) 
    return (res) 
} 
class(round.kernel) <- "kernel" 

ho provato la funzione, il kernel dovrebbe essere corretto. Ma con il comando seguente formazione sto ottenendo l'errore:

fit <- ksvm(y=train[,2],x=train[,3:4],kernel=round.kernel,type='eps-svr') 

Error in .local(x, ...) : 
    List interface supports only the stringdot kernel. 

La cosa più trickly è, ho provato il codice di esempio nel documento ksvm:

k <- function(x,y) {(sum(x*y) +1)*exp(-0.001*sum((x-y)^2))} 
class(k) <- "kernel" 

Ma io sono sempre lo stesso errore.

Qualcuno sa come definire correttamente una funzione del kernel?

+0

Questo è veramente utile. Puoi spiegare come hai derivato la funzione del kernel? Non vedo la connessione tra exp (-1/2 || distnace sfera ||^2) e come si completa 'res'. – momeara

+0

@momeara, penso che sia fondamentalmente basato su funzioni triangolari, quindi ci possono essere diversi modi per farlo usando arctan, arcsin, o qui come atan2. Controlla questo link: http://www.movable-type.co.uk/scripts/latlong.html –

+0

L'esempio funziona per me. –

risposta

6

Il mio problema è risolto come segue: i codici del kernel sono corretti, dovrei definire direttamente una funzione (x, y) e dichiarare la sua classe come "kernel". Il problema è anche nel doc ksvm supporta gli stili x, y, in realtà non funzionano. La modifica alla formula stile-dati può finalmente ottenere le cose in esecuzione:

fit <- ksvm(Freq~lat+lon,data=train[,2:4],kernel=roundrbf,type='eps-svr') 

Inoltre, ho anche letto il codice sorgente di rbfdot, e altri kernel definiti nel kernlab stesso. Si noti il ​​loro stile codici è come questo:

function(params){ 
    val <- function(x,y){ 
    # True kernel defined here 
    } 
    return (new ("kernel_name",.Data=val,kpar=list(params))) 
} 

Ma seriamente, ho provato, e rendendo le funzioni del kernel in questo stile non funzionerà. Il modo di lavorare è come questo stile direttamente:

k <- function(x,y){ 
    #calculate the result 
} 
class(k) <- "kernel" 
Problemi correlati