|
| 1 | +# Sufficiency diagnostics |
| 2 | + |
| 3 | +Parameters of fit summarise a solution in a few numbers. They do not say which |
| 4 | +cases produced those numbers — and that is usually the question you actually |
| 5 | +have. Which cases support this path? Which contradict it? Which outcomes does it |
| 6 | +fail to explain? |
| 7 | + |
| 8 | +```python |
| 9 | +from setqca import sufficiency_diagnostics |
| 10 | + |
| 11 | +diagnostics = sufficiency_diagnostics( |
| 12 | + data, |
| 13 | + outcome="SURV", |
| 14 | + terms=["DEV*URB*LIT*IND*STB", "DEV*~URB*LIT*~IND*STB"], |
| 15 | +) |
| 16 | +print(diagnostics) |
| 17 | +print(diagnostics.to_frame()) |
| 18 | +print(diagnostics.cases_frame()) |
| 19 | +``` |
| 20 | + |
| 21 | +Terms are given as expression strings and parsed, so a solution can be pasted |
| 22 | +straight in. Case labels come from the frame index by default, or from a column |
| 23 | +you name — no particular schema is assumed. |
| 24 | + |
| 25 | +## The case typology |
| 26 | + |
| 27 | +For a term `X` and outcome `Y`, with the crossover at 0.5: |
| 28 | + |
| 29 | +| Membership | Role | What it means | |
| 30 | +| --- | --- | --- | |
| 31 | +| `X > 0.5`, `Y > 0.5`, `X ≤ Y` | **typical** | Supports the claim. These are the cases to study for the mechanism. | |
| 32 | +| `X > 0.5`, `Y > 0.5`, `X > Y` | **deviant consistency (degree)** | Right corner, wrong magnitude — more in the term than in the outcome. | |
| 33 | +| `X > 0.5`, `Y ≤ 0.5` | **deviant consistency (kind)** | The term holds and the outcome does not. This is the case-level contradiction. | |
| 34 | +| `X ≤ 0.5`, `Y > 0.5` | **deviant coverage** | An outcome this term does not explain. | |
| 35 | +| `X ≤ 0.5`, `Y ≤ 0.5` | **individually irrelevant** | Outside both sets. | |
| 36 | + |
| 37 | +```python |
| 38 | +term = diagnostics.terms[0] |
| 39 | +term.typical # ('BE', 'CZ', 'NL') |
| 40 | +term.contradictory # cases where the term holds but the outcome does not |
| 41 | +term.deviant_coverage # outcomes this term misses |
| 42 | +term.deviant_consistency # both kinds of consistency deviance |
| 43 | +term.uniquely_covered # cases no other term reaches |
| 44 | +``` |
| 45 | + |
| 46 | +!!! note "Only consistency deviance counts against the claim" |
| 47 | + A deviant-coverage case is not evidence against sufficiency. It says the |
| 48 | + outcome occurred through some other path, which is exactly what a |
| 49 | + disjunctive solution expects. `CaseRole.contradicts_sufficiency` encodes |
| 50 | + the distinction. |
| 51 | + |
| 52 | +## Unique coverage |
| 53 | + |
| 54 | +Raw coverage counts the outcome membership a term accounts for. **Unique** |
| 55 | +coverage counts only what no other term accounts for: |
| 56 | + |
| 57 | +```text |
| 58 | +covU_i = [ Σ min(Xᵢ, Y) − Σ min(Xᵢ, max_{j≠i} Xⱼ, Y) ] / Σ Y |
| 59 | +``` |
| 60 | + |
| 61 | +A term with substantial raw coverage but near-zero unique coverage is redundant |
| 62 | +in practice — drop it and the same cases are still explained: |
| 63 | + |
| 64 | +```python |
| 65 | +diagnostics.redundant_terms |
| 66 | +``` |
| 67 | + |
| 68 | +Two identical terms each have unique coverage of exactly zero, which is the |
| 69 | +degenerate case the property makes obvious. |
| 70 | + |
| 71 | +!!! info "A small divergence from R" |
| 72 | + R reports `covU` as `NA` for a single-term solution, since there is no other |
| 73 | + term to be unique against. `setqca` reports the raw coverage instead: with |
| 74 | + nothing to share with, everything the term covers is uniquely covered by it. |
| 75 | + Verified against R for every multi-term solution on the Lipset data. |
| 76 | + |
| 77 | +## Reading R's `cases` column |
| 78 | + |
| 79 | +R's per-term `cases` column lists cases whose membership in the term exceeds the |
| 80 | +crossover. The typology splits that same set further, so R's list corresponds to |
| 81 | +**typical plus deviant-in-degree**, not to typical alone. |
| 82 | + |
| 83 | +On the Lipset conservative solution R lists `BE, CZ, NL, UK` for the first term. |
| 84 | +`setqca` agrees on all four being in the term, and additionally reports that UK |
| 85 | +is deviant in degree — its membership in the term exceeds its membership in the |
| 86 | +outcome. That distinction is the point of the typology, and it is not visible |
| 87 | +from the `cases` column alone. |
| 88 | + |
| 89 | +## Choosing cases to study |
| 90 | + |
| 91 | +The typology exists to support case selection in multi-method work: |
| 92 | + |
| 93 | +- **Typical** cases are where the proposed mechanism should be visible. |
| 94 | +- **Deviant consistency** cases are where it should be visible and is not — the |
| 95 | + most informative cases for revising the theory. |
| 96 | +- **Deviant coverage** cases point at paths the solution is missing. |
| 97 | +- **Uniquely covered** cases are the ones that justify keeping a term at all. |
| 98 | + |
| 99 | +::: setqca.analysis.sufficiency |
0 commit comments