2013-06-12 17 views
6

Mam szerokości i długości, więc muszę przedefiniować jądro RBF w exp (-1/2 || sophere distrance ||^2), co oznacza, że ​​muszę przepisać samą funkcję jądra. piszę jądra następująco:Jak dostosować funkcję jądra w ksvm pakietu 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" 

testowałem funkcji, jądro powinno być prawidłowe. Ale za pomocą następującego polecenia szkolenia otrzymuję błąd:

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. 

Bardziej trickly rzeczą jest, próbowałem przykładowego kodu w dokumencie ksvm:

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

ale otrzymuję ten sam błąd.

Ktoś wie, jak poprawnie zdefiniować funkcję jądra?

+0

Jest to bardzo pomocne. Czy możesz wyjaśnić, jak wyprowadziłeś funkcję jądra? Nie widzę związku pomiędzy exp (-1/2 || distnace kuli ||^2) i jak wypełniasz 'res'. – momeara

+0

@momeara, myślę, że jest on w zasadzie oparty na funkcjach trójkąta, więc może być wiele sposobów na to, używając arctan, arcsin lub tutaj, jak atan2. Sprawdź ten link: http://www.movable-type.co.uk/scripts/latlong.html –

+0

Ten przykład działa dla mnie. –

Odpowiedz

6

Mój problem został rozwiązany w następujący sposób: kody jądra są poprawne, powinienem bezpośrednio zdefiniować funkcję (x, y) i zadeklarować jej klasę jako "jądro". Problem występuje nawet w dokumencie, w którym ksvm obsługuje style x, y, w rzeczywistości nie działają. Zmieniając go do stylu Formuły danych może w końcu dostać wszystko działa:

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

Ponadto, czytałem też kod źródłowy rbfdot i inne ziarna zdefiniowane w samej kernlab. Kody zauważy ich styl jest tak:

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

ale poważnie, próbowałem, i uczynienie funkcje jądra w tym stylu nie będzie działać. Sposób działania jest podobny do tego stylu:

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