web-dev-qa-db-fra.com

UseMethod ("prédire"): aucune méthode applicable pour "prévoir" appliquée à un objet de classe "train"

J'ai un modèle (fit), basé sur des informations historiques jusqu'au mois dernier. Maintenant, je voudrais prédire l’utilisation de mon modèle pour le mois en cours. Lorsque j'essaie d'invoquer le code suivant:

predicted <- predict(fit, testData[-$Readmit])

Je reçois l'erreur suivante:

Error in UseMethod("predict") : no applicable method for 'predict'
    applied to an object of class "train"

Remarques:

  1. Le modèle d'ajustement a été créé via la fonction train de caret package, à l'aide de l'algorithme de forêt aléatoire.
  2. predict est une fonction générique qui invoquera la fonction de prédiction spécifique en fonction du premier argument d'entrée. Dans mon cas ce sera: 

    >fit$modelInfo$label

    [1] "Random Forest"

Par conséquent, la méthode de prédiction invoquée sera la suivante: Predict.randomForest . Voir [documentation caret] [3] pour plus d'informations.

Voici le code source récapitulatif pour générer le modèle et l'invoquer: 

# Script-1: create a model:
fit <- train(testData[-$Readmit], testData$Readmit)
saveRDS(fit, modelFileName) # save the fit object into a file

# Script-2: predict
fit <- readRDS(modelFileName) # Load the model (generated previously)
predicted <- predict(fit, testData[-$Readmit])

Note: Le temps d'exécution pour générer le modèle est d'environ 3 heures, c'est pourquoi je sauvegarde l'objet pour qu'il soit réutilisé par la suite.

L'ensemble de données du modèle de formation sous la structure suivante:

> str(fit$trainingData)
'data.frame':   29955 obs. of  27 variables:
$ Acuity                : Factor w/ 3 levels "Elective  ","Emergency ",..: 2 2 2 1 1 2 2 2 1 1 ...
$ AgeGroup              : Factor w/ 10 levels "100-105","65-70",..: 8 6 9 9 5 4 9 2 3 2 ...
$ IsPriority            : int  0 0 0 0 0 0 0 0 0 0 ...
$ QNXTReferToId         : int  115 1703712 115 3690 1948 115 109 512 481 1785596 ...
$ QNXTReferFromId       : int  1740397 1724801 1711465 1704170 1714272 1731911 1535 1712758 1740614 1760252 ...
$ iscasemanagement      : Factor w/ 2 levels "N","Y": 2 1 1 2 2 1 2 1 2 2 ...
$ iseligible            : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 2 2 2 2 ...
$ referralservicecode   : Factor w/ 11 levels "12345","278",..: 1 1 1 9 9 1 1 6 9 9 ...
$ IsHighlight           : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 1 ...
$ admittingdiagnosiscode: num  439 786 785 786 428 ...
$ dischargediagnosiscode: num  439 0 296 786 428 ...
$ RealLengthOfStay      : int  3 1 6 1 2 3 3 7 3 2 ...
$ QNXTPCPId             : int  1740397 1724801 1711465 1704170 1714272 1731911 1535 1712758 1740614 1760252 ...
$ QNXTProgramId         : Factor w/ 3 levels "QMXHPQ0839     ",..: 1 1 1 1 1 1 1 1 1 1 ...
$ physicalzipcode       : int  33054 33712 33010 33809 33010 33013 33142 33030 33161 33055 ...
$ gender                : Factor w/ 2 levels "F","M": 1 1 1 1 2 1 1 2 2 1 ...
$ ethnicitycode         : Factor w/ 4 levels "ETHN0001       ",..: 4 4 4 4 4 4 4 4 4 4 ...
$ dx1                   : num  439 786 296 786 428 ...
$ dx2                   : num  439 292 785 786 428 ...
$ dx3                   : num  402 0 250 0 0 ...
$ svc1                  : int  0 120 120 762 762 120 120 120 762 762 ...
$ svc2                  : int  120 0 0 0 0 0 0 0 0 0 ...
$ svc3                  : int  0 0 0 0 0 0 0 0 0 0 ...
$ Disposition           : Factor w/ 28 levels "0","APPEAL & GRIEVANCE REVIEW                                   ",..: 11 11 16 11 11 11 11 11 11 11 ...
$ AvgIncome             : Factor w/ 10 levels "-1",">100k","0-25k",..: 3 6 3 8 3 4 3 5 4 4 ...
$ CaseManagerNameID     : int  124 1 1 19 20 1 16 1 43 20 ...
$ .outcome              : Factor w/ 2 levels "NO","YES": 1 2 2 1 1 1 2 2 1 1    ...

maintenant la testData aura la structure suivante:

> str(testData[-$Readmit])
'data.frame':   610 obs. of  26 variables:
$ Acuity                : Factor w/ 4 levels "0","Elective  ",..: 3 2 4 2 2 2 4 3 3 3 ...
$ AgeGroup              : Factor w/ 9 levels "100-105","65-70",..: 4 3 5 4 2 9 4 2 4 6 ...
$ IsPriority            : int  0 0 0 0 0 0 1 1 1 1 ...
$ QNXTReferToId         : int  2140 482 1703785 1941 114 1714905 1703785 98 109 109 ...
$ QNXTReferFromId       : int  1791383 1729375 1718532 1746336 1718267 1718267 1718532 98 109 109 ...
$ iscasemanagement      : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 1 2 2 1 ...
$ iseligible            : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 2 2 2 2 ...
$ referralservicecode   : Factor w/ 7 levels "12345","IPMAT          ",..: 5 1 1 1 1 1 1 5 1 5 ...
$ IsHighlight           : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 1 ...
$ admittingdiagnosiscode: num  11440 11317 11420 11317 1361 ...
$ dischargediagnosiscode: num  11440 11317 11420 11317 1361 ...
$ RealLengthOfStay      : int  1 2 4 3 1 1 16 1 1 3 ...
$ QNXTPCPId             : int  3212 1713678 1738430 1713671 1720569 1791640 1725962 1148 1703290 1705009 ...
$ QNXTProgramId         : Factor w/ 2 levels "QMXHPQ0839     ",..: 1 1 1 1 1 1 1 1 1 1 ...
$ physicalzipcode       : int  34744 33175 33844 33178 33010 33010 33897 33126 33127 33125 ...
$ gender                : Factor w/ 2 levels "F","M": 2 1 2 1 2 2 2 1 1 2 ...
$ ethnicitycode         : Factor w/ 1 level "No Ethnicity   ": 1 1 1 1 1 1 1 1 1 1 ...
$ dx1                   : num  11440 11317 11420 11317 1361 ...
$ dx2                   : num  11440 11317 11420 11317 1361 ...
$ dx3                   : num  0 1465 0 11326 0 ...
$ svc1                  : int  52648 27447 50040 27447 55866 55866 51595 0 99221 300616 ...
$ svc2                  : int  76872 120 50391 120 120 38571 120 762 120 0 ...
$ svc3                  : int  762 0 120 0 0 51999 0 0 0 762 ...
$ Disposition           : Factor w/ 14 levels "0","DENIED- Not Medically Necessary                             ",..: 3 5 3 4 3 3 5 3 3 5 ...
$ AvgIncome             : Factor w/ 10 levels "-1",">100k","0-25k",..: 6 7 5 9 3 3 6 4 3 4 ...
$ CaseManagerNameID     : int  1 2 3 4 5 6 7 8 9 7 ...

La structure des variables est la même, à la différence que certaines variables factorielles ont des niveaux différents car certaines variables ont de nouvelles valeurs. Par exemple: Acuity dans le modèle a 3 niveaux et dans les données de test 4 niveaux.

Je n'ai pas d'emblée un moyen de connaître tout le niveau possible pour toutes les variables.

Tout conseil, s'il vous plaît ...

Merci d'avance,

David

8
David Leal

Je pense avoir trouvé la raison pour laquelle cela s'est produit ... La predict est une fonction générique du paquetage: stats. J'utilise la notation d'espace de nom ::- pour appeler les fonctions du package caret (c'est-à-dire la recommandation de créer un package utilisateur) et la fonction predict équivalente du package caret est: predict.train, c'est une fonction interne, qui ne peut pas être invoquée par un application externe. Le seul moyen d'appeler cette fonction consiste à utiliser la fonction générique predict du package stats, puis, en fonction de la classe du premier argument d'entrée: predicted <- predict(fit, testData[-$Readmit]) identifie la fonction predict particulière qui sera invoquée. 

Dans ce cas particulier, la classe de cette fonction est train; elle appelle donc réellement la fonction: train.predict à partir du package caret. Cette fonction gère également la fonction particulière demandée pour la prédiction en fonction de l’algorithme (méthode) utilisé, par exemple: predict.gbm ou predict.glm, etc. Elle est expliquée en détail dans la section caret documentation : "5.7 Extraction de prédictions et Probabilités de classe ".

Par conséquent, la notation ::- fonctionne bien pour les autres fonctions du package, telles que: caret.train par exemple, mais pas pour celle-ci: predict. Dans de tels cas, il est nécessaire de charger explicitement la bibliothèque afin qu’elle puisse appeler en interne la fonction predict.train.

En bref, la solution ajoute simplement la ligne suivante avant d'appeler la fonction predict:

library(caret)

Puis l'erreur disparaît. 

8
David Leal

D'après la réponse de @ David Leal, j'ai essayé de charger library(caret) avant d'appeler la fonction de prédiction, mais cela n'a pas aidé. 

Après avoir essayé un peu, je me suis rendu compte que je devais charger la bibliothèque qui contient le modèle lui-même. Dans mon cas, j'ai dû appeler library(kenlab) pour les vecteurs de support.

0
Nikhil Gupta