Bonjour,
_____
J'ai déjà posté ce sujet sur le forum CIRAD, sans succès jusque là. J'espère que vous pourrez m'aider. Si j'ai une réponse sur un des deux sujets je ferai part de la réponse dans tous les cas.
Merci par avance pour votre aide.
_____
Je suis en train de travailler sur une régression logistique et j'ai détecté une anomalie lorsque je fais une validation croisée. Je poste donc ici dans l'espoir que vous m'aidiez à cerner le problème.
J'utilise 100 observations de deux variables générées aléatoirement selon des lois normales de paramètres différents.
Par la suite je crée un modèle qui a l'air assez cohérent (voir la courbe ROC à la fin).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #### Génération des données #### z = c(rep(0,50),rep(1,50)) x = c(rnorm(50,0,4),rnorm(50,2,4)) y = c(rnorm(50,0,1),rnorm(50,2,1)) plot(x,y,col=z+1) #### Création du modèle et prédiction par GLM ### res.glm = glm(formula=z~x+y,family=binomial) predict.res.glm = predict(res.glm, type="response")
J'effectue maintenant la validation croisée sur quatre groupes. Le principe étant de prédire les données de chaque groupe à partir des trois autres.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #### Validation croisée #### # Définition de 4 groupes. Trois d'entres eux construisent le modèle, on prédit sur le dernier. g = sample(rep(1:4,25)) # Initialisation des prédictions vect.proba = rep(0,100) for (k in 1:4){ # Echantillon d'apprentissage sur 3 groupes appr = as.data.frame(cbind(x[g!=k], y[g!=k])) z.appr = z[g!=k] res.glm.kfold = glm(formula=z.appr~appr[,1]+appr[,2],family=binomial) # Echantillon de vérification verif = as.data.frame(cbind(x[g==k], y[g==k])) vect.proba[g==k] = predict(res.glm.kfold, newdata = verif, type="response") #https://stat.ethz.ch/R-manual/R-patched/library/stats/html/predict.lm.html }
Alors ici, plusieurs choses :
--> J'obtiens des warnings (8 exactement) au niveau de la prédiction dans la boucle.
J'avoue ne pas comprendre car la définition de newdata est, selon le manuel d'utilisation :1: 'newdata' had 25 rows but variables found have 75 rows
2: In vect.proba[g == k] = predict(res.glm.kfold, newdata = verif, :
number of items to replace is not a multiple of replacement length
Je fournis bien le même nombre de variables, mais en effet il n'y a pas le même nombre d'observations ce qui est tout à fait normal. J'ai vu plusieurs scripts sur le net qui utilisent ce paramètre pour faire une validation croisée (ici par exemple).optionally, a data frame in which to look for variables with which to predict. If omitted, the fitted linear predictors are used.
D'où la question : Est-ce que c'est la bonne chose à faire ?
--> Ensuite : mes prédictions par validation croisée sont foireuses. Je vous indique un extrait des prédictions entre la 40e et la 60e ligne (à la 50e, on passe de 0 à 1)
Vous pouvez voir que dans certains cas les prédictions ne concordent pas du tout. J'ai testé les différents modèles en modifiant les valeurs de k à la main pour tester. Les paramètres ne sont pas excessivement différents, et du coup je ne comprends pas pourquoi il y a un tel écart.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 Nb Z Predic_GLM Predic_ValCroisee 40 0 0.319408438 0.145276517 41 0 0.205839858 0.119031341 42 0 0.012653655 0.029117270 43 0 0.181420164 0.749168854 44 0 0.020543180 0.914641430 45 0 0.442173491 0.645873783 46 0 0.157567167 0.131166378 47 0 0.045872366 0.102201020 48 0 0.085971756 0.060728705 49 0 0.489664348 0.021215917 50 0 0.013036409 0.036993982 51 1 0.984022606 0.007688740 52 1 0.918224041 0.039215022 53 1 0.944663266 0.201269337 54 1 0.297424130 0.701688379 55 1 0.803391279 0.897638029 56 1 0.946804556 0.210754072 57 1 0.260940236 0.097831911 58 1 0.996113114 0.130593783 59 1 0.919221343 0.071754892 60 1 0.508894219 0.071091520
Je finis en indiquant les courbes ROC, où vous pouvez bien voir que les prédictions obtenues par ma validation croisée sont très mauvaises.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 > res.glm Coefficients: (Intercept) x y -2.0162 0.1303 2.1463 > glm(formula=z.appr.test.1~appr.test.1[,1]+appr.test.1[,2],family=binomial) Coefficients: (Intercept) appr.test.1[, 1] appr.test.1[, 2] -2.121 0.224 2.437 > glm(formula=z.appr.test.2~appr.test.2[,1]+appr.test.2[,2],family=binomial) Coefficients: (Intercept) appr.test.2[, 1] appr.test.2[, 2] -2.3885 0.1578 2.3182 > glm(formula=z.appr.test.3~appr.test.3[,1]+appr.test.3[,2],family=binomial) Coefficients: (Intercept) appr.test.3[, 1] appr.test.3[, 2] -2.02831 0.09401 2.26203 > glm(formula=z.appr.test.4~appr.test.4[,1]+appr.test.4[,2],family=binomial) Coefficients: (Intercept) appr.test.4[, 1] appr.test.4[, 2] -1.73949 0.09701 1.78679
Le code pour info
Est-ce que vous avez une idée du problème pour faire ma validation croisée de manière cohérente ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 library("ROCR") par(mfrow=c(1,2)) roc.pred.glm <- prediction(predict.res.glm,z) roc.perf.glm <- performance(roc.pred.glm,"tpr","fpr") plot(roc.perf.glm,colorize=T,lwd=3,xlab = "Taux de faux positifs",ylab = "Taux de vrais positifs",main = "Courbe ROC - Prédiction par GLM") roc.pred.croisee <- prediction(vect.proba,z) roc.perf.croisee <- performance(roc.pred.croisee,"tpr","fpr") plot(roc.perf.croisee,colorize=T,lwd=3,xlab = "Taux de faux positifs",ylab = "Taux de vrais positifs",main = "Courbe ROC - Validation croisée")
J'espère que le pavé ne posera pas de souci, mais vu que je m'arrache les cheveux depuis quelques heures sur cela, je tenais à être le plus précis possible.
Merci par avance pour votre aide.
Cordialement,
Emmanuel Rambeau
Partager