Skip to content

Commit 12dc6b9

Browse files
authored
Merge pull request #266 from fonnesbeck/M0_pymc
PyMC implementation of M0 model
2 parents 0fe01bf + d3c948f commit 12dc6b9

5 files changed

Lines changed: 98 additions & 0 deletions

File tree

posterior_database/models/info/M0_model.info.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
"stan": {
1212
"model_code": "models/stan/M0_model.stan",
1313
"stan_version": ">=2.26.0"
14+
},
15+
"pymc": {
16+
"model_code": "models/pymc/M0_model.py",
17+
"pymc_version": ">=5.16.0"
1418
}
1519
},
1620
"licence": "BSD3"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "M0_model_discrete",
3+
"keywords": ["BPA", "Ch.6", "Population", "Capture", "Recapture", "Individual", "Constant", "Discrete"],
4+
"title": "Inferring population size with constant detection probability",
5+
"description": "Detection probability of an individual is assumed constant over individuals and over time periods",
6+
"urls": "https://github.com/stan-dev/example-models/blob/master/BPA/Ch.06",
7+
"references": "kery2011population",
8+
"added_by": "Chris Fonnesbeck",
9+
"added_date": "2021-06-24",
10+
"model_implementations": {
11+
"pymc": {
12+
"model_code": "models/pymc/M0_model_discrete.py",
13+
"pymc_version": ">=5.16.0"
14+
}
15+
}
16+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import numpy as np
2+
import pymc as pm
3+
4+
def model(data):
5+
y = np.array(data["y"]) # capture history matrix
6+
T = np.array(data["T"]) # time periods
7+
8+
coords = {"individual": np.arange(data["M"]),
9+
"capture_period": np.arange(data["T"])}
10+
with pm.Model(coords=coords) as pymc_model:
11+
y_data = pm.Data("y", y, dims=("individual", "capture_period"))
12+
s = pm.Deterministic("s", y_data.sum(axis=1), dims="individual")
13+
is_observed = s > 0
14+
15+
# Inclusion probability
16+
omega = pm.Uniform("omega", 0, 1)
17+
# Capture probability
18+
p = pm.Uniform("p", 0, 1)
19+
20+
# Defining bernoulli and binomial components
21+
binom = pm.Binomial.dist(n=T, p=p)
22+
log_omega = pm.math.log(omega)
23+
log_one_minus_omega = pm.math.log(1-omega)
24+
log_one_minus_p = pm.math.log(1-p)
25+
26+
# Computing marginalization mixture
27+
logp_if_obs = log_omega + pm.logp(binom, s)
28+
logp_zero_single = pm.math.logaddexp(log_omega + T * log_one_minus_p , log_one_minus_omega)
29+
logp_each = pm.math.switch(is_observed, logp_if_obs, logp_zero_single)
30+
31+
pm.Potential("likelihood", logp_each.sum())
32+
33+
omega_nd = pm.Deterministic("omega_nd", (omega * (1 -p)**T) / (omega * (1 - p)**T + (1 - omega)))
34+
35+
return pymc_model
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import numpy as np
2+
import pymc as pm
3+
4+
def model(data):
5+
y = np.array(data["y"]) # capture history matrix
6+
T = np.array(data["T"]) # time periods
7+
coords = {"individual": np.arange(data["M"]),
8+
"capture_period": np.arange(data["T"])}
9+
with pm.Model(coords=coords) as pymc_model:
10+
11+
# Inclusion probability
12+
omega = pm.Uniform("omega", 0, 1)
13+
# Capture probability
14+
p = pm.Uniform("p", 0, 1)
15+
16+
# Inclusion indicator
17+
z = pm.Bernoulli("z", p=omega, dims="individual")
18+
19+
y_obs = pm.Bernoulli("y_obs", p=z[:, None]*p, observed=y, dims=("individual", "capture_period"))
20+
21+
N = pm.Deterministic("N", pm.math.sum(z))
22+
23+
omega_nd = pm.Deterministic("omega_nd", (omega * (1 -p)**T) / (omega * (1 - p)**T + (1 - omega)))
24+
25+
return pymc_model
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"keywords": ["bpa book", "capture-recapture"],
3+
"urls": "https://github.com/stan-dev/example-models/blob/master/BPA/Ch.06",
4+
"references": "kery2011population",
5+
"dimensions": {
6+
"omega": 1,
7+
"p": 1,
8+
"omega_nd": 1,
9+
"N": 1,
10+
"z": 237
11+
},
12+
"reference_posterior_name": null,
13+
"added_date": "2026-01-16",
14+
"added_by": "Chris Fonnesbeck",
15+
"name": "M0_data-M0_model_discrete",
16+
"model_name": "M0_model_discrete",
17+
"data_name": "M0_data"
18+
}

0 commit comments

Comments
 (0)