Skip to content

Fix NNS.dep/NNS.copula independence anchor (discordant partial moment) - #117

Merged
OVVO-Financial merged 10 commits into
mainfrom
claude/nns-python-v1.3-release-in5n5t
Jul 14, 2026
Merged

Fix NNS.dep/NNS.copula independence anchor (discordant partial moment)#117
OVVO-Financial merged 10 commits into
mainfrom
claude/nns-python-v1.3-release-in5n5t

Conversation

@OVVO-Financial

Copy link
Copy Markdown
Owner

Python port of OVVO-Financial/NNS#49 (merged).

Problem

nns_dep reported a large, non-vanishing dependence for independent data (≈0.60 at n=100, still ~0.44 as n→∞). A consistent dependence measure must decay to 0 under independence.

Root cause

The copula blends four normalized deviations from an independence anchor. Measured at n=200k (sampling noise → 0):

term true indep. null old anchor residual
discrete concordance 0.500 0.50 0
continuous concordance 0.500 0.50 0
discrete discordance (DPM) 0.500 0.75
continuous discordance (DPM) 0.500 0.75

DPM_nD counts a point concordant when it is all-below OR all-above the target — both fully-aligned orthants — so under independence P(discordant) = 1 − 2·0.5ⁿ (0.5 bivariate), not 1 − 0.5ⁿ = 0.75. The mismatch leaves ⅓ in each discordant term, and the final sqrt turns it into a permanent floor: sqrt(1/6) ≈ 0.41.

Fix

indep_D = 1 − 2·0.5ⁿ (→ 0.5 bivariate), in all four implementations:

  • src/nns/dependence.py_copula_signed, _copula_degree0_unsigned
  • src/nns/copula.py — n-dimensional nns_copula
  • src/nns/_nnscore_bindings.cpp — native bivariate (×3) and nD copula

The concordance anchor was already correct at 0.5 and is unchanged.

Effect (native-validated)

Independent dependence now decays toward 0 instead of plateauing:

n old fixed
1000 0.48 0.33
5000 0.44 0.22

Discrimination preserved: identical/linear = 1.00, quadratic = 0.99. Adds test_nns_dep_independence_null_is_consistent, which only passes under the corrected anchor.

⚠️ Parity cache must be regenerated

This intentionally changes every nns_dep/nns_copula value, so the committed tests/_r_cache.json (old-anchor R references) is stale and the tests/parity/test_dependence.py / test_copula.py suites will fail until it is regenerated against the fixed R NNS (#49):

python scripts/regenerate_r_cache.py --fresh

Cross-check already in hand: when #49's CI ran R CMD check, R produced copula fixtures B=0.2554, C=0.2000, D=0.2470, E=0.2000 — matching this fixed port exactly on the same inputs, confirming R↔Python parity under the new anchor.

🤖 Generated with Claude Code


Generated by Claude Code

claude and others added 10 commits July 14, 2026 13:24
…ents

Mirrors OVVO-Financial/NNS#49. The discordant partial moment (DPM_nD)
treats a point as concordant when it is all-below OR all-above the target
-- both fully-aligned orthants -- so under independence P(discordant) is
1 - 2*0.5**n, which is 0.5 for the bivariate copula, not 1 - 0.5**n = 0.75.

The old 0.75 anchor left a fixed 1/3 residual in each of the two discordant
terms, so sqrt(mean(0, 0, 1/3, 1/3)) = sqrt(1/6) ~ 0.41: a dependence floor
that never vanished for independent data regardless of sample size.
Correcting the anchor to 1 - 2*0.5**n makes the measure consistent --
independent data now decays toward 0 as n grows -- while leaving perfectly
dependent cases at 1.

Changed the bivariate kernels (_copula_signed, _copula_degree0_unsigned in
both the Python fallback and the native _nnscore bindings; anchor 0.5) and
the n-dimensional nns_copula (copula.py and native; 1 - 2*0.5**n). The
concordance anchor was already correct at 0.5 and is unchanged. Adds a
consistency invariant that only holds under the corrected anchor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019F6ZjcfXSxZWGMuSmQGmLN
regenerate_r_cache.py installs R NNS from the vendored tools/NNS/ source,
so it must carry the same indep_D fix (0.75 -> 0.5 in NNS_dep.cpp, and
1-(0.5^n) -> 1-2*(0.5^n) in Copula.R) for the regenerated parity cache to
reflect the corrected R behavior. Mirrors OVVO-Financial/NNS#49.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019F6ZjcfXSxZWGMuSmQGmLN
@OVVO-Financial
OVVO-Financial merged commit 65da6be into main Jul 14, 2026
0 of 8 checks passed
@OVVO-Financial
OVVO-Financial deleted the claude/nns-python-v1.3-release-in5n5t branch July 14, 2026 17:45
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.

2 participants