Pergunta

Estou tentando usar o kernlab R pacote de fazer Máquinas de Vetor de Suporte (SVM).Para o meu exemplo muito simples, eu tenho dois pedaços de dados de treinamento.A e B.

(A e B são do tipo matrix - eles são matrizes de adjacência para gráficos.)

Então eu escrevi uma função que leva+B e gera um kernel matriz.

> km
         [,1]     [,2]
[1,] 14.33333 18.47368
[2,] 18.47368 38.96053

Agora eu uso kernlab's ksvm função para gerar o meu modelo de previsão.Agora, eu estou apenas tentando obter a droga de coisa para funcionar - não estou preocupado com a formação de erro, etc.

Assim, Questão 1:Eu estou gerando o meu modelo corretamente?Razoavelmente?

# y are my classes. In this case, A is in class "1" and B is in class "-1"
> y
[1]  1 -1

> model2 =  ksvm(km, y, type="C-svc", kernel = "matrix");
> model2
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

[1] " Kernel matrix used as input."

Number of Support Vectors : 2 

Objective Function Value : -0.1224 
Training error : 0 

Tão longe, tão bom.Nós criamos nossos kernel personalizado matriz e, em seguida, criamos um ksvm modelo utilizando essa matriz.Temos nossos dados de treinamento rotuladas como "1" e "-1".

Agora prever:

> A
     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    1    0    1
[3,]    0    0    0

> predict(model2, A)
Error in as.matrix(Z) : object 'Z' not found

Uh-oh.Esta tudo bem.Tipo do esperado, realmente."Prever" quer algum tipo de vetor, não de uma matriz.

Então vamos experimentar algumas coisas:

> predict(model2, c(1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, km)
Error in as.matrix(Z) : object 'Z' not found

Alguns dos testes acima são absurdas, mas que é o meu ponto:não importa o que eu faça, eu só não consigo prever() olhar para os meus dados e fazer uma previsão.Escalares não funcionam, vetores não funcionam.Uma matriz 2x2 não funciona, nem uma matriz 3x3.

O que estou fazendo de errado aqui?

(Uma vez eu descobrir o que ksvm quer, então eu posso garantir que os meus dados de teste pode estar de acordo com esse formato normal/razoável/matemática de maneira saudável.)

Foi útil?

Solução

Se você pensar sobre como a máquina de vetor de suporte pode "usar" o kernel matriz, você verá que você não pode realmente fazer isso da maneira que você está tentando (como você viu :-)

Eu realmente lutou um pouco com isso quando eu estava usando kernlab + um kernel matriz ...coincidentemente, foi também para o gráfico de miolo!

De qualquer maneira, vamos perceber que, desde o SVM não sabe como calcular a sua função de kernel, ele precisa ter esses valores já calculados entre o novo (de testes) exemplos, e os exemplos que ele escolhe como o suporte a vetores durante a etapa de formação.

Assim, será necessário calcular a matriz kernel para todos de seus exemplos juntos.Você pode treinar em alguns teste e sobre os outros, removendo linhas + colunas da matriz kernel quando apropriado.Deixe-me mostrar a você com o código.

Podemos usar o código de exemplo na ksvm documentação para carregar nosso espaço de trabalho com alguns dados:

library(kernlab)
example(ksvm)

Você vai precisar acertar o retorno de alguns (2) vezes para que as parcelas de desenhar, e deixar o exemplo de terminar, mas agora você deve ter um kernel matriz em seu espaço de trabalho chamado K.Nós vamos precisar para recuperar o y vetor que ele deve usar para seus rótulos (como tem sido pisoteada por outros de código no exemplo):

y <- matrix(c(rep(1,60),rep(-1,60)))

Agora, escolher um subconjunto de exemplos para usar para testar

holdout <- sample(1:ncol(K), 10)

A partir deste momento, eu estou indo para:

  1. Crie uma formação de kernel chamado de matriz trainK a partir do original K kernel matriz.
  2. Criar uma SVM modelo do meu conjunto de treinamento trainK
  3. Utilize o suporte de vetores encontrados a partir de modelo para criar um teste de kernel matriz testK ...esta é a parte estranha.Se você observar o código kernlab para ver como ele usa o vetor de suporte índices, você vai ver porque ele está sendo feito desta forma.É possível fazer isso de outra forma, mas eu não vejo qualquer documentação/exemplos previsão com um kernel matriz, então eu estou fazendo isso "a hard way" aqui.
  4. Use o SVM para prever sobre estes recursos e a precisão dos relatórios

Aqui está o código:

trainK <- as.kernelMatrix(K[-holdout,-holdout])  # 1
m <- ksvm(trainK, y[-holdout], kernel='matrix')  # 2
testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F]) # 3
preds <- predict(m, testK)  # 4
sum(sign(preds) == sign(y[holdout])) / length(holdout) # == 1 (perfect!)

Que deve apenas cerca de fazê-lo.Boa sorte!

As respostas ao comentário abaixo

o que K[-reduto,-reduto] significa?(o que faz o "-" significa?)

Imagine que você tem um vetor x, e você deseja recuperar os elementos 1, 3 e 5, a partir dele, você faria:

x.sub <- x[c(1,3,5)]

Se você deseja obter tudo de x exceto elementos 1, 3, e 5, você faria:

x.sub <- x[-c(1,3,5)]

Então, K[-holdout,-holdout] retorna todas as linhas e colunas de K exceto para as linhas que queremos para o apoiava.

Quais são os argumentos de seu como.kernelMatrix - especialmente a [,SVindex(m),drop=F] argumento (o que é particularmente estranho porque parece que todo o suporte é uma matriz índice de K?)

Sim, eu embutidos dois comandos em uma só:

testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F])

Agora que você já treinou o modelo, que você deseja dar a ele um novo kernel matriz com os testes exemplos. K[holdout,] dar-lhe-ia apenas as linhas que correspondem aos exemplos de treinamento em K, e todas as colunas de K.

SVindex(m) dá-lhe os índices de seu apoio vetores a partir de sua original matriz de treinamento-lembre-se, as linhas/colunas têm holdout removido.Assim, para aqueles índices de coluna para ser o correto (ie.referência correta sv coluna), eu preciso primeiro remover o holdout as colunas.

De qualquer maneira, talvez este seja mais claro:

testK <- K[holdout, -holdout]
testK <- testK[,SVindex(m), drop=FALSE]

Agora testK só tem as linhas de nossa exemplos de testes e as colunas que correspondem aos vetores de suporte. testK[1,1] vai ter o valor da função de kernel calculado entre o primeiro teste de exemplo, e o primeiro vetor de suporte. testK[1,2] terá a função de kernel valor entre o seu 1º teste de exemplo e o segundo vetor de suporte, etc.

Atualização (2014-01-30) para responder o comentário de @wrahool

Tem sido um tempo desde que eu já joguei esse, então, os elementos de kernlab::ksvm são um pouco enferrujado, mas, em princípio, esta deve ser correcta :-) ...aqui vai:

qual é o ponto de testK <- K[holdout, -holdout] - não tem de remover as colunas que correspondem ao conjunto de teste?

Sim.A resposta curta é que, se você quiser predict usando um kernel matriz, você terá que fornecer uma matriz de dimensão rows por support vectors.Para cada linha da matriz (o novo exemplo que você deseja prever em) os valores das colunas são simplesmente o valor do kernel matriz avaliada entre esse exemplo e o de vetor de suporte.

A chamada para SVindex(m) retorna o índice do suporte de vetores dado na dimensão do original os dados de treinamento.

Então, primeiro fazendo testK <- K[holdout, -holdout] dá-me um testK matriz com as linhas dos exemplos que deseja prever, e as colunas são da mesma exemplos (dimensão), o modelo foi treinado na.

Eu ainda subconjunto de colunas de testK por SVindex(m) apenas a dar-me as colunas que (agora) corresponde às minhas vetores de suporte.Se eu não tivesse feito o primeiro [, -holdout] seleção, os índices devolvidos por SVindex(m) pode não corresponder à direita exemplos (a menos que todos os N do teste exemplos são o último N colunas da matriz).

Também, que faz exatamente o drop = condição FALSA fazer?

É um pouco defensivo codificação para assegurar que, após a operação de indexação é executada, o objeto retornado é do mesmo tipo que o objeto que foi indexado.

Em R, se o índice é apenas uma dimensão de um 2D (ou superior(?)) objeto, você é retornado um objeto de dimensão inferior.Eu não quero passar um numeric vetor em predict porque ele quer ter um matrix

Por exemplo,

x <- matrix(rnorm(50), nrow=10)

class(x)
[1] "matrix"

dim(x)
[1] 10  5

y <- x[, 1]

class(y)
[1] "numeric"

dim(y)
NULL

O mesmo vai acontecer com data.frames, etc.

Outras dicas

Primeiro, eu não usei Kernlab Muito de. Mas simplesmente olhando para os documentos, vejo exemplos de trabalho para o predict.ksvm() método. Copiar e colar e omitir as impressões para a tela:

 ## example using the promotergene data set
 data(promotergene)

 ## create test and training set
 ind <- sample(1:dim(promotergene)[1],20)
 genetrain <- promotergene[-ind, ]
 genetest <- promotergene[ind, ]

 ## train a support vector machine
 gene <-  ksvm(Class~.,data=genetrain,kernel="rbfdot",\
               kpar=list(sigma=0.015),C=70,cross=4,prob.model=TRUE)

 ## predict gene type probabilities on the test set
 genetype <- predict(gene,genetest,type="probabilities")

Isso parece bastante direto: use amostragem aleatória para gerar um conjunto de treinamento genetrain e seu complemento genetest, depois se encaixar via ksvm E uma chamada para um predict() método usando o ajuste e novos dados em um formato correspondente. Isso é muito padrão.

Você pode encontrar o Caret Pacote de Max Kuhn útil. Ele fornece uma estrutura geral de avaliação e teste para uma variedade de métodos e pacotes de regressão, classificação e aprendizado de máquina, incluindo Kernlab, e contém várias vinhetas mais um Papel JSS.

Steve Lianoglou está certo.

No Kernlab, é um pouco conectado e, ao prever, requer a matriz do kernel de entrada entre cada exemplo de teste e os vetores de suporte. Você precisa encontrar essa matriz.

Por exemplo, uma matriz de teste [NXM], onde n é o número de amostras de teste e M é o número de vetores de suporte no modelo aprendido (ordenado na sequência de Svindex (Modelo)).

Código de exemplo

trmat <- as.kernelMatrix(kernels[trainidx,trainidx])
tsmat <- as.kernelMatrix(kernels[testidx,trainidx])

#training
model = ksvm(x=trmat, y=trlabels, type = "C-svc", C = 1)

#testing
thistsmat = as.kernelMatrix(tsmat[,SVindex(model)])
tsprediction = predict(model, thistsmat, type = "decision")

Kernels é a matriz do kernel de entrada. TrainIDX e TestIDX são IDs para treinamento e teste.

Construa os rótulos a partir dos elementos da solução. Use este método preditor alternativo que leva o modelo KSVM (M) e os dados no formato de treinamento original (D)

predict.alt <- function(m, d){
  sign(d[, m@SVindex] %*% m@coef[[1]] - m@b)
}

K é a kernelMatrix para treinamento. Pelo bem da validação, se você correr predict.alt Nos dados de treinamento, você notará que o método preditor alternativo alterna os valores juntamente com os valores ajustados retornados pelo KSVM. O preditor nativo se comporta de uma maneira inesperada:

aux <- data.frame(fit=kout@fitted, native=predict(kout, K), alt=predict.alt(m=kout, d=as.matrix(K))) 
sample_n(aux, 10)
    fit  native alt
1     0       0  -1
100   1       0   1
218   1       0   1
200   1       0   1
182   1       0   1
87    0       0  -1
183   1       0   1
174   1       0   1
94    1       0   1
165   1       0   1
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top