Skip to content

Commit 6c5d621

Browse files
dilpathvwiela
andauthored
Compute criterion weights (by @vwiela) (#136)
--------- Co-authored-by: Vincent Wieland <v_wiela27@web.de>
1 parent 67c4d79 commit 6c5d621

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

doc/analysis.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ The PEtab Select Python library provides some methods to help with this. Please
77
See the Python API docs for the :class:`petab_select.Models` class, which provides some methods. In particular, :attr:`petab_select.Models.df` can be used
88
to get a quick overview over all models, as a pandas dataframe.
99

10-
Additionally, see the Python API docs for the ``petab_select.analysis`` module, which contains some methods to subset and group models,
10+
Additionally, see the Python API docs for the :mod:`petab_select.analyze` module, which contains some methods to subset and group models,
1111
or compute "weights" (e.g. Akaike weights).

petab_select/analyze.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import warnings
44
from collections.abc import Callable
55

6+
import numpy as np
7+
68
from .constants import Criterion
79
from .model import Model, ModelHash, default_compare
810
from .models import Models
@@ -12,6 +14,7 @@
1214
"group_by_predecessor_model",
1315
"group_by_iteration",
1416
"get_best_by_iteration",
17+
"compute_weights",
1518
]
1619

1720

@@ -159,3 +162,35 @@ def get_best_by_iteration(
159162
for iteration, iteration_models in iterations_models.items()
160163
}
161164
return best_by_iteration
165+
166+
167+
def compute_weights(
168+
models: Models,
169+
criterion: Criterion,
170+
as_dict: bool = False,
171+
) -> list[float] | dict[ModelHash, float]:
172+
"""Compute criterion weights.
173+
174+
N.B.: regardless of the criterion, the formula used is the Akaike weights
175+
formula, but with ``criterion`` values instead of the AIC.
176+
177+
Args:
178+
models:
179+
The models.
180+
criterion:
181+
The criterion.
182+
as_dict:
183+
Whether to return a dictionary, with model hashes for keys.
184+
185+
Returns:
186+
The criterion weights.
187+
"""
188+
relative_criterion_values = np.array(
189+
models.get_criterion(criterion=criterion, relative=True)
190+
)
191+
weights = np.exp(-0.5 * relative_criterion_values)
192+
weights /= weights.sum()
193+
weights = weights.tolist()
194+
if as_dict:
195+
weights = dict(zip(models.hashes, weights, strict=False))
196+
return weights

test/analyze/test_analyze.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pathlib import Path
22

3+
import numpy as np
34
import pytest
45

56
from petab_select import (
@@ -77,3 +78,17 @@ def test_relative_criterion_values(models: Models) -> None:
7778
for criterion_value in criterion_values
7879
]
7980
assert test_value == expected_value
81+
82+
83+
def test_compute_weights(models: Models) -> None:
84+
"""Test ``analyze.compute_weights``."""
85+
criterion_values = np.array(
86+
models.get_criterion(criterion=Criterion.AIC, relative=True)
87+
)
88+
expected_weights = (
89+
np.exp(-0.5 * criterion_values) / np.exp(-0.5 * criterion_values).sum()
90+
)
91+
test_weights = analyze.compute_weights(
92+
models=models, criterion=Criterion.AIC
93+
)
94+
np.testing.assert_allclose(test_weights, expected_weights)

0 commit comments

Comments
 (0)