Skip to content

Fix multivariate default n_best scaling and mirror R's dependence tryCatch chain - #85

Merged
OVVO-Financial merged 2 commits into
mainfrom
claude/inference-comparison-4vlt4q
Jul 13, 2026
Merged

Fix multivariate default n_best scaling and mirror R's dependence tryCatch chain#85
OVVO-Financial merged 2 commits into
mainfrom
claude/inference-comparison-4vlt4q

Conversation

@OVVO-Financial

Copy link
Copy Markdown
Owner

Changes

Two fixes to keep order=None behavior exact against R NNS, verified with a live R 4.3.3 + NNS 13.1 build:

1. _resolve_n_best: scale default n_best by sqrt(n_obs), not sqrt(n_features) (multivariate_regression.py)

The default n_best = max(1, floor((1-dependence)*sqrt(x.shape[1]))) mirrored R's Multivariate_Regression.R:129, where n is shadowed by ncol(original.IVs). With sqrt(#features) ≤ 2.24, the default collapsed to n_best = 1 for any dependence above ~0.1, making order=None predictions identical to order="max" (pure 1-NN) on continuous multivariate data. Now uses sqrt(x.shape[0]), consistent with the sqrt(n_obs) grid nns_stack already cross-validates over. Companion R PR: OVVO-Financial/NNS#39.

2. _regression_dependence: mirror R's tryCatch fallback around NNS.dep (regression.py)

R wraps the NNS.dep call in tryCatch(..., error = function(e) .1) before averaging with the copula measure; the port only guarded the copula half. The order=NULL dependence chain is now a literal transcription of the R block.

Verification

  • order=None ≠ order="max": max abs diff 2.539 on 200×5 shared test data, identical value in both languages; previously bit-identical predictions.
  • Cross-language sweep (9 datasets, n=50–500, spanning n<100 halving, weak/strong dependence, dependence==1): NNS.dep and NNS.copula components bit-identical (≤6e-16), composed dependence within 1 ulp, all 9/9 resolved dep.reduced.order values equal for order=None and integer overrides.
  • Integer order parity: univariate regression point counts (3/5/11/200/19 for order 1/2/4/max/None) and multivariate estimate diffs (4.74844/2.92378/0/0 vs "max") match live R digit-for-digit.
  • Point-estimate parity post-fix: 59/60 rows bit-exact vs patched R; the remaining row is the out-of-support gradient-extension path (diff 3.4e-3).
  • Full suite: 2226 passed, 12 skipped — no recorded R-parity case affected (all cached multivariate fixtures resolve to n_best=1 under both formulas).
  • Benchmark effect (5 seeds × 3 regimes, n_train=500): default nns_reg RMSE improves iid 1.39→1.12, support_shift 2.22→2.07, prior_trap 1.58→1.25.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BPbZvtDw4h2XJo9w5hw57h


Generated by Claude Code

claude added 2 commits July 13, 2026 01:05
The default n.best in nns_m_reg used floor((1-dependence)*sqrt(ncol)),
mirroring R's Multivariate_Regression.R:129 where n is shadowed by
ncol(original.IVs). With sqrt(#features) <= 2.24 for typical widths,
the default collapsed to n.best = 1 for any dependence above ~0.1,
making order=None predictions identical to order="max" (pure 1-NN) on
continuous multivariate data.

Use sqrt(nrow) instead, consistent with the sqrt(n_obs) grid nns_stack
already cross-validates over. Verified against a live patched R NNS
13.1 build on shared data: order=None now differs from order="max"
identically in both languages (59/60 test rows bit-exact, remaining row
is the out-of-support gradient-extension path). Full test suite passes;
no recorded R-parity case is affected because all cached multivariate
fixtures resolve to n.best = 1 under both formulas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BPbZvtDw4h2XJo9w5hw57h
R Regression.R wraps the NNS.dep call in tryCatch with a 0.1 fallback
before averaging with the copula measure; the port only guarded the
copula half. Wrap the nns_dep call the same way so the order=NULL
dependence chain is a literal transcription of the R block.

Verified against live R NNS 13.1 on nine datasets spanning n<100 and
n>=100: NNS.dep and NNS.copula components bit-identical, composed
dependence within 1 ulp, and every resolved dep.reduced.order equal
(order=NULL and integer overrides).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BPbZvtDw4h2XJo9w5hw57h
@OVVO-Financial
OVVO-Financial merged commit 80c6c6c into main Jul 13, 2026
8 checks passed
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