Skip to content

int/ #135–#139 together for testing (not for merging) - #140

Draft
ellispatrick wants to merge 16 commits into
review/9-coxnet-pathfrom
review/integration
Draft

ellispatrick wants to merge 16 commits into
review/9-coxnet-pathfrom
review/integration

Conversation

@ellispatrick

Copy link
Copy Markdown
Member

For testing only, not for merging. Holds #135, #136, #137, #138 and #139 together on top of #134, as #125 does for #126–#134. The later stacked PRs (defaults and dependencies, classifier registry, new classifiers) are based on this branch.

What it contains

PR Branch Contents
#136 review/10-metrics-defaults metrics and plots (Q6–Q12, Q19)
#135 review/11-classifier-fixes classifier fixes (Q13, Q22–Q24, Q26)
#137 review/12-speed-defaults speed and defaults (Q1, Q2, Q5, Q15, Q25, Q31, Q32)
#139 review/13-glm-cv-lambda penalised GLM chooses lambda by cross-validation (Q14)
#138 review/14-crossvalidate-null-outcome prepareData stops on a NULL or empty outcome

Decisions: ProjectClassifyR docs/DECISIONS.md, 10 October 2026.

Conflicts resolved

Evidence

🤖 Generated with Claude Code

https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4

ellispatrick and others added 16 commits October 14, 2026 10:49
…tion forest instead of growing a second forest (changes rankings)

Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 10 Oct 2026, Q1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
… split by default, as ranger and randomForestSRC do (changes results)

mTryProportion still sets a proportion when given. Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md,
10 Oct 2026, Q2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…d of a multinomial one (changes predictions slightly)

Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 10 Oct 2026, Q31).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…features at once

Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 10 Oct 2026, Q25). Rankings are the same except that
features whose statistics differ only by rounding error can swap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 10 Oct 2026, Q32).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…use the selection in every combination containing it (identical results)

With shared folds, an assay's selection in a split is the same in every combination of assays. The selection is
reused only for identical data, outcome and settings; one that draws random numbers is reused only from the same
random number state, which is then advanced as selecting again would. Decided by Ellis Patrick (ProjectClassifyR
DECISIONS.md, 10 Oct 2026, Q5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…ches, previousSelection, ensemble selection, resubstitution warning

- naiveBayesKernel: crossover points use the class densities scaled by class size, the same densities as the
  vertical distances (changes results with weighting = "crossover distance").
- fisherDiscriminant: the score is centred on the critical value, so its sign gives the predicted class and scores
  from different fold models are comparable (classes unchanged).
- kNNinterface (weighted): training samples at distance zero alone vote, equally, instead of a weight of 999999.
- previousSelection matches the original feature names; SelectParams passes .iteration to it automatically.
  prepareData makes safe feature names unique, so "a-b" and "a.b" no longer collide.
- .doSelection: ensemble selection (a list of ranking functions) works, with tuning of the number of features.
- runTests warns once when resubstitution tuning finds several numbers of features with a perfect training fit.

Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 2026-10-10, Q13, Q22-Q24, Q26).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…rouping for every metric, chance line per metric (changes results)

Decisions by Ellis Patrick, 10 Oct 2026 (ProjectClassifyR docs/DECISIONS.md, QUESTIONS.md Q6-Q12, Q19):
- AUC, the sample-wise C-index, crissCrossValidate's matrices and runTest's variable importance are no longer
  rounded; plots round only their labels.
- The sample-wise C-index counts a pair with tied risk scores as half concordant, as the C-index does.
- grouping = "fold" averages every class metric (e.g. Balanced Accuracy) within each permutation, as it already did
  for AUC and C-index.
- Macro precision and F1 count a never-predicted class as precision 0 instead of returning NaN.
- AUC of a group lacking a sample of some class is NaN with a warning, instead of an error.
- performancePlot's chance line is the metric's value under uniformly random predictions (1/k, 1 - 1/k, 0.5 or 0),
  and is omitted for metrics without one.
- rankingPlot divides the overlap by the length of the shorter list of top features; the overlap plots' axis labels
  say what they measure ("Top Features in Common", "Jaccard Similarity").
- crissCrossPlot hides the diagonal by default for both training types; showDiagonal = TRUE shows it
  (showResubMetric is deprecated).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…rially, without fitting an unused model of all training samples (changes results of nested tuning)

The inner cross-validation used to repeat the outer scheme (by default 20 x 5 per tuning value) with the outer
parallel back-end, and fitted a final model it never used. CrossValParams gains innerPermutations and innerFolds.
Decided by Ellis Patrick (ProjectClassifyR DECISIONS.md, 10 Oct 2026, Q15).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…bdas at which any class has a coefficient (changes results)

Why: resubstitution chooses lambdas close to the unpenalised end of the path (10-30x smaller than
cross-validation on the protocol data), which overfits larger cohorts: PROMAD GSE48581 (262 samples)
kept 53 features with balanced accuracy 0.638, against 18 features and 0.713 with cross-validation.
Over 11 data sets and views (asthma, Procedures 1, 3 and 4; 20 x 5 CV) the mean balanced accuracy
changes by +0.002 and the AUC by -0.006, models keep about 40% fewer features, and runs take 1.0-1.7x
as long (seconds). The inner folds are stratified by class, use the same path and class weights as the
fit, and measure the class-weighted misclassification, which is the balanced error.
extraParams = list(train = list(lambdaTuning = "resubstitution")) gives the previous choice exactly;
nFoldsLambda sets the number of folds. With a class of fewer than three training samples, lambda is
chosen by resubstitution with a warning.
The lambda filter used the signed sum of the first class's coefficients, so for three or more classes
it dropped lambdas at which only that class's coefficients were zero, and the choice depended on the
order of the factor levels; a path made only of such lambdas was an error. Every class is now
considered. Two-class results are unchanged by this part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…selection does

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
Why: an outcome of NULL (e.g. from outcomes[[name]] with a name the list doesn't have) passed every check,
and each fold then failed inside feature selection, so crossValidate stopped with "All cross-validations
had an error. The common problem is: argument 1 is not a vector", which doesn't point to the cause.
Found with the protocol's PROMAD data, whose outcome list is named Counts_<cohort>_Biopsy_ABMR.csv while
its measurement list is named <cohort>. prepareData, which crossValidate calls for matrix and DataFrame
input, now stops with "'outcome' is missing or empty".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4
…d lambda with the binomial model for two classes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfsjwkbDbHkX4kJZNe4ER4

This branch has not been deployed

No deployments
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.

1 participant