Composable spectral analysis¶
Module: spectralbridge.library_analysis.
Composable spectral-library methods, independent of the repository study.
Install earthlab-spectralbridge[analytics]. Arrays use observations by features;
units and wavelength support must be common. No routine establishes field cover,
physical calibration or universal ecological transfer. See the scientific API guide.
API glossary ยท Workflow / scientific context
Signatures and documentation below are collected from the current source. Advanced objects are not newly declared stable by inclusion here.
Audience: public.
project_simplex ¶
project_simplex(values)
Enforce Euclidean nonnegative sum-one fraction geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
array - like
|
Finite vector (C,) or matrix (N, C) of fraction coordinates for row-wise Euclidean projection onto the nonnegative sum-one simplex. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Same-shaped array of row-wise projected fractions; nonnegative coordinates sum to one but need not be uniquely physically identifiable. |
Notes
Inputs: finite vector (C,) or matrix (N,C); C >= 1. Sampling unit: each row. Outputs: same-shaped projected array. Assumptions: Euclidean distance and common fraction coordinates. Does not add information or establish uniqueness of a physical inversion. Reuses the audited sorting implementation.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> projected = api.project_simplex([-1., 2.])
>>> assert np.allclose(projected, [0., 1.])
Audience: public.
spectral_separability ¶
spectral_separability(spectra, labels, wavelengths, groups=None, *, blocks=None, mask=None, regions=None, permutations=999, seed=0, max_gap=8, missing='raise', integration_weights=None, maximum_units=5000)
Test pairwise conditional whole-spectrum differences, not prediction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
wavelengths
|
array - like
|
Finite wavelength coordinates in nanometers, aligned with spectral columns; numerical analysis routines require strictly increasing unique coordinates. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
blocks
|
array - like
|
Aligned exchangeability strata for restricted curve permutations; labels must be exchangeable within retained mixed blocks. |
None
|
mask
|
array - like
|
Boolean wavelength vector (B,), True for admitted common support; atmospheric and unsupported gaps should be excluded explicitly. |
None
|
regions
|
dict
|
Optional mapping from region names to (lower, upper) wavelength bounds in nanometers; gaps remain disconnected. |
None
|
permutations
|
int
|
Number of seeded restricted random permutations; spectral_separability requires at least 19. |
999
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
max_gap
|
float
|
Maximum wavelength gap in nanometers treated as contiguous during integration; larger gaps are not bridged. |
8
|
missing
|
('raise', drop_columns)
|
Nonfinite-value policy: 'raise' rejects missing support; 'drop_columns' removes incomplete columns globally before aggregation. |
'raise'
|
integration_weights
|
array - like or None
|
Optional positive quadrature weights aligned with wavelengths, expressing the declared support measure rather than sampling density. |
None
|
maximum_units
|
int
|
Maximum independent mean curves allowed in the quadratic energy-distance calculation; an explicit memory/runtime guard. |
5000
|
Returns:
| Type | Description |
|---|---|
dict
|
Pair-test, wavelength and region DataFrames plus retained-coordinate and multiplicity metadata; effect direction is second label minus first. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: spectra (N,B), labels (N,), strictly increasing wavelengths (B,); groups are observation identities, blocks are exchangeability strata. Optional boolean mask keeps supported coordinates; regions maps names to (low,high). Sampling unit: one identity mean curve; repeated identities must have constant labels/blocks. Without groups each row is an independent sampling unit. Outputs: dict of pair, wavelength and region DataFrames plus support metadata. Signed effects are second-minus-first labels; standardized effects divide by within-block response scale (not Cohen's d). Synchronized curve permutations within each pair preserve covariance across wavelengths. Max-statistic p-values control coordinates within pair; Bonferroni then controls all declared pairs. Whole-spectrum p-values use Holm across pairs separately for each statistic. Assumptions: exchangeable identities within mixed blocks; fixed support/units. Energy distances scale quadratically in unit count; maximum_units guards this. Missing='drop_columns' removes incomplete columns globally before aggregation; default rejects nonfinite values on requested support. Atmospheric gaps must be masked explicitly. Region effects use disconnected quadrature, not gap bridges. Does not establish classification, abundance, causality or universal difference.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> rng = np.random.default_rng(13)
>>> labels = np.repeat(["A", "B", "C"], 12)
>>> spectra = np.repeat(np.eye(3), 12, axis=0) + rng.normal(0, .01, (36, 3))
>>> identities = np.arange(36)
>>> result = api.spectral_separability(spectra, labels, [500., 505., 510.], identities, permutations=19)
>>> assert len(result["pairs"]) == 3
Audience: public.
generate_mixtures ¶
generate_mixtures(spectra, labels, parent_ids, *, pair_grid=(0, 0.1, 0.5, 0.9, 1), triple_grid=((1 / 3, 1 / 3, 1 / 3),), replicates=1, seed=0, class_order=None, parent_roles=None, maximum_mixtures=100000)
Generate reproducible pair/triple linear mixtures and exact generating weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
parent_ids
|
array - like
|
Unique identifiers for candidate parent spectra; aggregate repeated parents before generating mixtures. |
required |
pair_grid
|
sequence of float
|
Fractions in [0, 1] used for two-parent mixtures; the complementary fraction is one minus the supplied value. |
(0, 0.1, 0.5, 0.9, 1)
|
triple_grid
|
sequence of 3-element sequences
|
Sequence of three-element nonnegative sum-one fraction vectors; an empty sequence disables three-parent mixtures. |
((1 / 3, 1 / 3, 1 / 3),)
|
replicates
|
int
|
Positive number of seeded repetitions for parent selection or library-size sampling. |
1
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
parent_roles
|
array - like or None
|
Optional role labels aligned with candidate parents; retained as provenance alongside generating weights. |
None
|
maximum_mixtures
|
int
|
Positive upper limit on generated synthetic mixtures; prevents accidental combinatorial expansion. |
100000
|
Returns:
| Type | Description |
|---|---|
dict
|
Synthetic spectra, exact class fractions, classes and padded parent indices/IDs/categories/roles/fractions; shared parents imply dependence. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: finite parent spectra (P,B), labels/parent_ids (P,), explicit pair scalar fractions and triple simplex vectors; triple_grid=() disables triples. Sampling unit: synthetic mixture; shared parent mixtures are dependent. Outputs: spectra, truth in classes order, padded parent indices/IDs/categories/roles and parent fractions; zero-weight parents remain tracked for conservative holdout. Assumptions: one common spectral support/scale and ideal algebraic mixing. Does not establish physical mixing, parent purity or independent field truth.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> result = api.generate_mixtures(np.eye(2), ["A", "B"], ["p1", "p2"], pair_grid=(.25,), triple_grid=())
>>> assert np.allclose(result["truth"].sum(axis=1), 1)
Audience: public.
constrained_unmixing ¶
constrained_unmixing(targets, endmembers, *, endmember_ids=None)
Fit nonnegative sum-one FCLS using the existing small-library face solver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
targets
|
array - like
|
Finite target spectra (N, B) sharing the endmember library wavelength support and reflectance units. |
required |
endmembers
|
array - like
|
Finite reference matrix (M, B), one reference per row; constrained_unmixing admits at most 12 references. |
required |
endmember_ids
|
array - like or None
|
Optional unique identifiers aligned with reference rows; None uses row indices. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Endmember-ordered fractions, reconstruction, RMSE, reference IDs and solver details for each target. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If required processing or artifact validation cannot complete. |
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: targets (N,B), ordered endmembers (M,B), M<=12; optional unique IDs. Sampling unit: target spectrum. Outputs: fractions in supplied endmember order, reconstruction, RMSE, IDs and solver details. Assumptions: common units/support, admitted numerical faces/rank thresholds of mixtures.fcls (not exact arithmetic). Does not establish unique composition or biological truth from good residuals.
See Also
spectralbridge.library_analysis.fit_mesma : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> result = api.constrained_unmixing([[.25, .75]], np.eye(2))
>>> assert np.allclose(result["fractions"], [[.25, .75]])
Audience: public.
candidate_ambiguity ¶
candidate_ambiguity(fractions, errors, *, tolerance=0.01, class_order=None)
Summarize fraction variation among evaluated near-best candidate solutions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fractions
|
array - like
|
Nonnegative sum-one fraction coordinates, with classes/endmembers in the declared column order; shape requirements are given in Notes. |
required |
errors
|
array - like
|
Finite nonnegative reconstruction RMSE for each candidate composition, in the same target reflectance units. |
required |
tolerance
|
float
|
Absolute numerical tolerance in the compared quantity: reflectance for chunk checks, additive RMSE for candidate ambiguity. |
0.01
|
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Best and near-best candidate indices/compositions, per-class ranges and maximum range; uncertainty covers evaluated candidates only. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: simplex fractions (K,C) and nonnegative reconstruction RMSE (K,); tolerance is additive in those RMSE units. Sampling unit: one target's finite candidate set. Outputs: best index/fractions, near indices/solutions, per-class min/max/range, maximum range (ambiguity_score), near count and alternative count. Assumptions: comparable errors, common class order. Stable first-index tie rule. Counts refer to evaluated solutions and may include redundant compositions. Does not describe exhaustive physical uncertainty or all feasible fractions.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> result = api.candidate_ambiguity([[.2, .8], [.21, .79]], [.01, .015], tolerance=.01)
>>> assert result["near_count"] == 2
Audience: public.
fit_mesma ¶
fit_mesma(targets, endmembers, labels, *, endmember_ids=None, max_components=3, candidates=None, maximum_models=20000, tolerance=0.01, class_order=None)
Search explicit candidate models and retain inspectable near-fit compositions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
targets
|
array - like
|
Finite target spectra (N, B) sharing the endmember library wavelength support and reflectance units. |
required |
endmembers
|
array - like
|
Finite reference matrix (M, B), one reference per row; constrained_unmixing admits at most 12 references. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
endmember_ids
|
array - like or None
|
Optional unique identifiers aligned with reference rows; None uses row indices. |
None
|
max_components
|
int
|
Maximum references per candidate MESMA model, from 1 through 12; zero-weight selected components remain possible. |
3
|
candidates
|
sequence of tuples or None
|
Optional sequence of tuples of zero-based library row indices; None enumerates distinct-category models up to max_components. |
None
|
maximum_models
|
int
|
Positive upper bound on evaluated candidate models; the search fails explicitly when the requested budget is exceeded. |
20000
|
tolerance
|
float
|
Absolute numerical tolerance in the compared quantity: reflectance for chunk checks, additive RMSE for candidate ambiguity. |
0.01
|
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Class fractions, RMSE/reconstruction, selected references/component fractions, full candidate errors/fractions and ambiguity summaries. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: targets (N,B), library (P,B), category labels/optional IDs (P,); candidates is a sequence of tuples of library row indices. Default enumerates distinct-category models up to max_components. Sampling unit: target spectrum. Outputs: class fractions, selected endmember tuples/fractions, reconstruction, RMSE, candidate errors/fractions, ambiguity per target and numerical tolerances. Assumptions: finite same-unit library and explicit computational budget; each candidate is solved with the existing FCLS face/rank thresholds. Boundaries are allowed, so selected tuple can include zero-weight references. Stable first tie. Does not establish exhaustive uncertainty, purity or correct biological cover.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> result = api.fit_mesma([[.25, .75]], np.eye(2), ["A", "B"], max_components=2)
>>> assert np.allclose(result["fractions"], [[.25, .75]])
Audience: public.
evaluate_identifiability ¶
evaluate_identifiability(spectra, labels, groups=None, *, domains=None, folds=3, inner_folds=3, regularization=(0.1, 1, 10), seed=0, class_order=None)
Evaluate unseen identities or held domains with nested regularized recognition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
domains
|
array - like
|
Optional aligned site/year/domain labels for held-domain evaluation; held identities are purged globally from training. |
None
|
folds
|
int
|
Number of grouped outer evaluation folds, or grouped tuning folds for the ridge fraction estimator; requires enough independent groups. |
3
|
inner_folds
|
int
|
Number of grouped inner training-only folds used for regularization and feature-selection tuning. |
3
|
regularization
|
sequence of positive float
|
Prespecified positive classifier C values; multiple values trigger grouped inner tuning entirely within training data. |
(0.1, 1, 10)
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Grouped fold/overall scores, class recall/confusion, row-aligned predictions/probabilities, tuning memberships and fitted models. |
Notes
Inputs: finite spectra (N,B), labels, optional identity groups and site/year domains. Sampling unit: identity; repeated histories never cross train/test. Outputs: fold/overall balanced accuracy, per-class recall/confusion, predictions, class-ordered probabilities, row membership, hyperparameters and fitted models. Assumptions: one label per identity, common features; training is row-based, metrics identity-weighted. All scale fitting/tuning occurs inside training; multi-value regularization requires valid grouped inner folds, else raises. Held domains purge target identities globally, even from other training domains. Missing values are rejected; probabilities are not calibrated uncertainty. Does not establish mixture uniqueness, field fractions or universal transfer.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> rng = np.random.default_rng(13)
>>> labels = np.repeat(["A", "B", "C"], 12)
>>> spectra = np.repeat(np.eye(3), 12, axis=0) + rng.normal(0, .01, (36, 3))
>>> identities = np.arange(36)
>>> result = api.evaluate_identifiability(spectra, labels, identities, folds=2, regularization=(1,))
>>> assert "balanced_accuracy" in result["overall"]
Audience: public.
evaluate_feature_budget ¶
evaluate_feature_budget(spectra, labels, wavelengths, groups=None, *, budgets=(1, 3, 5), random_replicates=3, domains=None, folds=3, inner_folds=3, regularization=(0.1, 1, 10), seed=0, include_full=True, pca_components=None)
Measure predictive information versus feature count with nested selection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
wavelengths
|
array - like
|
Finite wavelength coordinates in nanometers, aligned with spectral columns; numerical analysis routines require strictly increasing unique coordinates. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
budgets
|
sequence of int
|
Distinct positive feature counts to evaluate, bounded by the available spectral columns. |
(1, 3, 5)
|
random_replicates
|
int
|
Positive number of seeded label-independent random feature paths; each path is nested across budgets. |
3
|
domains
|
array - like
|
Optional aligned site/year/domain labels for held-domain evaluation; held identities are purged globally from training. |
None
|
folds
|
int
|
Number of grouped outer evaluation folds, or grouped tuning folds for the ridge fraction estimator; requires enough independent groups. |
3
|
inner_folds
|
int
|
Number of grouped inner training-only folds used for regularization and feature-selection tuning. |
3
|
regularization
|
sequence of positive float
|
Prespecified positive classifier C values; multiple values trigger grouped inner tuning entirely within training data. |
(0.1, 1, 10)
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
include_full
|
bool
|
Include the full-feature classifier as a reference alongside budget-constrained models. |
True
|
pca_components
|
int or None
|
Optional PCA dimension evaluated using training-only fitted transforms; None omits this comparison. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Curve and selected-feature DataFrames plus detailed fold evaluations; selection is refitted within each training fold. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: finite spectra, labels, wavelengths, identities and optional held domains; explicit integer budgets, fixed seeded random paths and optional PCA size. Sampling unit: held-out identity. Outputs: curve DataFrame, detailed evaluation dicts and selected coordinates per outer fold. Selection refits inside every inner fold; each random path is label-independent and nested across budgets. Assumptions: valid group splits; PCA/scale fitting is training-only. Budgets are experimental settings, not chosen from outer scores for final evaluation. Does not establish globally optimal bands, a sensor design or field accuracy.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> rng = np.random.default_rng(13)
>>> labels = np.repeat(["A", "B", "C"], 12)
>>> spectra = np.repeat(np.eye(3), 12, axis=0) + rng.normal(0, .01, (36, 3))
>>> identities = np.arange(36)
>>> result = api.evaluate_feature_budget(spectra, labels, [500., 505., 510.], identities, budgets=(1,), folds=2, regularization=(1,), random_replicates=1)
>>> assert not result["curve"].empty
Audience: public.
compare_representations ¶
compare_representations(representations, labels, groups=None, *, domains=None, reference=None, **evaluation_options)
Compare paired same-row representations under identical grouped splits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
representations
|
dict
|
Mapping of names to finite (N, B) arrays with identical row identity/order; feature counts may differ. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
domains
|
array - like
|
Optional aligned site/year/domain labels for held-domain evaluation; held identities are purged globally from training. |
None
|
reference
|
str or None
|
Optional representation name used for paired differences; None selects the first supplied representation. |
None
|
evaluation_options
|
keyword arguments
|
Additional keyword options forwarded to evaluate_identifiability for each representation; domains must use the explicit argument. |
{}
|
Returns:
| Type | Description |
|---|---|
dict
|
Paired score summary, class metrics, detailed evaluations and reference name; synthetic representations remain diagnostic evidence. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: name->(N,B) finite arrays in identical observation order; labels/groups and optional held domains. Sampling unit: same held-out identity for every representation. Outputs: within and optional held-domain results, recall, dimensions, balanced accuracy and transfer penalties; differences vs reference. Assumptions: caller guarantees row alignment and paired preprocessing lineage; each classifier is separately nested and scaled using training rows only. Does not turn synthetic products into independent native-sensor validation.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> rng = np.random.default_rng(13)
>>> labels = np.repeat(["A", "B", "C"], 12)
>>> spectra = np.repeat(np.eye(3), 12, axis=0) + rng.normal(0, .01, (36, 3))
>>> identities = np.arange(36)
>>> result = api.compare_representations({"full": spectra, "subset": spectra[:, :2]}, labels, identities, folds=2, regularization=(1,))
>>> assert len(result["summary"]) == 2
Audience: public.
fit_ridge_fractions ¶
fit_ridge_fractions(spectra, fractions, groups=None, *, alphas=(1,), folds=3, seed=0, class_order=None)
Fit supervised multi-output ridge with explicit raw/projected predictions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
fractions
|
array - like
|
Nonnegative sum-one fraction coordinates, with classes/endmembers in the declared column order; shape requirements are given in Notes. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
alphas
|
sequence of positive float
|
Prespecified positive ridge penalties; multiple penalties require explicit independent parent-connected tuning groups. |
(1,)
|
folds
|
int
|
Number of grouped outer evaluation folds, or grouped tuning folds for the ridge fraction estimator; requires enough independent groups. |
3
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
Returns:
| Type | Description |
|---|---|
object
|
Fitted fraction model exposing predict(spectra), raw and simplex-projected predictions, fitted preprocessing/coefficients and tuning metadata. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: spectra (N,B), exact known simplex targets (N,C), positive alpha grid; groups are independent parent-connected bundles for synthetic training mixtures. Sampling unit: training mixture, with group-disjoint tuning if grid has >1 alpha. Outputs: fitted model with predict(), saved preprocessing/coefficient/intercept parameters and tuning memberships/scores. StandardScaler is refitted inside every tuning fold. Selection minimizes mean raw fraction MSE. Multiple alphas require explicit groups and grouped folds; a single alpha is prespecified. Assumptions: common units/support and no shared generating parent across groups; caller must form connected parent groups, not arbitrary mixture-row IDs. Does not establish unique physical inversion, calibrated uncertainty or field cover. Prediction returns both raw_prediction and projected_prediction.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> model = api.fit_ridge_fractions(np.eye(2), np.eye(2), alphas=(1,))
>>> prediction = model.predict([[.25, .75]])
>>> assert np.allclose(prediction["projected_prediction"].sum(axis=1), 1)
Audience: public.
fraction_diagnostics ¶
fraction_diagnostics(truth, predictions, *, class_order=None, detection_threshold=0.1, low_fraction=0.2, bins=(0, 0.1, 0.25, 0.5, 0.75, 1), groups=None, bootstraps=0, seed=0)
Separate known-fraction quantification from thresholded detection errors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
truth
|
array - like
|
Known nonnegative sum-one mixture fractions (N, C); these are synthetic targets, not independently measured field cover. |
required |
predictions
|
array - like
|
Finite predicted fraction matrix (N, C), in the same class order as truth; raw unconstrained predictions are accepted. |
required |
class_order
|
sequence or None
|
Explicit unique class-column order; None uses the function-specific canonical ordering. Preserve this order when comparing fraction arrays. |
None
|
detection_threshold
|
float
|
Fraction in (0, 1] at or above which the predicted class is declared detected. |
0.1
|
low_fraction
|
float
|
Upper positive truth-fraction bound in (0, 1] for low-abundance miss-rate summaries. |
0.2
|
bins
|
sequence of float
|
Strictly increasing calibration-bin edges spanning zero to one. |
(0, 0.1, 0.25, 0.5, 0.75, 1)
|
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
bootstraps
|
int
|
Nonnegative number of whole-group bootstrap resamples; positive values require at least two explicitly independent groups. |
0
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
Returns:
| Type | Description |
|---|---|
dict
|
Overall/per-class fraction errors, calibration bins, absent/low-positive detection summaries and optional whole-group intervals. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: truth (N,C) simplex and finite predictions (N,C), possibly raw; class ordering, detection/low-fraction thresholds and calibration bin edges. Sampling unit: mixture; supplied independent groups receive equal total weight and are resampled whole for percentile intervals on RMSE/bias. Shared parents require connected groups. Outputs: macro/per-class RMSE/bias, calibration bins, absent false-positive and low-positive miss rates, positive-only RMSE and CIs. Assumptions: synthetic truth is known; absent means exactly zero; detection is prediction >= threshold. Empty conditional denominators yield NaN. Bootstraps require explicit groups. Does not establish biological absence or field accuracy.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> result = api.fraction_diagnostics(np.eye(2), np.eye(2))
>>> assert result["overall"]["RMSE"] == 0
Audience: public.
evaluate_library_size ¶
evaluate_library_size(spectra, labels, groups=None, *, sizes=(10, 20), strategies=('balanced_random', 'farthest'), replicates=3, domains=None, folds=3, seed=0)
Evaluate retained identity-library capacity with fixed classifier/prior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectra
|
array - like
|
Finite observations-by-features matrix (N, B) on a common spectral support and scale; rows must align with labels and identity metadata. |
required |
labels
|
array - like
|
Nonmissing class/category labels with one value per spectrum; repeated identities must have a consistent label. |
required |
groups
|
array - like
|
Aligned independent-unit identifiers; keep repeated observations or parent-connected mixtures in the same group. None uses the function-specific row-based convention described in Notes. |
None
|
sizes
|
sequence of int
|
Positive total counts of retained training identities; each must fit within every evaluated training fold. |
(10, 20)
|
strategies
|
sequence of str
|
Library selection strategies drawn from 'random', 'balanced_random', and 'farthest'; selection uses training identities only. |
('balanced_random', 'farthest')
|
replicates
|
int
|
Positive number of seeded repetitions for parent selection or library-size sampling. |
3
|
domains
|
array - like
|
Optional aligned site/year/domain labels for held-domain evaluation; held identities are purged globally from training. |
None
|
folds
|
int
|
Number of grouped outer evaluation folds, or grouped tuning folds for the ridge fraction estimator; requires enough independent groups. |
3
|
seed
|
int
|
Random-number seed for reproducible sampling, splits or resampling; it does not create independent observations. |
0
|
Returns:
| Type | Description |
|---|---|
dict
|
Metrics and selected-identity DataFrames plus fixed-classifier description; unsupported classes are explicit rather than scored as valid. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the supplied options, dimensions, support or provenance violate the input contract. |
Notes
Inputs: finite spectra/labels/identities; total library sizes, strategies random, balanced_random or farthest; optional held-domain metadata. Sampling unit: held-out identity; training histories collapse to identity means. Outputs: fold/size/strategy/replicate scores, selected IDs and coverage distances. Farthest uses training-standardized Euclidean distance, seeded one per class; balanced_random cycles classes uniformly. Random is unconditional; missing a class produces explicit unsupported status rather than a misleading score. Assumptions: fixed C=1 regularized classifier; sizes are predeclared, selection and coverage use training rows only. Coverage distances use full-training scale. Does not isolate every model/prior confound or establish universal best size.
See Also
spectralbridge.library_analysis.constrained_unmixing : Related source-derived API contract.
Examples:
All spectra below are invented teaching data, not empirical validation.
>>> import numpy as np
>>> from spectralbridge import library_analysis as api
>>> rng = np.random.default_rng(13)
>>> labels = np.repeat(["A", "B", "C"], 12)
>>> spectra = np.repeat(np.eye(3), 12, axis=0) + rng.normal(0, .01, (36, 3))
>>> identities = np.arange(36)
>>> result = api.evaluate_library_size(spectra, labels, identities, sizes=(6,), strategies=("balanced_random",), replicates=1, folds=2)
>>> assert not result["metrics"].empty