L’execution des codes R ci-après fait appel aux packages tidyverse,rjags,ggextra,knitr,ggpubr,purrr, grid à installer préalablement
knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)
rm(list=ls())
library(tidyverse)
## ── Attaching packages ───────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.0 ✓ purrr 0.3.3
## ✓ tibble 3.0.0 ✓ dplyr 0.8.3
## ✓ tidyr 1.0.0 ✓ stringr 1.4.0
## ✓ readr 1.3.1 ✓ forcats 0.4.0
## ── Conflicts ──────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(rjags)
## Loading required package: coda
## Linked to JAGS 4.3.0
## Loaded modules: basemod,bugs
library(ggExtra)
On commence par introduire les données des trois groupes sous la forme d’une matrice \(X\) avec, en ligne le groupe d’étudiants et en colonne les résultats pour la première pêche (\(C_1\)), la quantité de poissons pris lors de la seconde pêche, mais pas la première \(C_{20}\) et enfin la quantité de poissons capturés les deux fois
X <- matrix(c(99,56,62,116,56,25,82,74,39),3,3, byrow = TRUE)
rownames(X) <- c("G1","G2","G3")
colnames(X)<- c("C1","C20","C21")
print(X,digits=1)
## C1 C20 C21
## G1 99 56 62
## G2 116 56 25
## G3 82 74 39
On construit d’abord les fonctions petersen et schnabel qui évaluent les estimeurs de Lincoln-Petersen et de Schnabel-Chapman ainsi que leur écart-type conditionnel à \(C_1, C_2\) si l’argument but vaut ESTIM. Pour Lincoln-Petersen, on utilise que \(C_{21}|C_1,C_2\) est une hypergéométrique, déjà codée en R, ce qui permet sa simulation (1000 tirages). Pour Schnabel-Chapman, on calcule l’estimateur de la variance de Wittes.
petersen<-function(C1=99,C20 = 56, C21=62, but="ESTIM"){
C2=C20+C21
nu.hat <- C1*C2/C21
pi.hat <- (C1+C2)/(2*nu.hat)
if(but=="ESTIM"){
sig.nu.hat= var(C1*C2/rhyper(nn = 1000,m = C1,n = nu.hat-C1,k = C2))^0.5
return(list(pi.hat=pi.hat,nu025.hat=nu.hat-2*sig.nu.hat,
nu.hat=nu.hat,nu975.hat=nu.hat+2*sig.nu.hat,
sig.nu.hat=sig.nu.hat))
} else return(list(pi.hat=pi.hat, nu.hat=nu.hat))
}
##__________________________________________
schnabel<-function(C1=99,C20 = 56, C21=62, but="ESTIM"){
C2=C20+C21
nu.hat <- ((C1+1)*(C2+1)/(C21+1))-1
pi.hat <- (C1+C2)/(2*nu.hat)
if(but=="ESTIM"){
sig.nu.hat=sqrt((C1+1)*(C20+C21+1)*(C1-C21)*(C2-C21)/(C21+1)/(C21+1)/(C21+2))
return(list(pi.hat=pi.hat,nu025.hat=nu.hat-2*sig.nu.hat,
nu.hat=nu.hat,nu975.hat=nu.hat+2*sig.nu.hat,
sig.nu.hat=sig.nu.hat))
} else return(list(pi.hat=pi.hat, nu.hat=nu.hat))
}
Pour refaire la figure 6, on a juste besoin de simulations pour évaluer la variabilité d’échantillonnage des estimateurs.
nu=200
pi1=pi2=0.1
repet=100000
C1=rbinom(repet,nu,pi1)
C21=rbinom(repet,C1,pi2)
C20=rbinom(repet,nu-C1,pi2)
NchapLincoln=petersen(C1 = C1, C20 = C20,C21 = C21,but = "Histo")$nu.hat
NchapSchnabel=schnabel(C1 = C1, C20 = C20,C21 = C21,but = "Histo")$nu.hat
print(paste("l'estimateur de Peterson-Lincoln est non défini avec une fréquence de ",round(sum(is.infinite(NchapLincoln))/repet,2)))
## [1] "l'estimateur de Peterson-Lincoln est non défini avec une fréquence de 0.13"
print(paste("Moyennes de nu, Lincoln et Schnabel"))
## [1] "Moyennes de nu, Lincoln et Schnabel"
print(c(nu, mean(NchapLincoln[!is.infinite(NchapLincoln)],na.rm=T),
mean(NchapSchnabel,na.rm=T)),2)
## [1] 200 225 178
print(paste("Risque quadratique de Lincoln et Schnabel"))
## [1] "Risque quadratique de Lincoln et Schnabel"
print(c(mean((NchapLincoln[!is.infinite(NchapLincoln)]-nu)^2,na.rm=T),
mean((NchapSchnabel-nu)^2,na.rm=T)), dig=2 )
## [1] 15127 10027
On peut alors réaliser une représentation de la répartition empirique des deux estimateurs
d<-tibble(`Lincoln-Petersen`=NchapLincoln,`Schnabel-Chapman`=NchapSchnabel)
d %>% gather(key=estimateurs,value = valeurs) %>% ggplot()+geom_density(aes(x=valeurs, color=estimateurs),adjust=2.5)+labs(y="densité empirique")+geom_vline(xintercept=nu)
Dans le même esprit, on peut refaire la figure 7 de l’article illustrant la décroissance du biais relatif avec \(nu\).
nu <- seq(100, 1000, by=50)
repet <- 20000
pi1 <- 0.3 ; pi2 <- 0.3
biaisP <- numeric(length(nu)) ;
biaisS <- numeric(length(nu))
for (k in 1:length(nu)) {
C1 <- rbinom(repet, nu[k], pi1)
C21 <- rbinom(repet, C1, pi2)
C20 <- rbinom(repet, nu[k]-C1, pi2)
C2 <- C21 + C20
NchapLincoln <- C1*C2/C21
NchapSchnabel <- (C1+1)*(C2+1)/(C21+1)-1
biaisP[k] <- (mean(NchapLincoln[C21!=0])-nu[k])/nu[k]
biaisS[k] <- (mean(NchapSchnabel[C21!=0])-nu[k])/nu[k]
}
d<-tibble(`Lincoln-Petersen`=biaisP,`Schnabel-Chapman`=biaisS, nu=nu)
d %>% gather(key=Estimateur,value = valeurs,-nu) %>% ggplot()+geom_line(aes(x=nu, y= valeurs,color=Estimateur))+labs(y="biais relatif")+geom_hline(yintercept=0)
Pour le calcul du tableau 3, on va utiliser la fonction map du package purr pour répéter le calcul sur chaque groupe.
d_grouped <- (X) %>% data.frame() %>% bind_cols(Gpe=c("G1","G2","G3")) %>%
group_by(Gpe) %>% nest
d_grouped<- d_grouped %>%
mutate( petersen=purrr::map(data, ~{petersen(.x$C1,.x$C20,.x$C21)} ),
schnabel=purrr::map(data, ~{schnabel(.x$C1,.x$C20,.x$C21)} ),
)
results<-d_grouped %>%
mutate(nu.p=map_dbl(petersen,"nu.hat"),
sig.nu.p=map_dbl(petersen,"sig.nu.hat"),
nu.s=round(map_dbl(schnabel,"nu.hat")),
sig.nu.s=map_dbl(schnabel,"sig.nu.hat")
) %>%
select(-petersen,-schnabel,-data)
knitr::kable(results, format="markdown", digits=c(0,0,1,0,1))
Gpe | nu.p | sig.nu.p | nu.s | sig.nu.s |
---|---|---|---|---|
G1 | 188 | 10.1 | 188 | 9.9 |
G2 | 376 | 59.1 | 368 | 51.8 |
G3 | 238 | 23.8 | 236 | 21.4 |
#knitr::kable(results, format="latex", digits=c(0,0,1,0,1))
Un détour par la loi conditionnelle de \(C_{21}\) sachant \(C_{1}\) et \(C_{2}\) permet d’introduire la loi hypergéométrique comme autre description possible des résultats d’une expérience de CMR basée sur deux pêches successives.
Commençons par écrire la loi d’échantillonnage selon le modèle binomial séquentiel: \[\begin{align*} \lbrack C_{1},C_{20},C_{21}|\nu,\pi_1,\pi_2] & = [C_{1}|\nu, \pi_1][C_{20}|C_{1},\nu, \pi_2][C_{21}|C_{1},\pi_2]\\ & =\frac{\pi_{1}^{C_{1}}(1-\pi_{1})^{\nu-C_{1}}\nu!}{(\nu-C_{1}% )!C_{1}!}\\ & \times\frac{\pi_{2}^{C_{20}}(1-\pi_{2})^{\nu-C_{1}-C_{20}}(\nu -C_{1})!}{(\nu-C_{1}-C_{20})!C_{20}!}\\ & \times\frac{\pi_{2}^{C_{21}}(1-\pi_{2})^{C_{1}-C_{21}}C_{1}!}% {(C_{1}-C_{21})!C_{21}!}% \end{align*}\]
On montre d’abord que la loi de \(C_{1},C_{20},C_{21}|\nu,\pi_1,\pi_2\) est la même en adoptant le modèle multinomial de bilan, décrit dans la section 4 équation 1 par: \[C_{1}|\nu, \pi_1 \sim dbin(\pi_{1},\nu)\\ C_{20}|C_{1}, \nu, \pi_2 \sim dbin(\pi_{2},\nu-C_{1})\\ C_{21}|C_{1}, \pi_2 \sim dbin(\pi_{2},C_{1})\] En effet, pour le modèle multinomial à 4 catégories, il vient: \[\begin{align*} \lbrack C_{1},C_{20},C_{21}|\nu,\pi_1,\pi_2] & =\frac{\pi_{1}^{C_{1}}(1-\pi_{1}% )^{\nu-C_{1}}\nu!}{(\nu-C_{1})!C_{1}!}\times\frac{\pi_{2}^{C_{20}}% (1-\pi_{2})^{\nu-C_{1}-C_{20}}(\nu-C_{1})!}{(\nu-C_{1}-C_{20})!C_{20}!}\\ & \times\frac{\pi_{2}^{C_{21}}(1-\pi_{2})^{C_{1}-C_{21}}C_{1}!}% {(C_{1}-C_{21})!C_{21}!}\\ & =\frac{\nu!}{C_{21}!(C_{1}-C_{21})!C_{20}!(\nu-C_{1}-C_{20})!}\\ & \times\pi_{1}^{C_{1}-C_{21}+C_{21}}(1-\pi_{1})^{\nu-C_{1}% -C_{20}+C_{20}}\pi_{2}^{C_{20}+C_{21}}(1-\pi_{2})^{C_{1}-C_{1}% +\nu-C_{21}-C_{20}}\\ & \propto\left( \pi_{1}\pi_{2}\right) ^{C_{21}}\left( \pi _{1}(1-\pi_{2})\right) ^{C_{1}-C_{21}}\\ & \times((1-\pi_{1})\pi_{2})^{C_{20}}((1-\pi_{1})(1-\pi _{2}))^{\nu-C_{1}-C_{20}}% \end{align*}\]
Pour plus de clarté, on omet momentanément le conditionnement sur \(\nu\), \(\pi_1\) et \(\pi_2\). La loi conditionnelle de \(C_{21}\) sachant \(C_{1}\) et \(C_{2}\) est facilement mise en évidence, en montrant comment la lire à partir de la conjointe de \(C_{1}\), \(C_{20}\) et \(C_{21}\) : \[\begin{align*} \lbrack C_{1},C_{20},C_{21}|\nu,\pi_1,\pi_2] & =[C_{1},C_{2}-C_{21},C_{21}|\nu,\pi_1,\pi_2]\\ \lbrack C_{21}|C_{1},C_{2},\nu,\pi_1,\pi_2] & \propto\frac{1}{C_{21}!(C_{1}-C_{21} )!C_{20}!(\nu-C_{1}-C_{20})!}\\ & \propto\frac{1}{C_{21}!(C_{1}-C_{21})!(C_{2}-C_{21})!(\nu-C_{1} -C_{2}+C_{21})!}\\ & \propto\frac{C_{1}!(\nu-C_{1})!}{C_{21}!(C_{1}-C_{21})!(C_{2}-C_{21} )!(\nu-C_{1}-C_{2}+C_{21})!}\\ & \propto C_{C_{1}}^{C_{21}}C_{\nu-C_{1}}^{C_{2}-C_{21}}=\frac{C_{C_{1} }^{C_{21}}C_{\nu-C_{1}}^{C_{2}-C_{21}}}{C_{\nu}^{C_{2}}}\\ \end{align*}\] car \({\displaystyle\sum\limits_{y}}C_{N}^{y}C_{B}^{K-y}=C_{N+B}^{K}\) d’après la formule du binome . On reconnaît une loi hypergéométrique de paramètres \((\nu,C_{1},C_{2})\). En utilisant la décomposition en produits suivante \([C_1,C_2,C_{21}|\nu,\pi_1,\pi_2]=[C_1|\nu,\pi_1][C_2|\nu,\pi_2][C_{21}|C_1,C_2,\nu]\), on tombe finalement sur la modélisation traditionnelle alternative d’une expérience de CMR, fondée sur un tirage sans remise des poissons recapturés lors de la 2ème pêche via une loi hypergéométrique:
\[\begin{align*} C_{1}|\nu,\pi_1 & \sim dbin(\pi_{1},\nu)\\ C_{2}|\nu,\pi_2 & \sim dbin(\pi_{2},\nu)\\ C_{21}|C_{1},C_{2},\nu & % \sim hypergeometrique(C_{2},C_{1},\nu-C_{1}) \sim hypergeometrique(\nu,C_{1},C_{2}) \end{align*}\]
Sur le même modèle que les fonctions petersen et schnabel, on construit une fonction qui réalise l’estimation du max de vraisemblance et qui construit un intervalle de confiance à 95% par approximation du chi-deux sur la vraisemblance profilée.
##__________________________________________
loglikHaricot <-function(nu,pi,C1,C21,C20){
dbinom(C1,nu,pi,log=T)+
dbinom(C21,C1,pi,log=T)+
dbinom(C20,nu-C1,pi,log=T)
}
##__________________________________________
maxloglikHaricot <-function(C1=99,C20 = 56, C21=62, numax=1000){
nutest= seq(C1+C20 , numax, by=1)
C2=C20+C21
logliktest= loglikHaricot(nu=nutest,pi = (C1+C2)/(2*nutest) ,
C1=C1,C21=C21,C20=C20)
imax=which.max(logliktest)
nu.hat=nutest[imax]
pi.hat=(C1+C2)/(2*nu.hat)
#likelihood ratio test
irange = 2*(logliktest[imax]-logliktest)-qchisq(p=0.95,df=1)
i1=which.min(irange^2)
if(i1 < imax) {i2 = which.min(irange[imax:length(irange)]^2)+(imax-1)
nu025.hat = nutest[i1]
nu975.hat = nutest[i2] } else {
# i2 correspond à q05
i2=which.min(irange[1:imax]^2)
nu025.hat = nutest[i2]
nu975.hat = nutest[i1] }
return(list(pi.hat=pi.hat,nu025.hat=nu025.hat,
nu.hat=nu.hat,nu975.hat=nu975.hat))
}
Le tableau 4 est alors obtenu en appelant les fonctions petersen, schnabel et maxloglikHaricot , puis en rangeant les résultats dans un tableau imprimé joliment grâce à la fonction R kable.
d_grouped <- (X) %>% data.frame() %>% bind_cols(Gpe=c("G1","G2","G3")) %>%
group_by(Gpe) %>% nest
d_grouped<- d_grouped %>%
mutate( petersen=purrr::map(data, ~{petersen(.x$C1,.x$C20,.x$C21)} ),
schnabel=purrr::map(data, ~{schnabel(.x$C1,.x$C20,.x$C21)} ),
maxloglik = purrr::map(data, ~{maxloglikHaricot(.x$C1,.x$C20,.x$C21, numax=1000)} ))
results<-d_grouped %>%
mutate(#pi.p= map_dbl(petersen,"pi.hat"),
nu025.p=round(map_dbl(petersen,"nu025.hat")),
nu.p=round(map_dbl(petersen,"nu.hat")),
nu975.p=round(map_dbl(petersen,"nu975.hat")),
#pi.s= map_dbl(schnabel,"pi.hat"),
nu025.s=round(map_dbl(schnabel,"nu025.hat")),
nu.s=round(map_dbl(schnabel,"nu.hat")),
nu975.s=round(map_dbl(schnabel,"nu975.hat")),
#pi.ml= map_dbl(maxloglik,"pi.hat"),
nu025.ml=round(map_dbl(maxloglik,"nu025.hat")),
nu.ml=round(map_dbl(maxloglik,"nu.hat")),
nu975.ml=round(map_dbl(maxloglik,"nu975.hat")),
) %>%
select(-petersen,-schnabel,-maxloglik,-data)
knitr::kable(results, format="markdown")
Gpe | nu025.p | nu.p | nu975.p | nu025.s | nu.s | nu975.s | nu025.ml | nu.ml | nu975.ml |
---|---|---|---|---|---|---|---|---|---|
G1 | 168 | 188 | 209 | 168 | 188 | 208 | 172 | 189 | 213 |
G2 | 251 | 376 | 501 | 264 | 368 | 472 | 297 | 385 | 534 |
G3 | 191 | 238 | 284 | 193 | 236 | 278 | 205 | 242 | 299 |
#knitr::kable(results, format="latex")
On réalise l’inférence bayésienne en profitant de la commodité du langage BUGS (on déclare le modèle dans la variable model). On utilise une loi a priori bêta(2,1) pour \(\pi\), un choix acceptable pour encoder le jugement d’un étudiant annonçant que son évaluation moyenne personnelle de l’efficacité \(\pi\) est de l’ordre de \(2/3\) mais qu’il n’en est pas très sûr : environ une chance sur deux pour l’intervalle \([0.4,0.8]\) ou son complémentaire. Et une loi a priori uniforme pour \(\nu\) , dans un souci de traduire une certaine équiprobabilité, mais sur un intervalle limité supérieurement à \(1000\) haricots .
numax=1000
model<-"model
{
#priors
nuReal ~ dunif(0,numax)
nu_prior ~ dunif(0,numax)
nu <- round(nuReal)
pi ~ dbeta(2,1)
pi_prior ~ dbeta(2,1)
#Vraisemblance
C1 ~ dbin(pi,nu)
PasPris <- nu - C1
C21 ~ dbin(pi,C1)
C20 ~ dbin(pi,PasPris)
}
"
C1=99; C20=56; C21=62;
data_jags<-list(C1=C1,C20=C20, C21=C21, numax=numax)
params <- c("pi", "pi_prior", "nu", "nu_prior")
min_nu <- C1 + C20 + 1
inits <- function(){
list(pi = rbeta(1, 1, 1), pi_prior = rbeta(1, 1, 1),
nuReal = runif(1, min_nu, numax))
}
n_iter <- 25000 # TOTAL Number of iterations including Burn in
n_burn <- 5000 #Number of iterations for Burn in
n_thin <- 10 #thin
n_chains <- 3 #nb chaines
modele <- jags.model(file = textConnection(object = model),
data = data_jags,
inits = list(inits(),inits(),inits()),
n.adapt = n_burn,
n.chains = n_chains, quiet = FALSE)
## Compiling model graph
## Resolving undeclared variables
## Allocating nodes
## Graph information:
## Observed stochastic nodes: 3
## Unobserved stochastic nodes: 4
## Total graph size: 13
##
## Initializing model
update(modele,n_burn)
Un point de vigilance important : Bien que de nombreux outils d’inférence bayésienne, relativement simples d’utilisation, existent aujourd’hui, ces outils n’intègrent aucun garde-fou permettant de s’assurer de leur bonne utilisation pratique : un minimum de connaissances en statistique bayésienne est donc requise pour une utilisation sereine, e.g., comment s’assurer, dans la mesure du possible, du bon comportement de l’algorithme d’inférence bayésienne mis en oeuvre? C’est l’objet du package coda qui calcule la taille effective d’échantillons MCMC, et met en oeuvre le test de Gelman-Rubin pour s’assurer que les chaînes ont convergé.
echantillons_mcmc <- coda.samples(model = modele,
variable.names = params,
n.iter = n_iter,
thin = n_thin)
# Have a look on posterior statistics
summary(echantillons_mcmc)
##
## Iterations = 10010:35000
## Thinning interval = 10
## Number of chains = 3
## Sample size per chain = 2500
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## nu 190.8473 10.5239 0.1215196 0.1272015
## nu_prior 494.1731 290.7658 3.3574743 3.4358545
## pi 0.5703 0.0398 0.0004596 0.0004648
## pi_prior 0.6664 0.2347 0.0027103 0.0027083
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## nu 173.0000 183.0000 190.0000 197.0000 214.0000
## nu_prior 22.3689 243.4486 490.5462 744.0597 975.3858
## pi 0.4899 0.5437 0.5714 0.5977 0.6454
## pi_prior 0.1503 0.5048 0.7074 0.8626 0.9874
# Have a look on MCMC chains
gelman.plot(echantillons_mcmc[, params])
gelman.diag(echantillons_mcmc[, params])
## Potential scale reduction factors:
##
## Point est. Upper C.I.
## pi 1 1.00
## pi_prior 1 1.00
## nu 1 1.00
## nu_prior 1 1.01
##
## Multivariate psrf
##
## 1
effectiveSize(echantillons_mcmc[, params])
## pi pi_prior nu nu_prior
## 7346.520 7510.693 6858.606 7165.587
On stocke les résultats dans la variable echantillons_posterior sous forme de tableau et on produit la figure 8.
echantillons_posterior <- echantillons_mcmc %>%
map_dfr(# On applique aux 3 éléments de la liste la même function
function(tab_mcmc){ # tab mcmc
resultat <- tab_mcmc %>% # On prend le tableau mcmc
as.data.frame() %>% # On transforme en data.frame
mutate(num_echantillon = 1:nrow(tab_mcmc)) # On créé un indice de numéro
},
.id = "chaine") %>% # On créée une colonne chaine qui stocke le numero de chaine
as_tibble()
p <- echantillons_posterior %>% rename(x=pi,y=nu) %>%
ggplot(aes(x = x,y=y)) +
geom_point(col = "red") +
geom_density_2d(col = "black") +
theme(legend.position="none")+
labs(x=expression(pi),
y=expression(nu),title="CMR: Population vs capturabilité")
ggExtra::ggMarginal(p, type = "densigram")
Et le tableau 5
sommaire<-echantillons_posterior %>% mutate(chaine=1:length(chaine)) %>% map_df(~{tibble(
mean=mean(.x),
sdt=sd(.x),
q05=quantile(.x,probs=.05),
q25=quantile(.x,probs=.25),
q50=quantile(.x,probs=.5),
q75=quantile(.x,probs=.75),
q95=quantile(.x,probs=.95)
)},
.id="param")
knitr::kable(sommaire[-1,], format="markdown",digits=2)
param | mean | sdt | q05 | q25 | q50 | q75 | q95 |
---|---|---|---|---|---|---|---|
nu | 190.85 | 10.52 | 176.00 | 183.00 | 190.00 | 197.00 | 210.00 |
nu_prior | 494.17 | 290.77 | 45.25 | 243.45 | 490.55 | 744.06 | 950.33 |
pi | 0.57 | 0.04 | 0.50 | 0.54 | 0.57 | 0.60 | 0.63 |
pi_prior | 0.67 | 0.23 | 0.22 | 0.50 | 0.71 | 0.86 | 0.97 |
num_echantillon | 1250.50 | 721.74 | 125.95 | 625.75 | 1250.50 | 1875.25 | 2375.05 |
On reprend quasiment les mêmes instructions en ajoutant simplement quelques lignes pour modéliser la troisième pêche.
model2<-"model
{
#priors
nuReal ~ dunif(0,500)
nu_prior ~ dunif(0,500)
nu <- round(nuReal)
pi ~ dbeta(2,1)
pi_prior ~ dbeta(2,1)
#Vraisemblance
C1 ~ dbin(pi,nu)
PasPris <- nu - C1
C21 ~ dbin(pi,C1)
C20 ~ dbin(pi,PasPris)
# troisieme peche
C321 ~ dbin(pi,C21)
UnMaisPasDeux<-C1-C21
C301 ~ dbin(pi,UnMaisPasDeux)
C320 ~ dbin(pi,C20)
JamaisPris <- nu - C1-C20
C300 ~ dbin(pi,JamaisPris)
}
"
C1=99; C20=56; C21=62;C300=41;C321=43;C301=15;C320=38;
data_jags_bis<-list(C1=C1,C20=C20, C21=C21,C300=C300,C321=C321,C301=C301,C320=C320)
params <- c("pi", "pi_prior", "nu", "nu_prior")
min_nu <- C1 + C20 + 1+C300
inits <- function(){
list(pi = rbeta(1, 1, 1), pi_prior = rbeta(1, 1, 1),
nuReal = runif(1, min_nu, 500))
}
modelebis <- jags.model(file = textConnection(object = model2),
data = data_jags_bis,
inits = list(inits(),inits(),inits()),
n.adapt = n_burn,
n.chains = n_chains, quiet = FALSE)
## Compiling model graph
## Resolving undeclared variables
## Allocating nodes
## Graph information:
## Observed stochastic nodes: 7
## Unobserved stochastic nodes: 4
## Total graph size: 19
##
## Initializing model
update(modelebis,n_burn)
echantillons_mcmc_bis <- coda.samples(model = modelebis,
variable.names = params,
n.iter = 3*n_iter,
thin = n_thin)
summary(echantillons_mcmc_bis)
##
## Iterations = 10010:85000
## Thinning interval = 10
## Number of chains = 3
## Sample size per chain = 7500
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## nu 216.6025 6.07090 0.0404727 0.041120
## nu_prior 250.3625 144.17838 0.9611892 0.949298
## pi 0.5460 0.02453 0.0001635 0.000166
## pi_prior 0.6691 0.23562 0.0015708 0.001571
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## nu 206.0000 212.0000 216.0000 220.0000 230.0000
## nu_prior 12.4547 125.0699 251.5266 375.2688 486.6905
## pi 0.4977 0.5295 0.5463 0.5627 0.5935
## pi_prior 0.1567 0.5041 0.7120 0.8677 0.9874
echantillons_posterior_bis <- echantillons_mcmc_bis %>%
map_dfr(# On applique aux 3 éléments de la liste la même function
function(tab_mcmc){ # tab mcmc
resultat <- tab_mcmc %>% # On prend le tableau mcmc
as.data.frame() %>% # On transforme en data.frame
mutate(num_echantillon = 1:nrow(tab_mcmc)) # On créé un indice de numéro
},
.id = "chaine") %>% # On créée une colonne chaine qui stocke le numero de chaine
as_tibble()
echantillons_post=rbind(echantillons_posterior %>% mutate(nbpech="Deux"),
echantillons_posterior_bis %>% mutate(nbpech="Trois")
)
####
library(cowplot)
# Main plot
df<-echantillons_post %>% select(pi,nu,nbpech) %>% mutate(Peches= nbpech)
pmain<-ggpubr::ggscatter(data = df, x = "pi", y = "nu",
add = "reg.line", # Add regression line
color = "Peches", palette = "jco", # Color by groups
shape = "Peches", # Change point shape by groups
fullrange = TRUE, # Extending the regression line
rug = FALSE# Add marginal rug
)
# Marginal densities along x axis
xdens <- axis_canvas(pmain, axis = "x")+
geom_density(data = df, aes(x = pi, fill = Peches),
alpha = 0.7, size = 0.2)+
ggpubr::fill_palette("jco")
# Marginal densities along y axis
# Need to set coord_flip = TRUE, if you plan to use coord_flip()
ydens <- axis_canvas(pmain, axis = "y", coord_flip = TRUE)+
geom_density(data = df, aes(x = nu, fill = Peches),
alpha = 0.7, size = 0.1)+
coord_flip()+
ggpubr::fill_palette("jco")
p1 <- insert_xaxis_grob(pmain, xdens, grid::unit(.2, "null"),
position = "top")
p2<- insert_yaxis_grob(p1, ydens, grid::unit(.2, "null"),
position = "right")
ggdraw(p2)
Dans cette annexe, nous supposons que \(\pi_{1} =\pi_{2}=\pi\). Par ailleurs, \(\pi \sim dbeta(a,b)\) et \(\nu\) suit une loi discrète de support fini.
La loi jointe des inconnues et des observables est donnée par: \[\begin{align*} \lbrack\nu,\pi,C_{1},C_{20},C_{21}] & =[C_{21}|C_{1} ,\pi][C_{20}|C_{1},\nu ,\pi][C_{1}|\nu,\pi][\nu][\pi]\\ & =\frac{\nu!\pi^{C_{1}+C_{2}}(1-\pi)^{2\nu-C_{1}-C_{2}}[\nu][\pi ]}{C_{21}!(C_{1}-C_{21})!C_{20}!(\nu-C_{1}-C_{20})!} \end{align*}\]
On en déduit immédiatement (en focalisant sur le rôle de ses arguments \(\pi\) puis \(\nu\)) les lois conditionnelles complètes de \(\pi\) et de \(\nu\): \[\begin{align*} \pi|\nu,C_{1},C_{20},C_{21} & \sim dbeta(a+C_{1}+C_{2}% ,b+2\nu-C_{1}-C_{2})\\ \lbrack \nu|\pi, C_{1},C_{20},C_{21}] & = \frac{(1-\pi)^{2\nu}\nu![\nu]}{(\nu -C_{1}-C_{20})!}\times Cste \end{align*}\]
L’écriture d’un échantillonneur de Gibbs et la comparaison de ses sorties par rapport à celles de Jags sont laissées au lecteur.