geoml.likelihood

class geoml.likelihood.Gaussian(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Gaussian likelihood.

Equivalent to a squared error model. The latent variable maps to the mean, while the noise variance is a parameter.

class geoml.likelihood.Laplace(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Laplace’s likelihood.

Equivalent to a linear error model. The latent variable maps to the mean, while the distribution’s scale factor is a parameter.

class geoml.likelihood.Gamma(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Gamma likelihood.

Used for strictly positive variables. The latent variable is shifted by a parameter and then mapped to the distribution’s shape. The rate parameter is fixed at 1.0.

class geoml.likelihood.StudentT(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Student-T likelihood.

A heavy-tailed distribution. The latent variable maps to the mean, while the scale and degrees of freedom are parameters.

class geoml.likelihood.EpsilonInsensitive(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Epsilon-insensitive likelihood.

Similar to the Laplace likelihood, with an addition epsilon parameter, below which error are not penalized. Can be used to obtain a model similar to the Support Vector Machine.

class geoml.likelihood.Huber(warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

Huber’s likelihood.

Based on the Huber loss.

class geoml.likelihood.MultivariateGaussian(n_components, warping=None, sharpness=1)[source]

Bases: Gaussian

class geoml.likelihood.MultivariateLaplace(n_components, warping=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

class geoml.likelihood.MultivariateEpsilonInsensitive(n_components, warping=None, sharpness=1)[source]

Bases: EpsilonInsensitive

class geoml.likelihood.MultivariateHuber(n_components, warping=None, sharpness=1)[source]

Bases: Huber

class geoml.likelihood.Mixture(warping, n_components=2, family='gaussian', separation=3.0, weights=None, contamination=None, sharpness=1)[source]

Bases: _ContinuousLikelihood

A likelihood whose noise is a mixture of scales.

The noise on a measurement comes from one of n_components copies of family, all sharing the latent location and differing in width, with trainable proportions. It fits data whose scatter is not one number – a careful assay and a rushed one, a fresh core and a weathered one – and, unlike a heavy-tailed likelihood, it says which mechanism each measurement came from (responsibilities()).

Parameters:
  • warping (geoml.warping.Warping) – The mixture’s own warping, applied once to the data. It sizes the mixture, and the components with it.

  • n_components (int) – How many noise scales, at least two.

  • family (str) – The distribution every component takes: “gaussian”, “laplace”, “studentt”, “epsiloninsensitive” or “huber”.

  • separation (float) – How much wider each component is than the one before it, at construction. Only the family’s width parameters move.

  • weights (array-like, optional) – Initial mixing proportions, one per component, summing to one. Default: 0.95 on the narrowest, the rest split evenly.

  • contamination (list of bool, optional) – Which components describe error rather than ground. Default: none of them. At least one component must be genuine.

  • sharpness (int) – Data augmentation factor, as in every likelihood.

components

The noise scales, narrowest first.

Type:

list of _ContinuousLikelihood

contamination

Which of them describe error rather than ground.

Type:

list of bool

Raises:

ValueError – If fewer than two components are asked for, if family is not one of the names above, if the contamination flags do not match the components, or if every component is marked as contamination.

See also

responsibilities

which component each measurement came from.

geoml.warping.ZScore

pair the mixture with robust=True.

Notes

The mixture is over the row. In a vector or compositional variable the columns are one observation, so the densities are multiplied across them before the components are weighted, giving one responsibility per location rather than one per element. The components’ scales stay per column. That density does not factorize, so a vector mixture takes its latent expectation over the joint posterior samples rather than each column’s quadrature.

Contamination is declared, not assumed. By default every component describes the ground and the mixture is a noise model. Marking a component as contamination says its readings replace a measurement rather than report one: integrated_backward() then leaves it out of the value while keeping it in the spread reported beside it. Training and measurement_samples() always use the full mixture.

Components of equal width do not pull apart in training, which is why separation spreads them at construction. Pair the mixture with a warping led by ZScore(size, robust=True), so that a gross outlier cannot set the scale everything else is normalized by.

References

Kuss, M. (2006) Gaussian Process Models for Robust Regression, Classification, and Reinforcement Learning. PhD thesis, TU Darmstadt.

Stegle, O., Fallert, S. V., MacKay, D. J. C. and Brage, S. (2008) Gaussian process robust regression for noisy heart rate data. IEEE Transactions on Biomedical Engineering 55(9), 2143-2151.

Examples

>>> warping = geoml.warping.ChainedWarping(
...     geoml.warping.ZScore(1, robust=True),
...     geoml.warping.Spline(1))
>>> likelihood = geoml.likelihood.Mixture(
...     warping, n_components=2, contamination=[False, True])
responsibilities(latent_mean, latent_variance, values)[source]

Posterior probability that each row came from each component.

One answer per row: the densities are multiplied across the columns before the components are weighted, as the likelihood fits them.

Parameters:
  • latent_mean (ArrayLike) – The model’s posterior at the measured locations, of shape (n_data,) or (n_data, size), as predict stores them.

  • latent_variance (ArrayLike) – The model’s posterior at the measured locations, of shape (n_data,) or (n_data, size), as predict stores them.

  • values (ArrayLike) – The measurements, in their own units, of the same shape.

Returns:

ndarray – Of shape (n_data, n_components), rows summing to one.

Return type:

NDArray[float64]

See also

geoml.models.VGPNetwork.responsibilities

the way in from a container, which also files the answer on the variable.

Notes

The latent expectation is taken column by column, off the marginals a prediction stores, so several columns are treated as independent. Read the result on data the model has not seen: at a training location the model interpolates its own measurement.

class geoml.likelihood.LikelihoodMixture(components, weights=None, shares='fixed')[source]

Bases: _Likelihood

A mixture of whole likelihoods, each with its own latent value.

Every measurement comes from exactly one population, chosen by its value rather than its place, so the populations cross and overlap anywhere and a prediction is a mixture – multimodal where they separate (the overlapping mixture of GPs of Lázaro-Gredilla et al., 2012). Not to be confused with Mixture, which mixes several noise widths around one latent value through one warping: here each population reads its own latent columns and brings its own family, noise and warping, so two populations may differ in skew as well as in location.

Population k reads the next components[k].size latent columns, in the order given; under shares=”latent” one more column per population follows them, whose softmax, scaled by a trained amplitude and moved by a trained bias per population, is the share of each population from place to place – the bias being what the shares return to away from the data. A shared warping is the same object given to every component. The share columns are best read from a GP of their own, apart from the populations’, which a categorical likelihood on a logged domain may also read.

Parameters:
  • components (Sequence[_ContinuousLikelihood]) – Two or more continuous likelihoods, one per population, all reading the variable’s number of columns.

  • weights (_types.ArrayLike | None) – The populations’ shares under shares=”fixed”, summing to one; equal by default, and set from the data by initialize.

  • shares (str) – “fixed”, one share per population over the whole model, or “latent”, shares read from latent columns, so that they change from place to place.

Notes

The bound at each row is log Σ_k π_k exp(E_q[log p_k(y | f_k)]), each population’s density in data space with its own warping’s Jacobian; with latent shares it is averaged over the share columns’ realizations. Realization s holds one point u_s in (0, 1), interleaved, and at each location belongs to the population whose interval of its own cumulative shares holds it – the same population everywhere when the shares are fixed, one that changes where its share field crosses the point when they are latent. Either way the fraction of realizations in a population is the expected share, so the plain ensemble is the mixture.

References

Lázaro-Gredilla, M., Van Vaerenbergh, S. and Lawrence, N. D. (2012). Overlapping mixtures of Gaussian processes for the data association problem. Pattern Recognition, 45(4), 1386-1395.

warped = True
log_lik(mu, var, y, has_value, samples=None, *args, latent_gaussian=True, **kwargs)[source]
labels(n_sim)[source]

Which population each of n_sim realizations belongs to, under fixed shares (the same everywhere).

Return type:

ndarray

predict(mu, var, sims, explained_var, *args, include_noise=True, n_splits=None, cutoffs=None, jitter=None, **kwargs)[source]
measurement_samples(sims, n_nodes=32, shift=None, jitter=None, jitter_shift=None)[source]

What a measurement at each location would read.

A prediction reports the ground, the noise having been integrated out, so its simulations are intervals for a quantity no assay ever observes. This keeps the node values instead of averaging them, which is the same computation stopped one step earlier: n_sim * n_nodes equally likely values per location, the exact predictive distribution of a sample. It is what any comparison against measured data needs – an accuracy plot, a cross-validation – and it is meant for the few thousand locations that carry measurements, never for a block model.

shift – uniforms of shape (n, size, n_sim), one per location, component and realization – rotates the noise nodes so that the sample is unbiased in every moment and independent between locations; see _measurement_nodes. The model’s doors draw it from the model’s seed. Without it every location in a column carries the same noise value: fine for reading one location, wrong for anything read across several – a variogram, a regional mean.

jitter, (rows, variables), is the latent variance the realizations leave out because a GP node’s input is uncertain; each node then carries a draw of it beside its noise value (see _jitter_draws), rotated by jitter_shift, (rows, 1, n_sim).

Returns:

(rows, variables, n_sim * n_nodes)

responsibilities(latent_mean, latent_variance, values)[source]

Posterior probability that each row came from each population.

Parameters:
  • latent_mean (ArrayLike) – The latent posterior at the measured locations, (n, size).

  • latent_variance (ArrayLike) – The latent posterior at the measured locations, (n, size).

  • values (ArrayLike) – The measurements, in their own units, (n, columns).

Returns:

ndarray – Of shape (n, n_populations), rows summing to one.

Return type:

NDArray[float64]

initialize(y, weights=None)[source]

Starts the populations apart: the rows clustered into as many groups as there are populations, each component’s warping started on its own group, the shares – fixed, or the latent shares’ bias – on the groups’ sizes.

The clustering is on each column through a Yeo-Johnson power transform, standardized, so a skewed grade splits into its populations rather than its outliers while the gap between them survives; seeded from the package generator.

class geoml.likelihood.Bernoulli(shift=0, sharpness=1)[source]

Bases: _Likelihood

__init__(shift=0, sharpness=1)[source]

Bernoulli’s likelihood.

Used for binary categorical variables.

Parameters:
  • shift (double) – How much to favor the positive or negative class. Value between -5 and 5.

  • sharpness (int) – Data augmentation. The weight of the data is multiplied by this factor. Results in sharper transitions between positive and negative regions.

log_lik(mu, var, y, has_value, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, n_splits=None, *args, **kwargs)[source]
classmethod one_class(sharpness=1)[source]
class geoml.likelihood.BernoulliMaximumMargin[source]

Bases: _Likelihood

A two-class likelihood with a margin, after a support vector machine’s.

A logistic of the latent value whose slope doubles inside the margin, between minus one and plus one, so samples are pushed out of it: past plus one for one class and below minus one for the other, where a sample on its own side costs little. c_rate, trained, sets the slope.

log_lik(mu, var, y, has_value, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, n_splits=None, *args, **kwargs)[source]
cdf(x)[source]
class geoml.likelihood.CategoricalGaussianIndicator(n_components, tol=0.001, sharpness=1, bias=False)[source]

Bases: _CategoricalLikelihood

Gaussian likelihood for indicator variables.

Assumes mutually exclusive categories (i.e. no geological rules), leading to maximum entropy far from the data points – or, with a trained bias per category, to the proportions the bias settles on. Is capable of dealing with boundary data.

__init__(n_components, tol=0.001, sharpness=1, bias=False)[source]

Initializer for CategoricalGaussianIndicator.

Parameters:
  • n_components (int) – The number of categories.

  • tol (double) – Normal score tolerance for boundary data.

  • sharpness (int) – Data augmentation. The weight of the data is multiplied by this factor. Results in sharper transitions between categories.

  • bias (bool) – Whether each category’s latent value is shifted by a trained constant, so that where the latent values return to zero, away from the data, the categories take the proportions the bias gives them rather than equal ones.

log_lik(mu, var, y, has_value, is_boundary=None, samples=None, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, n_splits=None, *args, **kwargs)[source]
class geoml.likelihood.HierarchicalGaussianIndicator(n_components, tol=0.001, sharpness=1, bias=False)[source]

Bases: CategoricalGaussianIndicator

Gaussian likelihood for indicator variables with geological rules.

Assumes a priority order among categories, so that a point at which a higher priority category is positive will automatically be negative for the lower priority ones. This allows the modelling of intrusions by giving a high priority to the intruding rock, and depositions by giving a low priority to the deposited layer, making it conform to the geometry of the rocks below it.

The priority is defined by the order of the labels in the data object, from lowest to highest.

log_lik(mu, var, y, has_value, is_boundary=None, samples=None, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, n_splits=None, *args, **kwargs)[source]
class geoml.likelihood.OrderedGaussianIndicator(levels, tol=1e-06, sharpness=1)[source]

Bases: _CategoricalLikelihood

Gaussian likelihood for indicator variables of conformable layers.

By assuming conformable layers, it is possible to model multiple categories with a single latent variable. The thresholds that define the contacts are determined during training. It is useful to add a linear trend to the network’s output.

__init__(levels, tol=1e-06, sharpness=1)[source]

Initializer for OrderedGaussianIndicator.

Parameters:
  • levels (int) – Number of conformable surfaces, one less than the number of rock layers.

  • tol (double) – Normal score tolerance for boundary data.

  • sharpness (int) – Data augmentation. The weight of the data is multiplied by this factor. Results in sharper transitions between categories.

get_thresholds()[source]
log_lik(mu, var, y, has_value, samples=None, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, n_splits=None, *args, **kwargs)[source]
class geoml.likelihood.GradientIndicator(tol=0.001)[source]

Bases: _Likelihood

log_lik(mu, var, y, has_value, samples=None, *args, **kwargs)[source]
predict(mu, var, sims, explained_var, *args, **kwargs)[source]