mescla.emma.archetypes

Archetypal analysis: data-driven candidates for end-members.

EMMA counts the sources and tells you which species behave as a mixture, but it cannot say where the vertices of the mixing simplex are. In practice that gap is filled by taking the most extreme samples in U-space and asking which combination encloses the most samples (mescla.emma.endmembers.suggest_endmembers()). Archetypal analysis (Cutler & Breiman, 1994) is the optimised form of exactly that step: it finds the k points on the convex hull that best reconstruct the whole data set, where each archetype is itself a convex combination of real samples.

\[X \approx A Z, \qquad Z = B X, \qquad A \ge 0,\; \sum_j A_{ij} = 1, \qquad B \ge 0,\; \sum_i B_{ji} = 1\]

The rows of \(A\) are non-negative and sum to one, and \(Z\) holds hull points – which is the mixing model’s geometry, imposed by the objective rather than checked afterwards. That is what makes this method, and not a clustering algorithm, the right unsupervised tool here.

Five cautions, each enforced or reported by the code below

1. The weights are not mixing ratios. They are reconstruction weights in standardised space: no error model, no per-species sigma, no distinction between a tracer you trust and one you do not. They will look exactly like the output of mescla.mixing.lsq.mixing_ratios() and they mean something weaker. ArchetypeResult.ratios therefore raises; hand ArchetypeResult.as_endmembers() to a real estimator instead.

2. Archetypes are still less extreme than the sources they stand for. Noise makes measured waters look more mixed than they are, and archetypes are fitted to the samples, so they shrink inward too. This method improves vertex selection; it does not do vertex correction. That remains the job of the maximum-likelihood estimator in mescla.mixing.ml.

3. It proposes, it does not discover. The objective knows nothing about hydrology. Use it after the conceptual model is written down, as a check on the candidates it names – never as a way to find out how many sources there are and what they might be.

4. The objective is not convex. The answer depends on the starting point, so seed is explicit, restarts are recorded, and archetype_stability() exists to ask whether the vertices come back. Instability is itself evidence that n_archetypes is wrong.

5. It minimises reconstruction error, not enclosure. suggest_endmembers() ranks vertex sets by the fraction of samples they bound; this minimises squared error, which a single very concentrated analysis can dominate. The two disagree exactly when such a sample is present, and an archetype set can therefore enclose fewer samples than a hand-picked one. Compare ArchetypeResult.hull_fraction with hull_fraction() of your candidates every time. A large disagreement is a reason to go and look at the sample the optimiser latched onto, not a verdict on either method.

References

Cutler, A. and Breiman, L. (1994). Archetypal analysis. Technometrics 36 (4), 338-347.

Morup, M. and Hansen, L. K. (2012). Archetypal analysis for machine learning and data mining. Neurocomputing 80, 54-63. (The FurthestSum initialisation used here.)

Functions

archetypal_analysis

Fit n_archetypes hull points to water samples.

archetype_rss_curve

Residual sum of squares against the number of archetypes.

archetype_stability

Refit from different seeds and ask whether the same vertices come back.

Classes

ArchetypeResult

Archetypes fitted to a set of water samples.