Dans le billet précédent, j’ai présenté le théorème de Bayes à travers l’exemple d’un modèle (très très simple) portant sur le comportement des ours. Ce modèle mettait en relation deux variables C et G où

  • C est la variable indicatrice de l’évènement « L’ours est en colère » (C=o ou C=n)
  • G est la variable indicatrice de l’événement « L’ours grogne » (G=o ou G=n).

Il est possible d’utiliser un modèle bayésien (même un modèle aussi simple que celui-ci) de différentes manières, en fonction de la question que l’on se pose, mais aussi en fonction des données dont on dispose. Je vous présente ci-après quelques cas « bien tranchés »…

Premier cas: on ne dispose de données ni pour C, ni pour G

Imaginons que l’on ait un modèle théorique de comportement pour des variables qu’on n’a pas observées. Il est tout de même possible de « tirer » quelque chose du modèle… Dans le billet précédent par exemple, on partait de

  • l’a priori quant à la distribution de C (Pr(C))
  • l’a priori quant à la table de probabilité conditionnelle de G sachant C (Pr(G/C))

et on parvenait à en tirer des conclusions sur la manière dont il fallait interpréter un grognement d’ours (« Si un ours grogne, alors il y a 82% de chances qu’il soit en colère ».)

Evidemment, dans ce cas de figure, le résultat ne vaut pas tripette si on n’est pas en mesure de défendre les a priori qui sous-tendent le modèle… En l’occurence, mes connaissances en éthologie ursine sont limitées donc mes a priori et (par conséquent) cette conclusion, ne valent pas tripette -sauf d’un point de vue pédagogique, bien sûr-.

On dit de ce genre de construction de modèle qu’elle se base sur une connaissance d’expert.

Deuxième cas: on dispose de données pour G, mais pas pour C

Imaginons maintenant que l’on dispose d’observations pour G mais que l’on est incapables de mesurer directement C (car on ne sait pas lire dans les pensées de l’ours pour déterminer s’il est en colère ou non). C est alors une variable latente.

Dans ce cas on va partir de

  • l’a priori quant à la distribution de C: Pr(C)
  • l’a priori quant à la distribution de G sachant C: Pr(G/ C)
  • les observations de G: Pr(G)

et on va en tirer une meilleure connaissance de C (Pr(C/ G))

Troisième cas: on dispose de données pour C, mais pas pour G

Ce cas n’est pas très vraisemblable pour mon exemple ursin car il sous-entend que nous disposerions d’une machine à lire les pensées des ours MAIS que nous serions incapables d’entendre leurs grognements… Menfin bon. Bref.

Supposons donc qu’on soit en mesure d’observer C mais pas G. On va alors pouvoir utiliser le modèle pour prédire la variable G (l' »output » du modèle) en fonction de C.

On part donc de:

  • les observations de C: Pr(C)
  • l’a priori quant à la distribution de G sachant C: Pr(G/ C)

et on en déduit la distribution de G.

Quatrième cas

Dans ce dernier cas, on dispose de données d’observation à la fois pour C et pour G.

On va pouvoir alors utiliser ces données pour ajuster le modèle c’est à dire qu’on part de:

  • la structure du modèle (ici, simplement le fait que G dépende de C)
  • les observations de C
  • les observations de G

et on en tire des renseignements quant à

  • la distribution de C: Pr(C)
  • la distribution de G sachant C: Pr(G/ C)

Voyez plutôt: si on part d’un petit jeu de données comme celui-ci:

data=data.frame(C=c("o","o","o","n","n","n","o","n","n","n","o","o","n","n","n"),
                G=c("o","o","n","o","n","n","o","n","o","n","n","o","n","o","n"))

et que l’on définit la structure du modèle:

require(bnlearn)
model=model2network("[C][G|C]")

on peut alors ajuster le modèle aux données et en tirer une estimation des probabilités de C et de G sachant C:

fitted=bn.fit(model,data, method="mle")
print(fitted$C)

## 
##   Parameters of node C (multinomial distribution)
## 
## Conditional probability table:
##    n   o 
## 0.6 0.4

print(fitted$G)

## 
##   Parameters of node G (multinomial distribution)
## 
## Conditional probability table:
##  
##    C
## G           n         o
##   n 0.6666667 0.3333333
##   o 0.3333333 0.6666667

Le fait d’ajuster le modèle aux observations montre qu’un ours a Pr(C=o)= 40% de chances d’être en colère, et qu’un ours en colère grogne dans Pr(G=o/ C=o)= 67% des cas, tandis qu’un ours qui n’est pas en colère grogne dans pr(C=o/ C=n) 33% des cas.

Autres cas

En pratique, il est possible (voire fréquent) d’utiliser un mélange des approches évoquées ci-dessus.

Par exemple, on peut avoir un jeu de données rassemblant des observations de C et G et les utiliser pour ajuster un modèle (comme ci-dessus, dans le quatrième cas évoqué), puis utiliser ce modèle pour prédire la variable C en fonction d’observations de G (comme dans le deuxième cas évoqué).

Sans rentrer trop dans les détails, je montre comment faire cela ci-dessous. Pour utiliser un modèle pour faire une prédiction, nous avons besoin d’utiliser un nouveau package, le package gRain. On convertit notre modèle « fitted » issu du package bnlearn en un modèle utilisable par gRain.

require(gRain)
grain.fitted=as.grain(fitted)

Puis on applique la fonction predict de ce package gRain à un nouveau jeu de données pour lequel on a seulement deux observations (G=o, et G=n) mais pas de donnée renseignant C.

On prédit la valeur de C en fonction des observations G et des paramètres du modèle ajusté:

predicted=predict(grain.fitted,
                   newdata=data.frame(C=c(NA,NA),
                                      G=c("o","n")),
                   response="C",
                   predictors="G",
                   type="distribution")
print(predicted$pred$C)

##              n         o
## [1,] 0.4285714 0.5714286
## [2,] 0.7500000 0.2500000

D’après le modèle, donc, la probabilité que l’ours soit en colère dans le premier cas (où il a grogné) est de 57% tandis que les chances qu’il soit en colère dans le deuxième cas (où il n’a pas grogné) sont de 25%.