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%.