2017-10-17 6 views
1

J'essaie d'utiliser le fournisseur de type R pour ajuster et prédire un modèle de machines vectorielles de support. J'ai été capable d'ajuster le modèle mais quand j'essaie de prédire le vecteur retourné a la même longueur que le vecteur d'entraînement, ce qu'il ne devrait pas avoir.Pourquoi R.predict.svm renvoie une liste de la mauvaise taille?

J'ai essayé le code équivalent directement dans R et la liste retournée a la bonne longueur.

Pourquoi cela se produit-il?

Voici un exemple:

open System 
open RDotNet 
open RProvider 
open RProvider.stats 
open RProvider.e1071 

// Random number generator 
let rng = Random() 
let rand() = rng.NextDouble() 

// Generate fake X1 and X2 
let X1s = [ for i in 0 .. 9 -> 10. * rand() ] // length = 10 
let X2s = [ for i in 0 .. 9 -> 5. * rand() ] // length = 10 

let Z1s = [ for i in 0 .. 5 -> 10. * rand() ] // length = 6 
let Z2s = [ for i in 0 .. 5 -> 5. * rand() ] // length = 6 

// Build Ys 
let Ys = [0;1;0;1;0;1;0;1;0;1] 

let XMat = 
    ["X1", box X1s; "X2", box X2s] 
    |> namedParams 
    |> R.cbind 

let ZMat = 
    ["Z1", box Z1s; "Z2", box Z2s] 
    |> namedParams 
    |> R.cbind 

let svm_model = 
    ["x", box XMat; "y", box Ys ; "type", box "C"; "gamma", box 1.0] 
    |> namedParams 
    |> R.svm 

let svm_predict = R.predict(svm_model, ZMat) 

let res = 
    if svm_predict.Type = RDotNet.Internals.SymbolicExpressionType.IntegerVector then 
     svm_predict.AsInteger() 
     |> List.ofSeq 
    else failwithf "Expecting a Numeric but got a %A" svm_predict.Type 

printfn "The predicted values are: %A" res 
// The predicted values are: [1; 2; 1; 2; 1; 2; 1; 1; 1; 2] 

Et voici le code de R d'origine:

library(stats) 
library(e1071) 

// Random number generator 
x1 <- 10 * rnorm(10) 
x2 <- 5 * rnorm(10) 
x = cbind(x1, x2) 

z1 <- 10 * rnorm(5) 
z2 <- 5 * rnorm(5) 
z = cbind(z1, z2) 

zs <- c(0,1,0,1,0,1,0,1,0,1) 

svm_fit = svm(x=x,y=zs,type="C",gamma=1.0) 
svm_pred = predict(svm_fit, z) 

print(svm_pred) 
1 2 3 4 5 
1 0 1 1 1 
Levels: 0 1 
+3

À quoi ressemble votre code R d'origine? –

+0

J'ai ajouté le code R. Merci d'avoir regardé ça. – Soldalma

+0

J'ai trouvé que le second argument dans 'let svm_predict = R.predict (svm_model, ZMat)' est sans importance. Peu importe ce que j'entre, le résultat est le même. Même si j'omets l'argument. – Soldalma

Répondre

2

Je soupçonne que la question pourrait être passer des paramètres à la fonction R.predict. Je ne suis pas un expert sur SVM, donc je ne suis pas sûr quel est le résultat cela devrait donner, mais quand je l'appelle comme suit, j'obtenir des résultats similaires à votre version R:

let svm_predict = 
    namedParams ["object", box svm_model; "newdata", box ZMat ] 
    |> R.predict 

Je pense que ce qui est Le fournisseur de type R déduit des informations sur les noms de paramètres de la fonction predict, mais il n'est pas capable de comprendre exactement ce que le second paramètre est - et donc plutôt que de le fournir comme newdata, il le fournit comme autre chose.

+0

Des millions de mercis! J'étais coincé. J'avais effectivement essayé de faire quelque chose de similaire mais je n'avais pas placé 'box' avant' svm_model'. Je supposais que puisque 'svm_model' est de type' SymbolicExpression' boxe ce n'était pas nécessaire. A la réflexion, il est clair que tous les tuples passés à 'namedParams' doivent avoir le même type, à savoir' string * obj'. – Soldalma