Domanda

Utilizzando kernlab Mi sono allenato un modello con codice come il seguente:

my.model <- ksvm(result ~ f1+f2+f3, data=gold, kernel="vanilladot")

Dal momento che è un modello lineare, preferisco a run-time per calcolare i punteggi come una semplice somma ponderata dei valori di caratteristiche piuttosto che utilizzare il macchinario completo SVM. Come posso convertire il modello a qualcosa di simile (alcuni pesi confezionati qui):

> c(.bias=-2.7, f1=0.35, f2=-0.24, f3=2.31)
.bias    f1    f2    f3 
-2.70  0.35 -0.24  2.31 

dove .bias è il termine distorsione e il resto sono dotate di pesi?

EDIT:

Ecco alcuni dati di esempio.

gold <- structure(list(result = c(-1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), f1 = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1), f2 = c(13.4138113499447, 
13.2216999857095, 12.964145772169, 13.1975227965938, 13.1031520152764, 
13.59351759447, 13.1031520152764, 13.2700658838026, 12.964145772169, 
13.1975227965938, 12.964145772169, 13.59351759447, 13.59351759447, 
13.0897162110721, 13.364151238365, 12.9483051847806, 12.964145772169, 
12.964145772169, 12.964145772169, 12.9483051847806, 13.0937231331592, 
13.5362700880482, 13.3654209223623, 13.4356400945176, 13.59351759447, 
13.2659406408724, 13.4228886221088, 13.5103065354936, 13.5642812689161, 
13.3224757352068, 13.1779418771704, 13.5601730479315, 13.5457299603578, 
13.3729010596517, 13.4823595997866, 13.0965264603473, 13.2710281801434, 
13.4489887206797, 13.5132372154748, 13.5196188787197), f3 = c(0, 
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0)), .Names = c("result", 
"f1", "f2", "f3"), class = "data.frame", row.names = c(NA, 40L
))
È stato utile?

Soluzione

Per ottenere la polarizzazione, basta valutare il modello con una caratteristica vettore di tutti gli zeri. Per ottenere il coefficiente del primo film, valutare il modello con un vettore di funzionalità con un "1" nella prima posizione, e zeri in qualsiasi altro luogo - e quindi sottrarre il bias, che già conoscete. Temo di non so sintassi R, ma concettualmente si desidera qualcosa di simile a questo:

bias = my.model.eval([0, 0, 0])
f1 = my.model.eval([1, 0, 0]) - bias
f2 = my.model.eval([0, 1, 0]) - bias
f3 = my.model.eval([0, 0, 1]) - bias

Per verificare che l'avete fatto correttamente, si può provare qualcosa di simile:

assert(bias + f1 + f2 + f3 == my.model.eval([1, 1, 1]))

Altri suggerimenti

Se non mi sbaglio, penso che tu stai chiedendo come estrarre il W vettore della SVM, dove W è definito come:

W = \sum_i y_i * \alpha_i * example_i

Ugh: non so miglior modo per scrivere le equazioni qui, ma questo solo è la somma del peso * vettori di supporto. Dopo aver calcolato il W, è possibile estrarre il "peso" per la funzione che si desidera.

Supponendo che questo è corretto, si sarebbe:

  1. Prendi gli indici dei vostri dati che sono i vettori di supporto
  2. ottenere il loro peso (alfa)
  3. Calcolare W

kernlab memorizza gli indici support vector ei loro valori in un elenco (in modo che funziona sui problemi multiclasse, troppo), in ogni caso qualsiasi uso di manipolazione lista è solo per ottenere i dati reali (vedrete che la lunghezza del liste restituiti da alpha e alphaindex sono solo 1 solo se si ha un problema di 2 classe, che sto supponendo che fate).

my.model <- ksvm(result ~ f1+f2+f3, data=gold, kernel="vanilladot", type="C-svc")
alpha.idxs <- alphaindex(my.model)[[1]]  # Indices of SVs in original data
alphas <- alpha(my.model)[[1]]
y.sv <- gold$result[alpha.idxs]
# for unscaled data
sv.matrix <- as.matrix(gold[alpha.idxs, c('f1', 'f2', 'f3')])
weight.vector <- (y.sv * alphas) %*% sv.matrix
bias <- b(my.model)

kernlab realtà bilance dei dati prima di fare la sua cosa. È possibile ottenere i (in scala) pesi in questo modo (dove, immagino, il bias dovrebbe essere 0 (?))

weight.vector <- (y.sv * alphas) %*% xmatrix(my.model)[[1]]

Se ho capito la tua domanda, questo dovrebbe ottenere ciò che stai cercando.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top