lnccbrown / lnccbrown/HSSM

Lapse choice component is not normalised on observed and choice-only rows

Open
#1,323 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
124
Forks
24
Avg merge
19h 32m
Merged PRs (30d)
60

Description

## Describe the bug

Companion to the missing-row lapse issue. For the mixture `f(rt, c) = (1-p)·s(rt, c) + p·l(rt)·q(c)` to be a density on `(0, ∞) × choices`, the lapse component needs a choice distribution `q(c)` (uniform, `1/n_choices`). Two places omit it:

1. **Observed rows** (`src/hssm/distribution_utils/dist.py`, the mixture block ~L615-634): the lapse term is `l(rt)` with no `1/n_choices`, so the lapse component carries mass `n_choices` and the mixture integrates to `1 + (n-1)·p` instead of 1. The effect is absorbed into `p_outlier`'s scale: a fitted or fixed `p_outlier = p` behaves like a proper mixture with lapse weight `≈ n·p` — for two-choice models the default 0.05 is effectively ≈ 0.10.
2. **Choice-only models**: `src/hssm/base.py` (`_check_lapse`) sets `self.lapse = 1 / self.n_choices` and `dist.py` (`lapse_func = lambda data: np.full_like(data, lapse)`) returns that value where a *log*-probability is expected, so the mixture uses `exp(1/n)` (≈ 1.65 for n = 2) instead of `1/n`.

## Expected behavior

Observed rows: lapse term `l(rt)/n_choices`. Choice-only rows: lapse term `log(1/n_choices)`. Then `∫_0^∞ Σ_c f(rt, c) drt = 1` for any `p`.

This changes every existing fit's `p_outlier` scale (by ≈ `n_choices`), so it needs a changelog migration note and a minor release rather than a patch.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the mixture block around lines 615–634 in src/hssm/distribution_utils/dist.py, then read _check_lapse in src/hssm/base.py and the choice-only lapse_func. Verify the observed and choice-only mixture terms have the expected probability normalization for any p and n_choices. Done includes the requested changelog migration note and minor-release treatment for the changed p_outlier scale.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
backend, data
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.