Fonction predict()

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Fonction predict()

Messagepar Maxime Deniaux » 12 Nov 2022, 10:39

Bonjour,

je tente ma chance ici car je n'ai pas su trouver de réponse ailleurs.
Mon problème concerne les valeurs sorties par la fonction predict() qui diffèrent selon la dimension du nouveau dataset utilisé pour faire ces prédictions. J'aurais aimé savoir si quelqu'un avait déjà rencontré le même problème car par le passé je n'avais jamais eu l'impression de l'avoir déjà eu.

Pour le contexte : j'utilise une random forest pour prédire le résultat d'un match de foot ("H" = Home, "D" = Draw, "A" = Away). Jusqu'ici pas de problème observé. Mais quand je tente de faire les prédictions pour de nouveaux matchs (non utilisés dans la formation du modèle random forest), j'obtiens des résultats différents selon le nombre de matchs que je cherche à prédire.

Par exemple, si on regarde plus attentivement certains matchs (disons 10) et que j'utilise la fonction, soit avec seulement ces 10 matchs, soit en ajoutant le reste du jeu 'test' (environ 500 matchs), les résultats sont les suivants :

Seulement les 10 matchs ( predict(modele_RF, 10_matchs, type = 'prob') ) :

............A..........D........H
1 ...... 0.427 ... 0.344 ... 0.229
2 ...... 0.442 ... 0.358 ... 0.200
3 ...... 0.468 ... 0.340 ... 0.192
4 ...... 0.438 ... 0.363 ... 0.199
5 ...... 0.444 ... 0.347 ... 0.209
6 ...... 0.454 ... 0.354 ... 0.192
7 ...... 0.398 ... 0.350 ... 0.252
8 ...... 0.436 ... 0.353 ... 0.211
9 ...... 0.462 ... 0.343 ... 0.195
10 ..... 0.406 ... 0.349 ... 0.245


Les 10 mêmes matchs mais avec le reste du jeu de données 'test' ( predict(modele_RF, 10_matchs_plus_jeu_test, type = 'prob') ) :

............A..........D........H
1 ...... 0.322 ... 0.331 ... 0.347
2 ...... 0.422 ... 0.341 ... 0.237
3 ...... 0.461 ... 0.284 ... 0.255
4 ...... 0.304 ... 0.320 ... 0.376
5 ...... 0.468 ... 0.398 ... 0.134
6 ...... 0.427 ... 0.342 ... 0.231
7 ...... 0.527 ... 0.356 ... 0.117
8 ...... 0.476 ... 0.388 ... 0.136
9 ...... 0.576 ... 0.311 ... 0.113
10 ..... 0.358 ... 0.355 ... 0.287


Comment se fait-il que les résultats puissent changer pour ces matchs ? (je dis ces matchs mais ça aurait pu être d'autres matchs du jeu de données test). Comment la taille du nouveau dataset peut venir interférer dans les résultats ?

De plus, si j'utilise la fonction pour les matchs un à un :

predict match 1
predict match 2
predict match 3
...

cela me renvoie exactement la même chose à chaque fois.

Voilà. C'est difficile pour moi de donner un exemple reproductible, ma table a été construite via pas mal de manipulations.
Le code est bien trop grand pour être mis ici.

En espèrant que vous puissiez m'aider.


Je vous remercie. Bonne journée.

Maxime

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Fonction predict()

Messagepar Facundo Muñoz » 12 Nov 2022, 15:00

Bonjour Maxime,

Je comprends la question, mais à priori je n'ai pas de réponse. Quelques pistes :

1. D'abord, la fonction predict() est "générique". C'est à dire que elle se comporte différemment en fonction de la classe de l'objet "modele_RF". Il faudrait lire la documentation de cette méthode pour bien comprendre comment elle fonctionne.

2. Ce serait un bon exercice d'essayer de faire un exemple réproductible minimale avec des données bidon, pour voir si on peut reproduire ce comportement. On identifie souvent la source des problèmes juste en essayant de les reproduire dans un autre contexte, de zéro. De plus, si vous avez un exemple reproductible, on pourra vous aider plus facilement.

Cordialement,
ƒacu.-

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 12 Nov 2022, 15:54

Facundo Muñoz a écrit :Bonjour Maxime,

Je comprends la question, mais à priori je n'ai pas de réponse. Quelques pistes :

1. D'abord, la fonction predict() est "générique". C'est à dire que elle se comporte différemment en fonction de la classe de l'objet "modele_RF". Il faudrait lire la documentation de cette méthode pour bien comprendre comment elle fonctionne.

2. Ce serait un bon exercice d'essayer de faire un exemple réproductible minimale avec des données bidon, pour voir si on peut reproduire ce comportement. On identifie souvent la source des problèmes juste en essayant de les reproduire dans un autre contexte, de zéro. De plus, si vous avez un exemple reproductible, on pourra vous aider plus facilement.

Cordialement,



Bonjour !

merci pour votre réponse. Oui vous avez raison sur le fait de donner un exemple, même plus petit et "bidon". Alors en voici un qui est pour le coup bien "bidon" du point de vue des données car elles sont fausses :


Code : Tout sélectionner


# Les equipes pour former le dataset :

HomeTeam = c("Monaco","Marseille","PSG","Lille","Lyon","Rennes")
AwayTeam  = c("Strasbourg","Reims","Troyes","Brest","Lorient","Nice")


# Tirages au sort successifs :

dataset = data.frame(HomeTeam   = sample(HomeTeam,500,replace = T),
             AwayTeam    = sample(AwayTeam,500,replace = T),
             Home_Odd   = sample(seq(1,1.5,0.05),500,replace = T),
             Away_Odd    = sample(seq(2,5,0.05),500,replace = T),
             Draw_Odd    = sample(seq(2.8,10,0.05),500,replace = T),
             FTR              = sample(c("H","D","A"),500,replace = T)
            )


# Variable a prédire, à mettre en facteur sinon random forest ne fonctionne pas  :

dataset$FTR = factor(dataset$FTR)


# Random forest :

RF <- randomForest::randomForest(FTR ~ .,
                                                     data            = dataset ,
                       importance  = TRUE,
                       na.action     = na.omit,
                       ntree           = 500)


# Les nouvelles données pour faire des predictions :

new_data = data.frame(HomeTeam    =  sample(HomeTeam,50,replace = T),
                AwayTeam     = sample(AwayTeam,50,replace = T),
                Home_Odd    = sample(seq(1,1.5,0.05),50,replace = T),
                Away_Odd     = sample(seq(2,5,0.05),50,replace = T),
                Draw_Odd     = sample(seq(2.8,10,0.05),50,replace = T)
                )


# Predictions :
# 1) sur toutes les lignes de new_data avec affichage des 10 premières
# 2) sur les 10 premières lignes de new_data :

predict(RF, new_data, type = 'prob')[1:10,]
predict(RF, new_data[1:10,], type = 'prob')

predict(RF, new_data)[1:10]
predict(RF, new_data[1:10,])


De mon côté, même avec cet exemple ci-dessus, je continue à avoir le même problème qu'expliqué auparavant.
J'avais déjà lu la documentation de la fonction avant de venir ici mais je n'ai pas su trouver d'informations pouvant expliquer ce problème. Mais peut-être suis-je passé à côté de l'information justement...je vais essayer de la lire de nouveau.

Bonne fin de journée.

Maxime

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Fonction predict()

Messagepar Facundo Muñoz » 12 Nov 2022, 20:42

Rebonjour,

Bon, déjà, je peux reproduire le comportement (c.f. ci-dessous). Donc, il semble pas une erreur.

Je ne suis pas trop familier avec les Random Forests, mais la seule explication que je trouve est que les points de branchement du modèle soient pas fixes mais relatifs aux données à prédire (e.g. brancher sur la mediane d'une variable). Je ne sais pas si ç'a trop du sens, mais ça expliquerait ce phénomène.

Code : Tout sélectionner


# Les equipes pour former le dataset :
HomeTeam = c("Monaco","Marseille","PSG","Lille","Lyon","Rennes")
AwayTeam  = c("Strasbourg","Reims","Troyes","Brest","Lorient","Nice")

# Tirages au sort successifs :
dataset = data.frame(
  HomeTeam   = sample(HomeTeam,500,replace = T),
  AwayTeam    = sample(AwayTeam,500,replace = T),
  Home_Odd   = sample(seq(1,1.5,0.05),500,replace = T),
  Away_Odd    = sample(seq(2,5,0.05),500,replace = T),
  Draw_Odd    = sample(seq(2.8,10,0.05),500,replace = T),
  FTR              = sample(c("H","D","A"),500,replace = T)
)


# Variable a prédire, à mettre en facteur sinon random forest ne fonctionne pas  :
dataset$FTR = factor(dataset$FTR)

# Random forest :
RF <- randomForest::randomForest(
  FTR ~ .,
  data            = dataset ,
  importance  = TRUE,
  na.action     = na.omit,
  ntree           = 500)


# Les nouvelles données pour faire des predictions :
new_data = data.frame(
  HomeTeam    =  sample(HomeTeam,50,replace = T),
  AwayTeam     = sample(AwayTeam,50,replace = T),
  Home_Odd    = sample(seq(1,1.5,0.05),50,replace = T),
  Away_Odd     = sample(seq(2,5,0.05),50,replace = T),
  Draw_Odd     = sample(seq(2.8,10,0.05),50,replace = T)
)


# Predictions :
# 1) sur toutes les lignes de new_data avec affichage des 10 premières
# 2) sur les 10 premières lignes de new_data :
predict(RF, new_data, type = 'prob')[1:10,]
#>        A     D     H
#> 1  0.354 0.316 0.330
#> 2  0.300 0.522 0.178
#> 3  0.498 0.220 0.282
#> 4  0.312 0.240 0.448
#> 5  0.258 0.390 0.352
#> 6  0.136 0.194 0.670
#> 7  0.294 0.378 0.328
#> 8  0.276 0.502 0.222
#> 9  0.152 0.304 0.544
#> 10 0.354 0.350 0.296
predict(RF, new_data[1:10,], type = 'prob')
#>        A     D     H
#> 1  0.354 0.316 0.330
#> 2  0.300 0.522 0.178
#> 3  0.498 0.220 0.282
#> 4  0.276 0.218 0.506
#> 5  0.258 0.390 0.352
#> 6  0.116 0.288 0.596
#> 7  0.234 0.372 0.394
#> 8  0.276 0.502 0.222
#> 9  0.152 0.304 0.544
#> 10 0.446 0.428 0.126
#> attr(,"class")
#> [1] "matrix" "array"  "votes"

predict(RF, new_data)[1:10]
#>  1  2  3  4  5  6  7  8  9 10
#>  A  D  A  H  D  H  D  D  H  A
#> Levels: A D H
predict(RF, new_data[1:10,])
#>  1  2  3  4  5  6  7  8  9 10
#>  A  D  A  H  D  H  H  D  H  A
#> Levels: A D H
ƒacu.-

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 12 Nov 2022, 20:55

Merci beaucoup pour le retour !

Bon...ce que je trouve perturbant c'est que de mon côté, j'ai vraiment entre le cas 1) et 2) pour chaque ligne, des variations parfois importantes.
Alors que vous, il y a grosso modo la moitié des lignes qui restent identiques.

Et pourtant j'ai lancé la manip beaucoup de fois, et j'ai toujours eu des lignes différentes.

Si je peux vous embêter encore une dernière fois, vous pourriez me dire si quand vous lancez les prédictions une à une (predict match x, predict match x+1, ...) , vous obtenez les mêmes proba à chaque fois?

Et par curiosité, sur quelle version de R êtes vous?

J'ai mis à jour récemment en 4.2.1 et avant j'étais en 4.0.2. Et je n'avais pas remarqué ces choses là. Mais je crois que je ne peux plus utiliser le package random forest avec cette version, donc...je ne peux pas vérifier malheureusement.

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Fonction predict()

Messagepar Facundo Muñoz » 12 Nov 2022, 21:16

Non, je n'obtiens pas le même résultat en faisant les prédictions des matchs individuels :


Code : Tout sélectionner

...
predict(RF, new_data, type = 'prob')[1,]
#>         A         D         H
#> 0.2431835 0.4532056 0.3036109
predict(RF, new_data, type = 'prob')[2,]
#>         A         D         H
#> 0.5151069 0.1400147 0.3448784
predict(RF, new_data, type = 'prob')[3,]
#>         A         D         H
#> 0.3006632 0.5460575 0.1532793

predict(RF, new_data[1,], type = 'prob')
#>           A         D        H
#> 1 0.1495947 0.4377303 0.412675
#> attr(,"class")
#> [1] "matrix" "array"  "votes"
predict(RF, new_data[2,], type = 'prob')
#>           A         D         H
#> 2 0.3655122 0.1260133 0.5084746
#> attr(,"class")
#> [1] "matrix" "array"  "votes"
predict(RF, new_data[3,], type = 'prob')
#>           A         D         H
#> 3 0.2343405 0.3728814 0.3927782
#> attr(,"class")
#> [1] "matrix" "array"  "votes"


Je suis sur R 4.2.2.
ƒacu.-

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 12 Nov 2022, 21:21

Facundo Muñoz a écrit :Non, je n'obtiens pas le même résultat en faisant les prédictions des matchs individuels :


Code : Tout sélectionner

...
predict(RF, new_data, type = 'prob')[1,]
#>         A         D         H
#> 0.2431835 0.4532056 0.3036109
predict(RF, new_data, type = 'prob')[2,]
#>         A         D         H
#> 0.5151069 0.1400147 0.3448784
predict(RF, new_data, type = 'prob')[3,]
#>         A         D         H
#> 0.3006632 0.5460575 0.1532793

predict(RF, new_data[1,], type = 'prob')
#>           A         D        H
#> 1 0.1495947 0.4377303 0.412675
#> attr(,"class")
#> [1] "matrix" "array"  "votes"
predict(RF, new_data[2,], type = 'prob')
#>           A         D         H
#> 2 0.3655122 0.1260133 0.5084746
#> attr(,"class")
#> [1] "matrix" "array"  "votes"
predict(RF, new_data[3,], type = 'prob')
#>           A         D         H
#> 3 0.2343405 0.3728814 0.3927782
#> attr(,"class")
#> [1] "matrix" "array"  "votes"


Je suis sur R 4.2.2.


Ok...bon ! Je vais tenter de réinstaller R, voir si cela change quelque chose.

Je vous remercie beaucoup pour le temps que vous avez passé pour m'aider.

Bonne fin de soirée !

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Fonction predict()

Messagepar Facundo Muñoz » 12 Nov 2022, 21:21

J'ai essayé le code sur R v4.0.2 sur docker est ça arrive la même chose.
ƒacu.-

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Fonction predict()

Messagepar Facundo Muñoz » 12 Nov 2022, 21:28

Oui, désolé. J'ai le sentiment que ç'a un rapport avec ça : https://stackoverflow.com/a/41829983

mais ça ne se resout pas en mettant ntree impair. Mais essayez quand même. Peut-être pour ça que je obtiens des différences moins importantes.

Il se peut que predict fasse des choix un peu arbitraires quand il y a des égalités et que cela dépende de l'ensemble de matchs à prédire. Je ne sais pas... franchement, c'est un peu obscure...

Bon courage.
ƒacu.-

Louaï Benseghir
Messages : 6
Enregistré le : 11 Juil 2018, 09:31

Re: Fonction predict()

Messagepar Louaï Benseghir » 10 Jan 2023, 20:59

Bonsoir à tous,

Je ne suis pas très sûr, mais il me semble que le problème vient du choix de l'échantillon d'apprentissage et de test qu'utilise R à chaque essai. En effet, à chaque fois que vous appliquez la fonction d'apprentissage, R prend au hasard des observations du jeux de données. Donc, si à chaque apprentissage le jeux de données est différent alors le modèle est forcément différent, est donc les résultats de prédiction le seront forcément. De plus, si l'échantillon d'apprentissage est différent la partition de test le sera aussi, et donc en sortie de la fonction predict() les lignes ne correspondront pas aux mêmes matches à chaque essai, ce pourquoi, vous n'avez pas les mêmes valeurs de prédiction à chaque fois.

Pour que R tire au hasard le même échantillon de données, utilisez la fonction set.seed() avant chaque fonction :
Avant chaque fonction de création de variable dépendante et indépendantes tel que sample() et avant la fonction d'apprentissage du modèle.

En principe comme ça vous aurez le même résultat de prédiction à chaque fois.

Bon courage.

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 10 Jan 2023, 21:13

Louaï Benseghir a écrit :Bonsoir à tous,

Je ne suis pas très sûr, mais il me semble que le problème vient du choix de l'échantillon d'apprentissage et de test qu'utilise R à chaque essai. En effet, à chaque fois que vous appliquez la fonction d'apprentissage, R prend au hasard des observations du jeux de données. Donc, si à chaque apprentissage le jeux de données est différent alors le modèle est forcément différent, est donc les résultats de prédiction le seront forcément. De plus, si l'échantillon d'apprentissage est différent la partition de test le sera aussi, et donc en sortie de la fonction predict() les lignes ne correspondront pas aux mêmes matches à chaque essai, ce pourquoi, vous n'avez pas les mêmes valeurs de prédiction à chaque fois.

Pour que R tire au hasard le même échantillon de données, utilisez la fonction set.seed() avant chaque fonction :
Avant chaque fonction de création de variable dépendante et indépendantes tel que sample() et avant la fonction d'apprentissage du modèle.

En principe comme ça vous aurez le même résultat de prédiction à chaque fois.

Bon courage.


Salut,

merci pour le msg.

Oui tu as raison sur ce que tu dis, mais dans mon problème, le modèle d'apprentissage ne changeait pas. Je le définissais une fois et je n'y touchais plus.

Seule la taille du jeu données test utilisé pour faire de nouvelles prédictions changeait, et c'est ici que je ne comprenais pas bien pourquoi pour (x) lignes du jeu de données test, les probas retournées étaient différentes si il y avait x lignes ou x lignes + y lignes (sachant que quand je dis x lignes, je parle des mêmes x lignes que ce soit dans x ou x + y)

C'était pas du tout intuitif pour moi et j'ai toujours pas trouvé la réponse d'ailleurs. En plus, ce n'est pas un problème que je retrouve systématiquement quand j'utilise la fonction predict pour un objet random forest, donc...vraiment difficile d'y comprendre quelque chose.

Bonne soirée !

Bertrand Vassor
Messages : 46
Enregistré le : 18 Sep 2017, 10:18

Re: Fonction predict()

Messagepar Bertrand Vassor » 11 Jan 2023, 08:06

Bonjour Maxime,

pourquoi ne pas contacter la personne qui maintient la library ?
Cdlt. B

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 11 Jan 2023, 08:35

Bertrand Vassor a écrit :Bonjour Maxime,

pourquoi ne pas contacter la personne qui maintient la library ?
Cdlt. B


Salut !

Parce que je ne sais pas comment m'y prendre ! Mais j'y avais pensé bien-sûr.

Je ne suis pas du tout familier avec le reporting de potentiels bugs donc je ne sais vraiment pas comment on fait. J'ai tenté de trouver un mail ou nom ici : https://www.rdocumentation.org/packages/stats/versions/3.6.2 mais pas de nom, et le mail R-core@R-project.org je ne suis pas sûr qu'il faille passer par celui-ci d'après ce que j'ai pu lire ici : https://www.r-project.org/bugs.html.

Donc...c'est pour ça que je suis resté un peu sans rien faire, en attendant que quelqu'un vienne commenter ici en disant que j'ai fait n'importe quoi ou qu'il y a bien quelque chose qui cloche !

Bonne journée

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Fonction predict()

Messagepar Logez Maxime » 11 Jan 2023, 09:39

Bonjour,

Attention, comme il l'a déjà été précisé dans le fil de cette discussion la fonction predict est une fonction "générique". Autrement dit elle va chercher la fonction "predict.classe" qui est rattachée à la classe de ton objet et si elle n'en trouve pas cherchera la fonction par défaut ("predict.default" qui n'a pas été implémentée).
C'est pour ça que tu peux utiliser la même fonction avec des modèles de type "lm", "glm", "gam", etc. et donc aussi de ton random forest.
Pour savoir toutes les fonctions accessibles depuis la fonction générique tu peux faire

Code : Tout sélectionner

methods("predict")
.
Normalement en faisant ça tu verras qu'il existe la fonction "predict.randomForest" (si tu as chargé le package).
C'est aux auteurs de cette fonction que tu dois écrire et non aux auteurs de la fonction predict (de la fonction générique), parce que c'est elle qui va être utilisée infine pour renvoyer les prédictions de ton random forest.

Sur la page du package tu trouveras l'adresse mail de l'auteur, a qui tu pourras écrire directement et lui poser ta question.

Cordialement,
Maxime

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Fonction predict()

Messagepar Maxime Deniaux » 11 Jan 2023, 10:13

Logez Maxime a écrit :Bonjour,

Attention, comme il l'a déjà été précisé dans le fil de cette discussion la fonction predict est une fonction "générique". Autrement dit elle va chercher la fonction "predict.classe" qui est rattachée à la classe de ton objet et si elle n'en trouve pas cherchera la fonction par défaut ("predict.default" qui n'a pas été implémentée).
C'est pour ça que tu peux utiliser la même fonction avec des modèles de type "lm", "glm", "gam", etc. et donc aussi de ton random forest.
Pour savoir toutes les fonctions accessibles depuis la fonction générique tu peux faire

Code : Tout sélectionner

methods("predict")
.
Normalement en faisant ça tu verras qu'il existe la fonction "predict.randomForest" (si tu as chargé le package).
C'est aux auteurs de cette fonction que tu dois écrire et non aux auteurs de la fonction predict (de la fonction générique), parce que c'est elle qui va être utilisée infine pour renvoyer les prédictions de ton random forest.

Sur la page du package tu trouveras l'adresse mail de l'auteur, a qui tu pourras écrire directement et lui poser ta question.

Cordialement,
Maxime



Salut,

oui effectivement j'avais bien retenu que la fonction predict() était générique et dépendait donc de l'objet entré en paramètre.
Mais je n'avais pas assez bien compris les dessous du fonctionnement global comme tu l'as précisé dans ton msg.

Donc le package de predict.randomForest() est randomForest (https://www.rdocumentation.org/packages/randomForest/versions/4.7-1.1) si je comprends bien car la fonction est dans la liste. Néanmoins je ne vois toujours pas de mail ?

Je vois un "MAINTAINER" qui renvoie vers une autre page (https://www.rdocumentation.org/collaborators/name/Andy%20Liaw) qui elle même peut renvoyer vers un Github (https://github.com/null). Puis plus rien ?

De plus, sur la page https://www.rdocumentation.org/collaborators/name/Andy%20Liaw, où il est mentionné quels sont les packages dont la personne est l'auteur ou le mainteneur, randomForest n'est pas mentionné.

Est-ce que je loupe quelque chose ?

Merci !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité