Skip to content

stats: longest-prefix factor attribution; a colon inside a level is not an interaction - #37

Open
ChrisW09 wants to merge 1 commit into
mainfrom
fix/term-attribution
Open

stats: longest-prefix factor attribution; a colon inside a level is not an interaction#37
ChrisW09 wants to merge 1 commit into
mainfrom
fix/term-attribution

Conversation

@ChrisW09

Copy link
Copy Markdown
Collaborator

Fixes #7.

Bug 1 — first-prefix attribution. ordinal.py and logistic.py attributed a coefficient to next((f for f in factors if term.startswith(f)), None). With factors ["retrieve", "retrieve.top_k"] (the shape the codebase's own test_readable_clmm_term treats as real), the R term retrieve.top_k2 was attributed to retrieve — so significant_factors reported the wrong factor while the row's label said retrieve.top_k=2. Both files now use a shared _term_factor (longest prefix), matching _readable_term's existing rule.

Bug 2 — colon inside a level. Every : was treated as R's interaction separator, but ollama-style levels (model="llama3:8b") put colons inside the coefficient name (modelllama3:8b). Verified effects: main effects flagged interaction=True, labels garbled to model=llama3 × 8b, and the statsmodels path emitted raw patsy junk with factor=None. Fixes:

  • R terms: _split_r_term treats : as a separator only when every piece starts with a known factor name (a heuristic — the robust long-term fix is for clmm.R/glmm.R to emit structured per-coefficient factor+level, noted in the docstring).
  • statsmodels terms: _parse_statsmodels_term now matches the C(Q(…))[T.…] groups with finditer instead of pre-splitting on :, so a colon inside [T.llama3:8b] is naturally part of the level.

Regression tests cover longest-prefix attribution, both split behaviors, readable labels, and the statsmodels main-effect/interaction cases. The existing test_readable_clmm_term still passes unchanged.

Test: full cafe-core suite — 110 passed (1 pre-existing failure = #4, fix in PR #34).

🤖 Generated with Claude Code

…rsing

- factor attribution used the FIRST factor whose name prefixes the
  coefficient term, so with factors like ['retrieve', 'retrieve.top_k']
  the term 'retrieve.top_k2' was attributed to 'retrieve' — reporting
  the wrong factor in significant_factors while the label (which already
  used longest-prefix) said retrieve.top_k=2. Now longest prefix wins,
  via a shared _term_factor helper.
- every ':' in a term was treated as R's interaction separator, but a
  ':' can appear inside a level (model='llama3:8b' -> coefficient
  'modelllama3:8b'). Main effects were flagged as interactions, labels
  garbled to 'model=llama3 × 8b', and the statsmodels path produced raw
  patsy junk with factor=None. R terms now split on ':' only when every
  piece starts with a known factor (_split_r_term); statsmodels terms
  are parsed by matching the C(Q('...'))[T....] groups directly instead
  of pre-splitting.

Fixes #7

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stats: CLMM/GLMM coefficient→factor attribution uses first-prefix match; colons in factor levels parse as interactions

1 participant