| Title: | Evidence Workflows for Self-Organizing Map Classification |
|---|---|
| Description: | Provides explicit data-design objects, leakage-safe preprocessing, design-aware resampling, reproducible ensembles of self-organizing maps, and evidence-oriented diagnostics for ecological, environmental and evolutionary applications. The package separates continuous-representation diagnostics from the defensibility of a hard partition and supports explicit abstention when evidence is insufficient. Self-organizing maps follow Kohonen (1982) <doi:10.1007/BF00337288>, using the 'kohonen' implementation described by Wehrens and Kruisselbrink (2018) <doi:10.18637/jss.v087.i07>. |
| Authors: | Shaowen Ye [aut, cre] |
| Maintainer: | Shaowen Ye <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.2.0 |
| Built: | 2026-10-11 14:54:24 UTC |
| Source: | https://github.com/shaowen-ye/SOMevidence |
In addition to analyst-defined thresholds, the assessment checks that every
source partition and the consensus retain the requested k, and that all
requested cross-model fits succeeded. Missing audit evidence produces an
uncertain result rather than being treated as a pass.
assess_defensibility( audit, partitions = NULL, k = NULL, gate = NULL, consensus = NULL, cross_model = NULL )assess_defensibility( audit, partitions = NULL, k = NULL, gate = NULL, consensus = NULL, cross_model = NULL )
audit |
A |
partitions |
Optional |
k |
Candidate number of clusters when partition stability is assessed. |
gate |
Optional analyst-defined |
consensus |
Optional |
cross_model |
Optional |
A "supported" status means only that the analyst-specified evidence
requirements and structural completeness checks were met for the stated
data, analysis design, preprocessing, model budget and candidate k. It does
not demonstrate that discrete ecological types exist, identify a causal
mechanism, or establish ecological truth.
A representation audit alone cannot support a hard partition. A supported
decision also requires traceable comparative partition evidence and at
least one prespecified partition-quality requirement. Missing evidence or a
representation-only gate produces an "uncertain" result.
A som_defensibility object containing evidence and reasons.
Audit representation quality across a SOM ensemble
audit_som(ensemble)audit_som(ensemble)
ensemble |
A fitted |
A som_audit object containing fit-level metrics and summaries.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 1) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) audit_som(fit_som_ensemble(data, specification, keep_models = FALSE))data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 1) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) audit_som(fit_som_ensemble(data, specification, keep_models = FALSE))
Computes scope-specific representation diagnostics and compares the topology induced by prespecified pairs of SOM fits. Pairwise evidence uses shortest-hop distances on each SOM grid, so no node labels or map orientations are forced into correspondence. All calculations are exact under explicit fit-pair and sample-pair budgets.
audit_som_representation( ensemble, scope = c("analysis", "assessment"), neighbourhood_size = NULL, pairs = NULL, max_pairwise_comparisons = 10000L, max_sample_pairs = 1000000L, fail_fast = FALSE )audit_som_representation( ensemble, scope = c("analysis", "assessment"), neighbourhood_size = NULL, pairs = NULL, max_pairwise_comparisons = 10000L, max_sample_pairs = 1000000L, fail_fast = FALSE )
ensemble |
A fitted |
scope |
Rows compared within each fit: |
neighbourhood_size |
Optional positive integer |
pairs |
Optional prespecified data frame with |
max_pairwise_comparisons |
Maximum number of fit pairs. The function stops before dense topology calculations when this budget is exceeded. |
max_sample_pairs |
Maximum total number of unordered jointly mapped sample pairs across all requested fit comparisons. |
fail_fast |
Whether to stop at the first metric-computation error. |
This experimental audit concerns continuous representation, not the
defensibility of a hard partition. It supplies no score, ranking, automatic
threshold or decision status and is not accepted by assess_defensibility().
A som_representation_audit object with fit metrics, pairwise
topology reproducibility, optional sample-neighbourhood records,
descriptive summaries, computation budgets, provenance, warnings and
failures. Sample pairs and fit pairs are not treated as independent
inferential replicates.
data <- simulate_som_scenario("gradient", n = 45, p = 3, seed = 21) ensemble <- fit_som_ensemble( data, som_spec(c(3, 2), seeds = 22:23, rlen = 10, k = 2), keep_models = FALSE ) audit_som_representation(ensemble, neighbourhood_size = 5)data <- simulate_som_scenario("gradient", n = 45, p = 3, seed = 21) ensemble <- fit_som_ensemble( data, som_spec(c(3, 2), seeds = 22:23, rlen = 10, k = 2), keep_models = FALSE ) audit_som_representation(ensemble, neighbourhood_size = 5)
For each successful fit with assessment rows, the function contrasts mapping error in the analysis and assessment sets and records the fraction of held- out samples mapped to units unoccupied during training. These quantities describe domain shift; they do not establish ecological transferability on their own.
audit_transfer(ensemble)audit_transfer(ensemble)
ensemble |
A fitted |
A som_transfer_audit object with fit-level transfer diagnostics.
data <- simulate_som_scenario("gradient", n = 60, p = 3, seed = 7) splits <- som_resamples(data, method = "leave_domain_out") specification <- som_spec(c(3, 2), seeds = 1, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, splits) audit_transfer(ensemble)data <- simulate_som_scenario("gradient", n = 60, p = 3, seed = 7) splits <- som_resamples(data, method = "leave_domain_out") specification <- som_spec(c(3, 2), seeds = 1, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, splits) audit_transfer(ensemble)
Compare SOM partitions with controlled cross-model references
compare_cross_models( partitions, cross_models, scope = c("analysis", "assessment", "all") )compare_cross_models( partitions, cross_models, scope = c("analysis", "assessment", "all") )
partitions |
A |
cross_models |
A |
scope |
Compare analysis rows ( |
A som_cross_comparison containing ARI and AMI effect sizes,
summaries, reference-fit success rates, source-partition completeness and
source-partition provenance. Neither agreement metric is reported as
accuracy.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 5) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) partitions <- partition_som(ensemble) references <- fit_cross_models(ensemble, methods = "ward") compare_cross_models(partitions, references)data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 5) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) partitions <- partition_som(ensemble) references <- fit_cross_models(ensemble, methods = "ward") compare_cross_models(partitions, references)
Partitions with the same k are compared through sample co-assignment.
Labels are aligned to the consensus partition only after fitting. This label
alignment does not align SOM nodes and must not be used to force maps with
different grids into a common node geometry.
consensus_som( partitions, k, linkage = "average", method = c("auto", "coassignment", "aligned_vote"), max_coassignment_n = 5000L )consensus_som( partitions, k, linkage = "average", method = c("auto", "coassignment", "aligned_vote"), max_coassignment_n = 5000L )
partitions |
A |
k |
Number of clusters to audit. |
linkage |
Linkage used to partition the sample co-assignment matrix. |
method |
Consensus algorithm. |
max_coassignment_n |
Largest sample count for an automatically created dense co-assignment matrix. Set this deliberately because memory grows quadratically with sample count. |
A som_consensus object containing aligned assignments,
partition-assignment, consensus-label and replicated
coverage, membership support, assignment entropy and clusterwise Jaccard
values. The object also records whether the consensus itself retains all
requested clusters and retains the originating partition method as
provenance. For co-assignment consensus, coassignment and tree contain
the dense matrix and its hierarchical clustering; both are NULL for
aligned voting. Aligned voting avoids quadratic growth in sample count, but
alignment and upstream partition auditing can still grow quadratically in
the number of ensemble members.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 3) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) consensus_som(partition_som(ensemble), k = 2)data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 3) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) consensus_som(partition_som(ensemble), k = 2)
External labels are evaluated only after SOM fitting and consensus construction. ARI and AMI quantify agreement; neither is called accuracy, and agreement does not make the external labels ecological ground truth.
evaluate_external_labels( consensus, labels = NULL, exclude = NULL, label_ids = NULL, match_by = c("auto", "id", "position") )evaluate_external_labels( consensus, labels = NULL, exclude = NULL, label_ids = NULL, match_by = c("auto", "id", "position") )
consensus |
A |
labels |
Optional external labels. By default, the |
exclude |
Optional label values to omit, such as an explicit unknown category. Missing labels and samples without at least two analysis-scope assignments are always omitted and counted because one assignment cannot provide consensus evidence. |
label_ids |
Optional unique sample identifiers corresponding to
|
match_by |
Matching rule. |
A som_external_assessment object containing the contingency table,
long-form cluster composition, ARI, AMI, resolved matching information and
mutually exclusive sample-omission accounting.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 9) ensemble <- fit_som_ensemble( data, som_spec(c(3, 2), seeds = 10:11, rlen = 10, k = 2) ) consensus <- consensus_som(partition_som(ensemble), k = 2) labels <- stats::setNames( data$metadata$external_label, data$metadata$id ) evaluate_external_labels(consensus, labels[sample(names(labels))])data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 9) ensemble <- fit_som_ensemble( data, som_spec(c(3, 2), seeds = 10:11, rlen = 10, k = 2) ) consensus <- consensus_som(partition_som(ensemble), k = 2) labels <- stats::setNames( data$metadata$external_label, data$metadata$id ) evaluate_external_labels(consensus, labels[sample(names(labels))])
Expand an ensemble specification into its model budget
expand_som_spec(spec)expand_som_spec(spec)
spec |
A |
A data frame with one row per grid and random seed.
expand_som_spec(som_spec(c(4, 3), seeds = 1:3, rlen = 20, k = 2:3))expand_som_spec(som_spec(c(4, 3), seeds = 1:3, rlen = 20, k = 2:3))
K-means, Ward.D2 and Gaussian mixture models use the same data object, resampling indices and leakage-safe preprocessing as a fitted SOM ensemble. The function creates reference partitions for triangulation; it does not rank algorithms or define any method as ground truth.
fit_cross_models( ensemble, methods = c("kmeans", "ward"), k = ensemble$spec$k, kmeans_seeds = 1L, kmeans_nstart = 50L, kmeans_iter_max = 100L, gmm_model_names = NULL, keep_models = FALSE, fail_fast = FALSE, gmm_seed = 1L )fit_cross_models( ensemble, methods = c("kmeans", "ward"), k = ensemble$spec$k, kmeans_seeds = 1L, kmeans_nstart = 50L, kmeans_iter_max = 100L, gmm_model_names = NULL, keep_models = FALSE, fail_fast = FALSE, gmm_seed = 1L )
ensemble |
A fitted |
methods |
Any of |
k |
Candidate numbers of clusters. |
kmeans_seeds |
Random seeds used only for K-means initialization. |
kmeans_nstart |
Number of random starts per K-means fit. |
kmeans_iter_max |
Maximum number of iterations per K-means start. |
gmm_model_names |
Optional covariance models passed to
|
keep_models |
Whether to retain fitted cross-model objects. |
fail_fast |
Whether to stop at the first fit failure. |
gmm_seed |
Base random seed for reproducible GMM initialization. A
deterministic fit-specific seed is derived from the split and candidate
|
A som_cross_models object with partitions, warnings and explicit
failures.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 4) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) fit_cross_models(ensemble, methods = c("kmeans", "ward"))data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 4) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) fit_cross_models(ensemble, methods = c("kmeans", "ward"))
Every model receives preprocessing parameters estimated only from its own analysis rows. Failures are recorded instead of silently discarded. Topographic error is computed during fitting so duplicate full processed matrices need not be retained in every ensemble member.
fit_som_ensemble( data, spec, resamples = NULL, preprocess = som_preprocess(), keep_models = TRUE, fail_fast = FALSE, parallel = FALSE )fit_som_ensemble( data, spec, resamples = NULL, preprocess = som_preprocess(), keep_models = TRUE, fail_fast = FALSE, parallel = FALSE )
data |
A |
spec |
A |
resamples |
A |
preprocess |
One |
keep_models |
Whether to retain fitted |
fail_fast |
Whether to stop at the first model failure. |
parallel |
Whether to distribute ensemble members through the current
|
A som_ensemble object.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 1) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) ensembledata <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 1) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) ensemble
The Shiny interface exposes a compact subset of the package workflow for
teaching and exploratory configuration. Every completed run can export its
exact R script and a YAML configuration snapshot. Version 1.1.x cannot
import that snapshot to restore GUI controls. The exported script, not the
GUI session or snapshot, is the executable analysis record. The interface is
designed for a local R session, and SOMevidence sends no telemetry. In a
local session, selected files remain on the local computer. A remotely
deployed Shiny application transfers selected files to its host, whose
operator is responsible for access controls and data handling.
launch_som_app()launch_som_app()
A shiny.appobj. Pass it to shiny::runApp() or print it in an
interactive R session. The application does not return an analysis result;
users can export the executable R script for a configured run.
Experimental. The interface and its exported configuration snapshot schema may change after independent usability testing. The ordinary R API remains the authoritative analysis interface.
Every ensemble member applies only the transformations, centering, scaling and layer geometry learned from its own analysis split. The function reports best-matching units and mapping distances separately by fit; it does not align nodes across different grids or call the result prediction accuracy.
map_som_ensemble(ensemble, new_data, fail_fast = FALSE)map_som_ensemble(ensemble, new_data, fail_fast = FALSE)
ensemble |
A |
new_data |
A |
fail_fast |
Whether to stop at the first member-specific mapping error. |
A som_newdata_mapping object with sample-by-fit records, fit-level
distance and occupancy summaries, failures and new-data metadata.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 8) specification <- som_spec(c(3, 2), seeds = 1, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = TRUE) new_data <- som_data(layers = list( environment = data$layers$environment[1:3, , drop = FALSE] )) map_som_ensemble(ensemble, new_data)data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 8) specification <- som_spec(c(3, 2), seeds = 1, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = TRUE) new_data <- som_data(layers = list( environment = data$layers$environment[1:3, , drop = FALSE] )) map_som_ensemble(ensemble, new_data)
The registry records provenance, version, licence, implementation status and
the intended role of each external dataset. Only records marked
implemented are used by a current package tutorial. Candidate records are
governed prospects, not claims of completed package validation. The
function returns metadata only; it never downloads data or changes the
user's files.
open_data_registry(role = NULL, domain = NULL)open_data_registry(role = NULL, domain = NULL)
role |
Optional role used to filter the registry. Matching is exact and case-sensitive; unmatched values return no matching rows. |
domain |
Optional scientific domain used to filter the registry. Matching is exact and case-sensitive; unmatched values return no matching rows. |
A data frame with one row per governed external dataset.
open_data_registry(role = "quickstart")open_data_registry(role = "quickstart")
When x is a som_audit, fit-level metrics are directly comparable only
when every successful fit uses the same analysis rows. To preserve the
established interface, an audit with distinct analysis sets still returns
its exploratory fit-level frontier, but emits a warning and marks the result
with attr(result, "comparison_scope") == "distinct_analysis_sets". Such a
frontier must not be used to choose a configuration. Instead, construct
prespecified configuration-level summaries over identical successful split
and seed coverage, then pass that justified comparable data frame.
pareto_candidates( x, metrics = c(quantization_error = "min", topographic_error = "min", empty_unit_rate = "min") )pareto_candidates( x, metrics = c(quantization_error = "min", topographic_error = "min", empty_unit_rate = "min") )
x |
A |
metrics |
Named character vector whose values are |
The non-dominated rows, with a pareto column. Results derived from
a som_audit also carry a comparison_scope attribute.
Form and compare candidate hard partitions of SOM units
partition_som( ensemble, k = ensemble$spec$k, method = "ward.D2", scope = c("analysis", "all"), max_pairwise_comparisons = 1000000L )partition_som( ensemble, k = ensemble$spec$k, method = "ward.D2", scope = c("analysis", "all"), max_pairwise_comparisons = 1000000L )
ensemble |
A fitted |
k |
Candidate numbers of clusters. Defaults to the ensemble specification. |
method |
Hierarchical clustering method used on SOM codebooks. |
scope |
Evidence scope. The default, |
max_pairwise_comparisons |
Maximum number of pairwise partition
comparisons created across all requested |
A som_partitions object. Agreement is reported as ARI and AMI,
not accuracy. AMI is chance-adjusted and normalized by the arithmetic mean
of the two partition entropies.
data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 2) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) partition_som(ensemble)data <- simulate_som_scenario("clusters", n = 45, p = 3, seed = 2) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2) ensemble <- fit_som_ensemble(data, specification, keep_models = FALSE) partition_som(ensemble)
This function deliberately plots a named ensemble member instead of silently treating one fitted map as representative of the ensemble. Component values are on the processed scale used for training.
plot_som_plane( x, type = c("component", "occupancy", "neighbour_distance"), fit_id = NULL, layer = NULL, variables = NULL )plot_som_plane( x, type = c("component", "occupancy", "neighbour_distance"), fit_id = NULL, layer = NULL, variables = NULL )
x |
A |
type |
One of |
fit_id |
Identifier of one successful ensemble fit. It may be omitted only when the ensemble contains exactly one successful fit. |
layer |
Layer name used for a component plane. It may be omitted for a single-layer analysis. |
variables |
Optional component names. All variables in |
An editable ggplot object.
Plot SOM audit trade-offs
## S3 method for class 'som_audit' plot(x, ...)## S3 method for class 'som_audit' plot(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
Plot sample-level consensus evidence
## S3 method for class 'som_consensus' plot( x, type = c("support", "heatmap"), samples = NULL, max_samples = 500L, ... )## S3 method for class 'som_consensus' plot( x, type = c("support", "heatmap"), samples = NULL, max_samples = 500L, ... )
x |
A |
type |
Either |
samples |
Optional sample indices for a heatmap. |
max_samples |
Maximum heatmap size allowed without explicit |
... |
Unused. |
A ggplot object.
Plot cross-model agreement without ranking methods
## S3 method for class 'som_cross_comparison' plot(x, ...)## S3 method for class 'som_cross_comparison' plot(x, ...)
x |
A |
... |
Unused. |
A faceted ggplot object showing ARI and AMI distributions.
Plot new-data mapping shift across an ensemble
## S3 method for class 'som_newdata_mapping' plot(x, ...)## S3 method for class 'som_newdata_mapping' plot(x, ...)
x |
A |
... |
Unused. |
An editable ggplot object.
Plot partition reproducibility across candidate class counts
## S3 method for class 'som_partitions' plot(x, ...)## S3 method for class 'som_partitions' plot(x, ...)
x |
A |
... |
Unused. |
A faceted ggplot object with ensemble agreement intervals.
Each point represents one sample at one candidate k. The horizontal axis
conditions cluster-member sets on jointly evaluable shared samples and
therefore isolates repartitioning. The vertical axis also includes eligible
members unique to either scenario and therefore combines data coverage with
repartitioning. Values are medians across evaluable contrasts. Membership
sets are compared directly, so the plot is invariant to arbitrary
cluster-label permutations. It describes sensitivity to the scenarios that
were supplied, not a probability that a cluster assignment is correct.
## S3 method for class 'som_sensitivity' plot(x, k = NULL, ...)## S3 method for class 'som_sensitivity' plot(x, k = NULL, ...)
x |
A |
k |
Optional candidate cluster counts to display. |
... |
Unused. |
An editable ggplot object.
Plot mapping shift in held-out domains
## S3 method for class 'som_transfer_audit' plot(x, ...)## S3 method for class 'som_transfer_audit' plot(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
Each named scenario must provide data and spec, and may provide
resamples, preprocess and k. Scenarios may represent alternative
variable modules, transformations, layer weights, grids or data-coverage
rules. Results remain separate by scenario and evidence stream; the function
creates no aggregate ranking.
run_som_sensitivity( scenarios, cross_models = c("kmeans", "ward"), cross_model_control = list(), consensus_method = "auto", max_coassignment_n = 5000L, max_pairwise_comparisons = 1000000L, sample_profiles = TRUE, keep_workflows = TRUE, fail_fast = FALSE )run_som_sensitivity( scenarios, cross_models = c("kmeans", "ward"), cross_model_control = list(), consensus_method = "auto", max_coassignment_n = 5000L, max_pairwise_comparisons = 1000000L, sample_profiles = TRUE, keep_workflows = TRUE, fail_fast = FALSE )
scenarios |
A named list of workflow argument lists. |
cross_models |
Reference methods used in every scenario. |
cross_model_control |
Named reference-model controls passed to every
scenario through |
consensus_method |
Consensus method used in every scenario. |
max_coassignment_n |
Dense co-assignment limit. |
max_pairwise_comparisons |
Pairwise partition-comparison budget passed to each scenario. |
sample_profiles |
Whether to compute sample-level membership-set
contrasts. Set to |
keep_workflows |
Whether to retain full workflow objects. |
fail_fast |
Whether to stop at the first scenario failure. |
A som_sensitivity object with tidy evidence tables, shared-sample
comparisons between scenario consensus partitions, sample-level
membership-set comparisons, scenario failures and optionally full
workflows. Scenario agreement uses only samples assigned by at least two
ensemble members in both scenarios, and at least two jointly evaluable
samples are required before co-membership can be compared. For each focal
sample, membership_jaccard_shared conditions on the jointly evaluable
sample universe and isolates repartitioning, whereas
membership_jaccard_all also includes eligible members unique to either
scenario and therefore combines coverage and repartitioning effects.
Neither requires aligning arbitrary cluster labels. sample_summary
reports both distributions and distinguishes coverage of all planned
contrasts from coverage conditional on globally comparable contrasts.
These are sensitivity diagnostics, not confidence probabilities.
Comparisons across
different data objects require supplied identifiers or explicit row names;
unsafe default identifiers, failed scenarios, unavailable consensus and
absent common k values remain visible through comparison_status rather
than being silently omitted. Legacy objects without identifier
provenance must be reconstructed with an explicit id argument before
cross-object comparison. Candidate k values are read exactly from each
scenario or its specification; malformed values are not coerced. A failed
scenario without a valid candidate set remains visible with k = NA but
cannot contribute to a candidate-specific contrast denominator.
Experimental. The scenario-list interface may change after independent usability testing. Individual workflow functions and their evidence tables are the candidate-stable interfaces.
The workflow preserves representation quality, partition stability,
sample-level consensus and cross-model agreement as separate evidence
streams. It does not combine them into a score or select a winning k.
run_som_workflow( data, spec, resamples = NULL, preprocess = som_preprocess(), k = spec$k, cross_models = c("kmeans", "ward"), cross_model_control = list(), consensus_method = "auto", max_coassignment_n = 5000L, keep_models = FALSE, fail_fast = FALSE, parallel = FALSE, max_pairwise_comparisons = 1000000L )run_som_workflow( data, spec, resamples = NULL, preprocess = som_preprocess(), k = spec$k, cross_models = c("kmeans", "ward"), cross_model_control = list(), consensus_method = "auto", max_coassignment_n = 5000L, keep_models = FALSE, fail_fast = FALSE, parallel = FALSE, max_pairwise_comparisons = 1000000L )
data |
A |
spec |
A |
resamples |
Optional |
preprocess |
One |
k |
Candidate numbers of hard partitions. |
cross_models |
Controlled reference methods passed to
|
cross_model_control |
Named list of optional |
consensus_method |
Consensus method passed to |
max_coassignment_n |
Dense co-assignment limit passed to
|
keep_models |
Whether to retain fitted SOM and reference model objects. |
fail_fast |
Whether a model or consensus failure should stop the run. |
parallel |
Whether SOM ensemble members should use the current
|
max_pairwise_comparisons |
Pairwise partition-comparison budget passed
to |
A som_workflow object containing each evidence stream and explicit
failure logs.
data <- simulate_som_scenario("clusters", n = 60, p = 4, seed = 6) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2:3) workflow <- run_som_workflow( data, specification, cross_models = c("kmeans", "ward") ) summary(workflow)data <- simulate_som_scenario("clusters", n = 60, p = 4, seed = 6) specification <- som_spec(c(3, 2), seeds = 1:2, rlen = 10, k = 2:3) workflow <- run_som_workflow( data, specification, cross_models = c("kmeans", "ward") ) summary(workflow)
Simulate known-structure data for SOM validation
simulate_som_scenario( scenario = c("gradient", "clusters", "overlap", "grouped_pseudoreplication", "multilayer_conflict"), n = 180L, p = 6L, seed = 1L, noise_sd = 1, class_probs = c(1, 1, 1), n_groups = NULL, group_icc = 0.7, n_domains = 3L, domain_shift = 0, missing_rate = 0, missing_mechanism = c("none", "mcar", "domain"), id = NULL )simulate_som_scenario( scenario = c("gradient", "clusters", "overlap", "grouped_pseudoreplication", "multilayer_conflict"), n = 180L, p = 6L, seed = 1L, noise_sd = 1, class_probs = c(1, 1, 1), n_groups = NULL, group_icc = 0.7, n_domains = 3L, domain_shift = 0, missing_rate = 0, missing_mechanism = c("none", "mcar", "domain"), id = NULL )
scenario |
One of |
n |
Number of samples. |
p |
Number of variables per primary layer. |
seed |
Random seed. |
noise_sd |
Within-structure residual standard deviation. |
class_probs |
Three positive class proportions for simulations with genuine discrete classes. They are normalized internally. Ignored for a continuous gradient. |
n_groups |
Number of sampling groups for
|
group_icc |
Target intraclass correlation induced by the simulated
group effect. Used only for |
n_domains |
Number of balanced sampling domains. A gradient always has
domains spanning its latent coordinate. Other scenarios receive domains
when |
domain_shift |
Magnitude of an additive domain-specific shift applied to the first two variables. Zero creates no additional domain shift. |
missing_rate |
Expected fraction of entries set to missing. |
missing_mechanism |
One of |
id |
Optional stable sample identifiers. Supply these when independently constructed simulated objects will be compared in a sensitivity workflow. |
A som_data object with additional truth and simulation_spec
components. Known latent variables and labels are never included in the
training layers. Discrete labels are also copied to external_label for
post hoc agreement assessment.
Experimental. Existing scenario names are retained within the 1.x series, while new scenarios and scenario-specific controls may be added in minor releases.
simulated <- simulate_som_scenario( "gradient", n = 60, p = 4, seed = 1, domain_shift = 0.5 ) simulatedsimulated <- simulate_som_scenario( "gradient", n = 60, p = 4, seed = 1, domain_shift = 0.5 ) simulated
Construct a design-explicit SOM data object
som_data( x = NULL, layers = NULL, id = NULL, group = NULL, time = NULL, domain = NULL, weight = NULL, external_label = NULL )som_data( x = NULL, layers = NULL, id = NULL, group = NULL, time = NULL, domain = NULL, weight = NULL, external_label = NULL )
x |
A numeric matrix or data frame for a single-layer analysis. |
layers |
A named list of numeric matrices or data frames. Use either
|
id |
Optional unique sample identifiers. |
group |
Optional sampling-group identifiers. |
time |
Optional time values retained as metadata. |
domain |
Optional monitoring-domain identifiers. |
weight |
Optional non-negative survey or summary weights. These weights are retained only as metadata in the current release. They are not used in SOM training, evidence metrics or design summaries. |
external_label |
Optional external ecological labels. They are retained
for post hoc assessment and never added to the training layers. A fully
named vector is aligned to |
An object of class som_data. Named multi-layer inputs are aligned
to the first layer by row name when all layers provide row names;
incompatible or partly named layers are rejected. An explicit id vector
is always interpreted positionally against the first layer and never
changes its row order. If no layers have usable row names, their existing
row order is treated as authoritative. The scalar id_source records
whether sample identifiers were supplied, taken from explicit
non-positional row names or generated locally. Stable identifiers are
required to compare different data-coverage scenarios.
x <- data.frame(temperature = 10:14, oxygen = c(9, 8, 8, 7, 6)) data <- som_data(x, id = paste0("sample_", seq_len(nrow(x)))) datax <- data.frame(temperature = 10:14, oxygen = c(9, 8, 8, 7, 6)) data <- som_data(x, id = paste0("sample_", seq_len(nrow(x)))) data
No universal thresholds are supplied. A gate records the analyst's prespecified requirements.
som_gate( max_topographic_error = NULL, max_empty_unit_rate = NULL, min_median_ari = NULL, min_median_ami = NULL, min_pairwise_coverage = NULL, min_cluster_jaccard = NULL, min_consensus_coverage = NULL, min_replicated_coverage = NULL, min_membership_support = NULL, max_assignment_entropy = NULL, min_cross_model_ari = NULL, min_cross_model_methods = NULL, min_success_rate = NULL )som_gate( max_topographic_error = NULL, max_empty_unit_rate = NULL, min_median_ari = NULL, min_median_ami = NULL, min_pairwise_coverage = NULL, min_cluster_jaccard = NULL, min_consensus_coverage = NULL, min_replicated_coverage = NULL, min_membership_support = NULL, max_assignment_entropy = NULL, min_cross_model_ari = NULL, min_cross_model_methods = NULL, min_success_rate = NULL )
max_topographic_error |
Optional maximum median topographic error. |
max_empty_unit_rate |
Optional maximum median empty-unit rate. |
min_median_ari |
Optional minimum median pairwise ARI. |
min_median_ami |
Optional minimum median pairwise AMI. |
min_pairwise_coverage |
Optional minimum median proportion of samples jointly assigned in pairwise partition comparisons. |
min_cluster_jaccard |
Optional minimum across cluster-level median Jaccard values. |
min_consensus_coverage |
Optional minimum proportion of samples with an identifiable consensus label. |
min_replicated_coverage |
Optional minimum proportion of samples assigned by at least two partitions, for which support and entropy are estimable. |
min_membership_support |
Optional minimum median sample membership support. |
max_assignment_entropy |
Optional maximum median normalized assignment entropy. |
min_cross_model_ari |
Optional minimum of the method-specific median SOM-to-reference ARI values. Each requested reference method must have an evaluable result; pooled comparisons are not used for this gate. |
min_cross_model_methods |
Optional minimum number of reference methods represented in the comparison. |
min_success_rate |
Optional minimum model-fit success rate. |
A som_gate object.
som_gate(min_success_rate = 0.95, min_cluster_jaccard = 0.75)som_gate(min_success_rate = 0.95, min_cluster_jaccard = 0.75)
Define leakage-safe SOM preprocessing
som_preprocess( transform = "identity", center = TRUE, scale = TRUE, zero_replacement = NULL )som_preprocess( transform = "identity", center = TRUE, scale = TRUE, zero_replacement = NULL )
transform |
One of |
center |
Whether to subtract training-set column means. |
scale |
Whether to divide by training-set column standard deviations. |
zero_replacement |
Positive replacement required when |
A preprocessing specification of class som_preprocess.
som_preprocess(transform = c("log", "identity"))som_preprocess(transform = c("log", "identity"))
Construct design-aware resamples
som_resamples( data, method = c("full", "subsample", "group_subsample", "block_subsample", "leave_domain_out", "custom"), repeats = 50L, prop = 0.8, seed = 1L, unit = "group", domain = "domain", splits = NULL )som_resamples( data, method = c("full", "subsample", "group_subsample", "block_subsample", "leave_domain_out", "custom"), repeats = 50L, prop = 0.8, seed = 1L, unit = "group", domain = "domain", splits = NULL )
data |
A |
method |
One of |
repeats |
Number of repeated subsamples. |
prop |
Proportion of rows or sampling units retained for analysis. |
seed |
Random seed used to generate all splits. |
unit |
Metadata column name or vector defining groups or predefined
blocks. |
domain |
Metadata column name or vector defining transfer domains. |
splits |
For |
A som_resamples object. The object records the number of distinct
analysis sets in n_unique_analysis_splits and identifies repeated sets
in duplicate_analysis_splits.
x <- matrix(seq_len(120), nrow = 30) data <- som_data(x, group = rep(paste0("site_", 1:10), each = 3)) som_resamples(data, method = "group_subsample", repeats = 2, seed = 1)x <- matrix(seq_len(120), nrow = 30) data <- som_data(x, group = rep(paste0("site_", 1:10), each = 3)) som_resamples(data, method = "group_subsample", repeats = 2, seed = 1)
Specify a reproducible SOM ensemble
som_spec( grids = data.frame(xdim = 7L, ydim = 5L), seeds = 1:10, rlen = 500L, alpha = c(0.05, 0.01), radius = NULL, topology = c("hexagonal", "rectangular"), neighbourhood = c("gaussian", "bubble"), toroidal = FALSE, mode = c("batch", "online", "pbatch"), k = 2:8, max_na_fraction = 0, layer_weights = NULL, normalize_layers = TRUE, cores = 1L )som_spec( grids = data.frame(xdim = 7L, ydim = 5L), seeds = 1:10, rlen = 500L, alpha = c(0.05, 0.01), radius = NULL, topology = c("hexagonal", "rectangular"), neighbourhood = c("gaussian", "bubble"), toroidal = FALSE, mode = c("batch", "online", "pbatch"), k = 2:8, max_na_fraction = 0, layer_weights = NULL, normalize_layers = TRUE, cores = 1L )
grids |
A two-column data frame with |
seeds |
Integer random seeds. |
rlen |
Number of training iterations. |
alpha |
Initial and final learning rates. |
radius |
Optional initial and final neighbourhood radii. |
topology |
Rectangular or hexagonal grid. |
neighbourhood |
Bubble or Gaussian neighbourhood. |
toroidal |
Whether the grid is toroidal. |
mode |
Training mode supported by |
k |
Candidate numbers of hard partitions retained for later auditing. |
max_na_fraction |
Maximum allowed fraction of missing variables per
layer and sample passed to |
layer_weights |
Optional non-negative scientific weights, one per layer. |
normalize_layers |
Whether to divide each scientific layer weight by its training-set mean squared Euclidean distance. The package uses the variance identity for a deterministic, leakage-safe estimate and applies the same effective weights to SOM and cross-model fits. |
cores |
Number of cores used by |
A som_spec object.
specification <- som_spec( grids = list(c(4, 3), c(5, 4)), seeds = 1:2, rlen = 50, k = 2:4 ) expand_som_spec(specification)specification <- som_spec( grids = list(c(4, 3), c(5, 4)), seeds = 1:2, rlen = 50, k = 2:4 ) expand_som_spec(specification)
Summarize workflow quality assurance and model outcomes
## S3 method for class 'som_workflow' summary(object, ...)## S3 method for class 'som_workflow' summary(object, ...)
object |
A |
... |
Reserved for future methods. |
A summary.som_workflow object containing fit, consensus,
cross-model and provenance summaries plus the original failure tables.
Upgrades a supported public SOMevidence object to the current structural contract using only deterministic, non-analytical migrations. The function never refits a model or fabricates scientific evidence. If a required field cannot be reconstructed, it asks the user to recompute the affected result.
upgrade_som_object(x)upgrade_som_object(x)
x |
A persisted public |
Contract versions describe object structure, not the package or algorithm
version that generated an analysis. Retain som_workflow$provenance and
sessionInfo() for that purpose.
A validated object under the current contract. The input is not modified in place. Repeated upgrades are idempotent.
data <- som_data(matrix(seq_len(18), nrow = 6)) legacy <- data attr(legacy, "som_contract_version") <- NULL upgrade_som_object(legacy)data <- som_data(matrix(seq_len(18), nrow = 6)) legacy <- data attr(legacy, "som_contract_version") <- NULL upgrade_som_object(legacy)