Computes type-specific performance metrics for each trait. By default
the model is evaluated on the test split stored in the fit object. An
alternative data can provide the truth matrix, and alternative
splits can select compatible held-out cells from the original fit;
evaluation does not refit the baseline or GNN for a new holdout design.
Arguments
- fit
pigauto_fit object.
- data
pigauto_data object (default:
NULL, uses the training data stored in the fit viapredict()).- splits
splits object (default:
NULL, usesfit$splits). Alternative indices must be a compatible subset of the cells held out when the fit was made; this argument does not refit for a new holdout design.
Details
Metrics by trait type:
- continuous
RMSE, Pearson r, and MAE on the z-scored latent scale
- count
RMSE, MAE, and Pearson r on the z-scored log1p latent scale
- binary
Accuracy, Brier score
- categorical
Accuracy (overall)
- ordinal
RMSE on the z-scored latent scale, Spearman rho
- proportion
RMSE and MAE on the transformed latent scale, Pearson r
- zi_count
RMSE, MAE, and Pearson r on the original count scale, comparing observed counts with predicted expected counts; zero-accuracy and Brier score are computed for the zero/nonzero gate
- multi_proportion
Aitchison distance in CLR space, z-scored CLR RMSE, and decoded simplex MAE
When conformal scores are present in the fit, conformal_coverage_95
is reported for continuous, count, ordinal, and proportion traits. This is
the empirical fraction of test predictions inside the same trait-level
conformal radius around each prediction. It uses one score per trait, not
cell-specific or Mondrian bounds.
Cross-validation and model reports can also report coverage of their
actual per-cell bounds.
When the fit includes a baseline, baseline metrics are appended with
method = "baseline" for direct comparison. This uses the baseline
already stored in the fit and its selected defaults; evaluate() has
no argument for alternative baseline settings. To compare another
baseline, construct it explicitly in a separate evaluation workflow.
Examples
# \donttest{
data(avonet300, tree300)
tree <- ape::keep.tip(tree300, tree300$tip.label[seq_len(30L)])
traits <- avonet300[match(tree$tip.label, avonet300$Species_Key),
c("Mass", "Wing.Length"), drop = FALSE]
rownames(traits) <- tree$tip.label
pd <- preprocess_traits(traits, tree)
splits <- make_missing_splits(pd$X_scaled, trait_map = pd$trait_map)
fit <- fit_pigauto(pd, tree, splits = splits, epochs = 5L,
verbose = FALSE)
#> Warning: Small validation set for 2 trait(s): Mass (n=1), Wing.Length (n=2). Calibrated gate and conformal scores will be noisy for these trait(s). 95% split-conformal coverage is NOT achievable for 2 trait(s) with fewer than 19 validation cells (Mass (n=1), Wing.Length (n=2)): the achievable ceiling is n_val / (n_val + 1), which only reaches 0.95 at n_val >= 19. See `?fit_pigauto` under 'Calibration at small n' for smoothing options.
eval_df <- evaluate(fit)
eval_df[eval_df$metric == "rmse", ]
#> method trait type metric value n_test
#> 1 pigauto Mass continuous rmse 0.2115063 8
#> 5 pigauto Wing.Length continuous rmse 0.4305777 4
#> 9 baseline Mass continuous rmse 0.2115063 8
#> 12 baseline Wing.Length continuous rmse 0.4305777 4
# }
