bayesian_models package

Submodules

bayesian_models.models module

class bayesian_models.models.BEST(nan_handling: str = <factory>, cast: ~numpy.dtype | None = <factory>, group_var: str | int | None = <factory>, effect_magnitude: bool = False, std_difference: bool = False, common_shape: bool = True, multivariate_likelihood: bool = False, _data_processor: ~bayesian_models.data.Data | None = <factory>, _initialized: bool | None = <factory>, _trained: bool | None = <factory>, save_path: str | None = None)

Bases: BESTBase

Bayesian Group difference estimation with pymc.

Kruschke’s Bayesian Estimation Superceeds the t-Test (BEST) model implementation for estimating differences between groups. The implementation is based on the official pymc documentation.

The model assumes StudentT likelihood over observations for added robustness. See the discussions section Bayesian Estimation Superceeds The t Test (BEST) for a more in depth explanation and motivation for this model

Class Attributes:

  • WarperFunction := Type definition

  • std_upper:float = 1e1 := Upper boundary for the standard deviations prior
  • std_lower:float = 1e0 := Lower boundary for standard deviations prior

Note

The original model has exceedingly wide priors:

\[\sigma_k \thicksim \mathcal{U}(10^{-3}, 10^{3})\]

These defaults are not sensible for most applications. [0.1-10] boundaries are implemented as defaults instead

  • ν_λ:float = 1/29.0 := Exponential decay parameter for the ν prior
  • ν_offset:float = 1 := Offset parameter for the ν prior. Since \(\nu \in [1,+ \infty])\) this should be left unchanged
  • ddof:int = 1 := Degrees of freedom parameter for empirical pooled standard deviations
  • std_diffusion_factor:int = 2 := Scalar multiplier for empirical pooled standard deviations on the μ prior. Controls how diffuse the prior is
  • zero_offset:float = 1e-4 := Small offset parameter to avoid numerical errors with pooled standard deviations
  • jax_device:str = ‘gpu’ := numpyro parameter for alternate sampling. Controls which device numpyro will use
  • jax_device_count: int =1 := numpyro setting. Number of devices to be used for HMC sampling (parallel)

Attention

Due to persistent problems with the numpyro dependency these parameters are ignored

Object Attributes:

  • group_var:str := Coordinate label for the categorical variable to group by

    Danger

    Due to issues with the underlying pymc implementation and limitations of numpy.isnan the categorical variables’ levels should be recorded as something castable to a float, if numpy array is used to store the data. It is recommended that a pandas.DataFrame be used instead

  • effect_magnitude:bool=False := Whether to compute an ‘effect size’ during inference. This metric is somewhat more more difficult to interpret, since it is no longer in the original units and is defined as:
    \[E=\dfrac{\Delta\mu_{1,2}}{\sqrt{\dfrac{ \sigma_{1}^{2}\sigma_{2}^{2}}{2}}}\]
  • std_differences:bool=False := Selects whether or not to estimate standard deviation differences between groups. Optional. Defaults to False. If effect_magnitude=True this value is ignored and the difference is computed automatically.
  • common_shape:bool=True := If True make the simplifying assumption that all input dimensions have the same shape parameter ν. Else, assign distinct shape parameters to all dimensions of the input array. Optional. Defaults to True. If switched off, warns of likely unidentified model.
  • multivariate_likelihood:bool=True := Flag signaling whether to use a multivariate likelihood or a univariate one. Optional.Defaults to False (use univariate likelihoods).

    Note

    The multivariate likelihood is always assumed to have a diagonal scale matrix. Hence this option is equivalent to independent univariates with the common degrees of freedom assumption, but is more computationally expensive and should be avoided

  • save_name:Optional[str]=None := A string specifying location and filename to save the model’s inference results. Optional. If set during objects’ construction, the save method may be called without an explicit save_path argument.
  • idata:Optional[arviz.InferenceData]=None := arviz.InferenceData object containing the results of model inference. Becomes set after calling the fit method
  • trained:bool=False := Sentinel signaling whether the model has been trained or not. Defaults to False. Should be switched on after calling fit. Prevents predict from being called on an object that has not been trained.
  • initialized:bool=False := Sentinel signaling whether the model has been full initialized. Defaults to False. Should be set after the object is called. Prevents fit and predict from being called prior to complete initialization.

Private Attributes:

  • var_names:dict[str:list[str]] := A dictionary with the ‘means’, ‘stds’ and ‘effect_magnitude’ keys, mapped to lists of the variables
  • _permutations:Optional[Iterable[tuple[str,str]]]=None := An iterable of groups per group_var. Contains all unique pairs of unique values of group_var.
  • _n_perms:Optional[int]=None := The number of groups.
  • levels:Optional[Iterable[str]] = None := Grouping variable levels. All unique values of group_var.
  • _ndims:Optional[int]=None := Number of input features. Only meaningful if common_shape is False.
  • num_levels:Optional[int]=None := The number of unique groups/ values of group_var.
  • coords := dict-like of dimension labels xarray coords. Will be inferred from inputs and used to label the posterior
  • _group_distributions:Optional[Dict[str, pymc.Distribution]]=None := A dict used internally to map inferred distributions. Defaults to None.
  • _model:Optional[pymc.Model] := The pymc.Model object

Object Methods:

  • __init__:= Begin initializing the object by setting all options, parameters and hyperparameters
  • __call__(data) := Initialize the model by specifying the full probability model according to options passed to __init__. Accepts a data structure and a label indicating the variable that defines the groups
  • fit(sampler, *args, **kwargs) := Perform inference on the model. sampler is valid sampler, i.e. pymc.sample or pymc.sampling.jax.sample_numpyro_nuts. All other arguments are forwarded to the sampler. Returns a arviz.InferenceData object containing the results of inference. Sets the trained and idata attributes
  • predict(var_names:Iterable[str], ropes:Iterable[tuple[float, float]], hdis=Iterable[float])->dict[str, pandas.DataFrame] := Compute results of group comparisons and return a dictionary mapping derived metrics to pandas.DataFrame objects containing inference summary. Decisions are made using the ROPE+HDI rule. Returns a dictionary mapping derived variable labels to pandas DataFrames containing the results. Accepts per variable rope limits and hdis. See the function for more details on these and other options
  • summary := Wrapper for arviz.summary. Returns summary results of model inference
  • plot_posterior := Wrapper for arviz.plot_posterior. Plot the inferred posterior
  • plot_trace := Wrapper for arviz.plot_trace. Plot inference results
  • _consistency_checks_ := Check that model parameters and hyperparameters are consistent and compatible
  • _preprocessing_ := Preprocess data. Delegates to the data module and calls the specified processor to preprocess the data
  • _fetch_differential_permutations_ := Compute all unique pairs of groups.

Class Methods:

Setters for all class attributes. Named set_attribute

  • set_std_upper(val:float)->None := Update the std_upper class attribute
  • set_std_lower(val:float)->None := Update the std_lower class attribute
  • set_shape_offset(val:float)->None := Update the ν_offset class attribute

    Caution

    Should generally not be modified

  • set_jax_device(device:str)->None := Update the jax_device class attribute
  • set_jax_device_count(val:int)->None := Update the jax_device_count class attribute
  • set_diffusion_factor(val:float)->None := Update the std_diffusion_factor attribute
  • set_degrees_of_freedom(val:int)->None := Update the ddof class attribute
cast: dtype | None
common_shape: bool
property coords: dict[str, Any] | None
effect_magnitude: bool
fit(*args, sampler=<function sample>, **kwargs) InferenceData

Perform inference by sampling from the posterior. infer is an alias for fit

Args:

  • sampler=pymc.sample := The pymc sampler to run MCMC with. Optional. Defaults to pymc.sample
  • *args:tuple[Any] := Arguements to be forwarded to the sampler
  • **kwargs:dict[str, Any] := Optional keyword arguments to be forwarded to the sampler

Returns:

  • idata:arviz.InferenceData := The results of inference

Raises:

  • RuntimeError := If called before fit has been called

Warns:

  • If any divergences are detected

group_var: str | int | None
property idata: InferenceData | None
infer(*args, sampler=<function sample>, **kwargs) InferenceData

Perform inference by sampling from the posterior. infer is an alias for fit

Args:

  • sampler=pymc.sample := The pymc sampler to run MCMC with. Optional. Defaults to pymc.sample
  • *args:tuple[Any] := Arguements to be forwarded to the sampler
  • **kwargs:dict[str, Any] := Optional keyword arguments to be forwarded to the sampler

Returns:

  • idata:arviz.InferenceData := The results of inference

Raises:

  • RuntimeError := If called before fit has been called

Warns:

  • If any divergences are detected

property initialized: bool
load(save_path: str | None = None) None

Load a pre trained model from the disk

Only meaningful for models saved with the ‘netcdf’ method. Otherwise, use ‘pickle’ directly instead

Caution

Not checks are being made that the posterior trace is compatible with model object

Args:

  • save_path:Optional[str] := File path to load the model from. If save_path has been provided at object initialization, it can be ignored

Returns:

  • None

classmethod mean(data, axis: int = 0)
property model: Model | None
multivariate_likelihood: bool
nan_handling: str
nan_present_flag: bool | None
num_levels: int | None
plot_posterior(*args, **kwargs)

Wrapper for arviz.plot_posterior

Plot Posterior densities in the style of John K. Kruschke’s book.

Args:

  • *args:tuple[Any] := Arguments to be forwarded to arviz.plot_posterior
  • **kwargs:dict[str, Any] := Keyword arguments to be forwarded to:code:arviz.plot_posterior

Returns:

  • graph:Any := The posterior plot object

plot_trace(*args, **kwargs)

Wrapper for arviz.plot_trace

Plot distribution (histogram or kernel density estimates) and sampled values or rank plot. If divergences data is available in sample_stats, will plot the location of divergences as dashed vertical lines.

Args:

  • *args:tuple[Any] := Arguments to be forwarded to arviz.plot_trace
  • **kwargs:dict[str, Any] := Keyword arguments to be forwarded to arviz.plot_trace

Returns:

  • plot:Any := Trace plot object

predict(var_names: Sequence[str] = ['Δμ'], ropes: Sequence[tuple[float, float]] = [(-0.1, 0.1)], hdis: Sequence[float] = [0.95], multilevel_on: str = '[', extend_summary: bool = True)

Render decisions on group differences, according to the ROPE+HDI rule:

  • HDI in ROPE := Not Significant (All plausible values are equivalent to 0)

  • HDI & ROPE == () := Significant (No plausible value is equivalent to zero)

  • HDI & ROPE != HDI :math:lor () := Withhold decision (‘Indeterminate’) (Some plausible values are equivalent to zero, other are not)

Aggregates results in a dictionary, mapping deterministic variable names to results dataframes. ROPE and HDI threshold limits are set on a dataframe wide level

Example usage:

from sklearn.datasets import load_iris
from bayesian_models.models import BEST
import pandas as pd

X, y = load_iris(return_X_y=True, as_frame=True)
names = load_iris().target_names
Y = y.replace(
    {i:name for i, name in enumerate(names)}
    )
df = pd.concat([X, Y], axis=1)
df.columns=df.columns[:-1].tolist()+["species"]
# Data
#        sepal length (cm)   ...   species
#    0                  5.1  ...   setosa
#    1                  4.9  ...   setosa
#    2                  4.7  ...   setosa
#    3                  4.6  ...   setosa
#    4                  5.0  ...   setosa
#    ...                ...  ...     ...
#    145                6.7  ...   virginica
#    146                6.3  ...   virginica
#    147                6.5  ...   virginica
#    148                6.2  ...   virginica
#    149                5.9  ...   virginica

obj = BEST()(df, "species")
obj.fit()
results = obj.predict() # Only 'Δμ' by default
print(results['Δμ'])
# Output
#                                            Significance
# Δμ(setosa, versicolor)  sepal length (cm) Indeterminate
#                        sepal width (cm)   Indeterminate
#                        petal length (cm)  Indeterminate
#                        petal width (cm)   Indeterminate
# Δμ(setosa, virginica)  sepal length (cm)  Indeterminate
#                        sepal width (cm)   Indeterminate
#                        petal length (cm)  Indeterminate
#                        petal width (cm)   Indeterminate
# Δμ(versicolor, sepal length (cm)          Indeterminate
#                       sepal width (cm)    Indeterminate
#                        petal length (cm)  Indeterminate
#                        petal width (cm)   Indeterminate

Args:

  • var_names:Iterable[str]=[‘Δμ’] := An iterable of derived metrics to return. Optional. Defaults to returning expected difference. Default names are ‘Δμ’ for the difference of means, ‘Δσ’ for the difference of standard deviations and ‘Effect_Size’ for Kruschkes effect size.
  • ropes:Iterable[tuple[float, float]] := An Iterable of length-2 tuples of floats, defining the Region Of Practical Equivalence. Each rope is applied to all features for every variable in var_names.
  • hdis:Iterable[float] := An iterable of non-negative floats defining the probability threshold for the credible interval. Is applied to all features for each variable in var_names
  • multilevel_on:str=’[’ := A separator defining the multilevel index. pymc by default concatinates the label according to the form: {var_name}[{feature_label}]. The argument will reindex them in a multilevel fashion of the form (var_name, feature_label) in the resulting dataframe. Set to None to disable this behavior.
  • extend_summary:bool=True := If True the new Significance column extends the summary dataframe. Else return a new dataframe containing only the Significance results. Optional. Defaults to True and returns an extended version of the summary.

Returns:

  • results:dict[str,pandas.DataFrame] := Decision results. Returned in the form of dictionary, whose keys are the names of deterministic quantities (i.e. ‘Δμ’ ‘Δσ’ ‘E’ ‘ν’). Items are pandas.DataFrame object containing summary results (like those returned by arviz.summary) with an additional column, named Significance containing the decision
save(save_path: str | None = None, method: str = 'netcdf') None

Save the model object for later reuse

Available save methods are ‘netcdf’ and ‘pickle’. The latter is discouraged and has known problems. For the ‘netcdf’ method the posterior trace will be saved.

Caution

At present, no checks are being made to verify that the posterior is compatible with the model object

Args:

  • save_path:Optional[str] := The file path to save the model to. If save_path has been provided at model initialization, need not be provided
  • method:str=’netcdf’ := Which method to use to save the model. For the ‘netcdf’ method, only the posterior trance is save and consequently reloaded. For the ‘pickle’ method, attempts to serialize the entire model. The latter case should be avoided

Returns:

  • None

save_path: str | None
classmethod set_degrees_of_freedom(val: int) None
classmethod set_diffusion_factor(val: float) None
classmethod set_jax_device(device: str) None
classmethod set_jax_device_count(val: int) None
classmethod set_mean_of_means(func: Callable[[...], ndarray[Any, dtype[ScalarType]]]) None
classmethod set_shape_factor(val: float) None
classmethod set_shape_offset(val: float) None
classmethod set_std_lower(val: float) None
classmethod set_std_of_means(func: Callable[[...], ndarray[Any, dtype[ScalarType]]]) None
classmethod set_std_upper(val: float) None
classmethod std(data, ddof: int | None = None, scale: int | None = None, zero_offset: float | None = None, axis: int = 0)
std_difference: bool
summary(*args, **kwargs) DataArray | DataFrame

Wrapper for arviz.summary(idata)

Args:

  • *args:tuple[Any] := Arguments to be forwarded to arviz.summary
  • **kwargs:dict[str, Any] := Keyword arguments to be forwarded to arviz.summary

Returns:

  • summary_results:xarray.DataArray := Summary results

property trained: bool
var_names: dict[str, list]
static warp_input(data, row_indexer, column_indexer, transform, unwrap: bool = True)

Utility method that selects a subset of the data and applies transform one it.

Used to supply the data or values extracted form the data(mean, standard deviation) to the computation graph

Args:

  • data:Any := The data to process
  • row_indexer:Any := Indexer for row selection
  • column_indexer:Any := Indexer for column selection
  • transform:Callable:= A callable that takes a data structure and returns a data structure
  • unwrap:bool=True := When True unwraps the resulting pandas.DataFrame to the underlying numpy.NDArray object. Optional. Defaults to True and returns a numpy array object

Returns:

  • ndf:bayesian_models.Data := A group of the original Data
  • warped_input:bayesian_models.Data := The output of transform
class bayesian_models.models.BayesianEstimator

Bases: BayesianModel

Abstract base class for “predictive” style models.

These models take some input information X and return some output predicted quantity Y.

abstract property posterior_trace
class bayesian_models.models.BayesianModel

Bases: ABC

Abstract base class for all Bayesian Models in pymc.

Defines a common API for all model objects

Object Methods:

  • __init__ := Begin initializing the model by setting all of the models parameters and hyperparameters. If a model has multiple variations, these are set here. The subclass should define valid hyperparameters as class or object attributes. Object level properties should be preferred where a user is expected to need to change these parameters for a single dataset. Class level parameters are preferred where a user is likely to want to apply the same model to multiple data (with the same parameters)
  • __call__ := Initialize the object by specifying the full probability model for inference. This method should also receive the training data. These should be set using pymc.Data containers. The data received should be placed in a Data container, supplied by the data submodule for preprocessing/ For most simple, and predictive models, that accept some input information and attempt to predict some output quantity, the inputs should be declared as mutable shared tensors pymc.Data(name, X, mutable=True) and the predict method should invoke pymc.set_data(inputs) to replace the input tensor with a new one. For other special cases see the predict method. Should return the object itself for easy method chaining. Should set the objects’ initialized property to signal that the fit method can be called.
  • fit := Sample from the posterior according to the sampler argument. Forwards all other arguments to the sampler, sets the models’ idata and trained flag, signaling the predict and other posterior methods can be called. infer is an alias for fit
  • predict := Produce output from the model. The implementation details of this method, vary depending on the model.
    • For predictive type models that attempt to predict some Y based on some X, this method should sample from the posterior predictive and return an appropriate Y.
      • For most simple models should call pymc.set_data(dict(inputs=X_new)) and sample y_obs from the posterior predictive.

        Example:

        def predict(self, Xnew, ...):
            with self.model:
                pm.set_data(dict(inputs=Xnew))
                y = pm.sample_posterior()
            return y
        
      • For models with special predictive APIs like Gaussian Process models, should declare a new variable as a shared tensor pymc.Data(X_new, mutable=True) the first time predictions are made, additional nodes corresponding to the special API (i.e. gp.condintional) and any further postprocessing nodes corresponding to data transforms and response functions. Further calls to this method should invoke pymc.set_data to replace the previous inputs with the new ones followed by pymc.sample_posterior_predictive.

        Example:

        def predict(self, Xnew):
            with self.model:
                if not self.predictive_initialized:
                    predicted = pm.Data(
                        'predicted',
                        Xnew, 
                        mutable=True
                        )
                ...
                ynew = pm.sample_posterior_predictive()
                return ynew
        
      • For non-predictive models (i.e. oversampling models, statistical comparison models etc), data node(s) are immutable and predict should perform the equivalent operation for these models (i.e. render importance decisions), yield augmented or rebalanced datasets etc.
  • plot_trace := Wrapper for arviz.plot_posterior

  • plot_posterior := Wrapper for arviz.plot_posterior

  • summary := Wrapper for arviz.summary

abstract fit()
abstract property idata
abstract property initialized
abstract load()
abstract property model
abstract predict()
abstract save()
abstract property save_path
abstract property trained
bayesian_models.models.ELU(x, alpha: float = 1.0)

pytensor implementation of the ELU activation function:

\[f(x) \triangleq \begin{cases} x & x \gt 0 \\ \alpha (e^x-1) &\text{if } b \\ \end{cases}\]

Args:

  • x := The input tensor

  • alpha:float=1.0 := The \(\alpha\) parameter of the ELU function

Returns:

  • function := Elementwise operation

bayesian_models.models.GELU(x)

pytensor implementaion of the GELU activation function.

This function is defined as:

\[X \thicksim \mathcal{N}(0,1) f(x) \triangleq xP(X\le x) = x\Phi (x)=x \frac 12 [1+erf(\frac {x}{\sqrt{2}})]\]

Args:

  • x := Input tensor

Returns:

  • function := The elementwise operation

bayesian_models.models.ReLU(x, leak: float = 0.0)

pytensor implementation of the ReLU activation function:

\[f(x)\triangleq max(leak, x)\]

NOTE: With leak=0 this is the standard ReLU function. With leak a small number i.e. 1e-2 this is Leaky ReLU. Otherwise this is Parametric ReLU

Args:

  • x := The input tensor

  • leak:float=.0 := The leak parameter of the ReLU. When equal to 0, returns the standard ReLU, when equal to a small number i.e. 0.001 this is Leaky ReLU, otherwise it’s parametric ReLu

Returns:

  • function := Elementwise operation

bayesian_models.models.SWISS(x, beta: float = 1)

pytensor implementation of the Swiss activation function:

\[f(x) \triangleq x sigmoid(\beta x)\]

NOTE: This implementation is equivalent to the ‘Swiss-1’ activation function, where \(\beta\) is not learned. The original SWISS function has this as a learnable parameter instead

bayesian_models.models.SiLU(x)

pytensor implementation of the SiLU activation function. This function is defined as:

\[f(x) \triangleq x \sigma (x)\]

Args:

  • x := Input tensor

Returns:

  • function := The elementwise operation

bayesian_models.utilities module

class bayesian_models.utilities.DictTable

Bases: dict

Jupyter utility class that overrides the dicts’ defaults __repr__ rendering the input dictionary to an HTML table for convenient jupyter rendering

class bayesian_models.utilities.SklearnDataFrameScaler(scaler: Callable[[...], Any], backend: str = 'pandas', *args, **kwargs)

Bases: object

Extend the functionality of sklearn scalers, allowing for labeled inputs and outputs

Adds labels to the result of sklearn scalers

Args:

  • scaler:Callable[[…], tuple[numpy.ndarray]] := The scaler Callable. Must use the class based API
  • backend:str=’pandas’ := Which label matrix backend to use. Valid options are ‘pandas’ and ‘xarray’

Returns:

  • scaler_arrays:tuple[pd.DataFrame, xarray.DataArray] := A tuple of rescaled and relabeled arrays
bayesian_models.utilities.count_missing_nan(df: DataFrame, axis: int = 0)

Return a new DataFrame with the counts of missing and invalid values across specified axis.

Args:

  • df:pandas.DataFrame := The data

  • axis:int=0 := The axis across which missing

values will be enumerated. Defaults to 0 (show missing values in each column)

Returns:

  • missing_df:pd.DataFrame := A DataFrame containing

counts of missing values

bayesian_models.utilities.dataarray_from_pandas(df: DataFrame, dim_names=['dim_0', 'dim_1'], **kwargs)

Convert a pandas.DataFrame to an equivalent xarray.DataArray

Args:

  • df:pandas.DataFrame := The pandas.DataFrame to convert

  • dim_names:Sequence[Hashable] := A sequence of Hashable

names to be used for the two axis. Optional. Defaults to the names ‘dim_0’ and ‘dim_1’.

  • **kwargs:dict[Any,Any] := Keyword arguements to be

forwarded to xarray.DataArray constructor. Optional

Returns:

  • converted:xarray.DataArray := The converted dataframe

bayesian_models.utilities.dict_powerset(dictionary: dict, keys_only: bool = False) Iterable

Dictionary powerset function. Lazily returns all possible ‘sub-dictionaries’ from an input dict - including an emtpy dict. Returns entire dicts if keys_only=True or tuples of keys otherwise. Examples:

bayesian_models.utilities.dirichlet_moments(a: ndarray, standardize: bool = True)

Calculate the Dirichlet distributions’ critical moments. A dirichlet is fully specified by it’s first two moments, i.e. mean and variance

Args:

  • shape:Sequence:= The shape parameter(α) of the

Dirichlet. First dimention is assumed to by sepperate Dirichlets and the last dimention defines the shape

  • standardize:bool=True := If true standardizes

the variance, returning standard deviation. Else returns plain second order central moment i.e. the variance. Optional. Defalts to True.

Returns:

  • dirich_moments:xarray.Dataset := An xarray.Dataset

containing the calculcate moments. Always has the ‘variance’ and ‘mean’ data variables, and if standardize=True also contains the ‘std_dev’ data variable

Raises:

  • ValueError:= If the input a cannot be coerced into

an array-like structure, via a.values

bayesian_models.utilities.extract_dist_shape(dist: Type[Distribution]) list[str]
bayesian_models.utilities.flatten(obj: Iterable)

Flatten a nested iterable

Recursively flatten arbitrary an arbitrary input iterable, yielding values iteratively.

Args:

  • obj:Iterable := The nested iterable to flatten

Yields:

  • element:Any := Each non-iterable element in the array
bayesian_models.utilities.gen_masked_predictions(model, masked_generator, baseline_truth, metrics: list[typing.Callable[..., typing.Any]] = [functools.partial(<function mean_squared_error>, squared=False)], return_elements: bool = False, **kwargs)

Generate performance metric evaluations on masked inputs.

Args:

  • model:= The model to generate predictions from

  • masked_generator:= Masked inputs generator. Firstmost

element must be ground truth, i.e. fully unmasked inputs

  • baseline_truth:np.ndarray := Array of values to be used

as ground truths. Will be expanded during evaluation process

  • metrics:list[Callable[…,Any]] := Metrics to be used in

the assessment of the A.N.N. predictions. Currently only a single metric is supported. The metric should be a Callable accepting a baseline truth tensor, a predictions tensor and a sample_dim arguement. Currently only single rank inputs are supported and the sample_dim determines the features axis.

  • return_inputs:bool=True := Selects whether to return detected

inputs or just the absolute indices of the masks.

  • kwargs:dict[str,Any]:= Keyword arguments to be forwarded

to, among other places model.predict

Returns:

  • Measures:collections.namedtuple := A namedtupe containing

the metric evaluation for the masks and optionally the corresponding inputs. Has three fields:

  • iteration:int>=1 := Enumerates the current iteration

  • measures:numpy.ndarray := Array of metric evaluations

for the masks. For code consistency, is a rank-4 tensor of the form distribution_moment x permutation x sample x features of the general form 1 x batch_size x 1 x 1.

  • inputs:Optional[xarray.DataArray]=None := If

return_elements=True if an xarray.DataArray containing the masked inputs, otherwise is None. The array is a rank-3 tensor of permutations x samples x features. Defaults to non-empty field.

bayesian_models.utilities.invert_dict(e)
bayesian_models.utilities.list_difference(l1, l2)
bayesian_models.utilities.mean_squared_error(true: ndarray[Any, dtype[ScalarType]], predicted: ndarray[Any, dtype[ScalarType]], sample_weights=None, squared: bool = True, mean: bool = True, average: bool = True, sample_dim: int = 0)

Squared Error implementation, based on sklearn.metrics.mean_squared_error with more options.

Args:

  • true:numpy.typing.NDArray := Array of true values

  • predicted:numpy.typing.NDArray := Array of predicted values

  • mean:bool=True := Selects whether to calculate the mean of

error across all samples or return indevidual errors. Optional Defaults to True (and return Mean Squared Error)

  • average:bool=True := Selects how to handle multidimentional

inputs. If True (default) averages over the outputs axis. With The averaging behavior is determined by sample_weights. If None then performs uniform averaging, otherwise returns a weighted average. If False averaging is done, and errors are returned for each output. Optional. Defaults to True and returns uniform average MSE.

  • sample_weights:Optional[np.typing.NDArray] := An array of

weights to be used during averaging over the outputs dimention. Must be of appropriate length and is ignored is average=False. If None the average is uniform. Optional. Defaults to None and returns uniform averaging.

  • sample_dim:int=0 := Specifies the sample dimention. Optional.

Defaults to 0.

Returns:

  • errors:numpy.ndarray := An array of errors. Either mse, if

mean=True and squared=True, rmse if squared=False, squared error if mean=False and squared=True or error if mean=False and squared=False:

  • mean=True`and `average=True := Scalar mse

  • mean=True and average=False := Output-length vector

of errors for each output

  • mean=False and average=True := observations-length

vector of averaged error for each test sample

  • mean=False and average=False := 2D array, of the same

shape as the inputs

bayesian_models.utilities.package_dirichlet_predictions(raw_preds, outputs, inputs=None, model=None) DataArray

Converts the raw numpy tensor output of an A.N.N to a human-readable xarray.DataArray, with optional post-processing

Args:

  • raw_preds:numpy.ndarray := The output of the

tf.model.predict

  • outputs:xarray.DataArray := The test set of

the N.N., from which names and labels will be infered.

  • inputs:Optional[xarray.DataArray] := The inputs

to the model. Should only be prodived if the inputs were masked, and this should be the unmasked tensor, from which appropriate reshape will be infered. First two dimentions are assumed to be of permutation x sample. Optional. Defaults to None (ignored and no reshaping will be attempted).

model:Optional[tf.keras.model]=None := The model, whose metadata will be extracted and added to the resulting DataArray’s attributes. Optional. Currently not implemented.

bayesian_models.utilities.powerset(sequence: Sequence) Iterable

Powerset implementation in pure python. Returns all possible ‘subsets’ of input sequence, including the empty set. Evaluation is lazy, and each element returned is a tuple of the elements of the original iterable. Example:

bayesian_models.utilities.query_multiple(df, col, multiquery)
bayesian_models.utilities.reverse_tidy_multiindex(df: DataFrame, sep='.')

Convert a tidy dataframe to hierarchically indexed one based on separator delimiters

Reverses the tidying to a hierarchical format. Different levels of the index are identified based on “sep”

Args:

  • df:pandas.DataFrame := The dataframe to process

  • sep:str=’_._’ := The string delimiter, separating values for different levels of the index

Returns:

  • ndf:pandas.DataFrame := The dataframe with hierarchical index

bayesian_models.utilities.rowwise_value_counts(df: DataFrame)

Returns row-wise counts of values for categorical variables.

Args:

  • df:pandas.DataFrame := The dataframe to process

Returns:

  • counts:pandas.DataFrame := A new DataFrame of counts of

distinct values in the input dataframe

bayesian_models.utilities.select_subarray(df: DataFrame, targets: list[tuple[str, str, str]], indicators: list[tuple[str, str, str]], scaleX: bool = True, train_split: bool = False, mappings: dict[str, Union[str, int, float]] | None = None, dummify: bool = False) tuple[pandas.core.frame.DataFrame, pandas.core.frame.DataFrame]
bayesian_models.utilities.std_scale(df)
bayesian_models.utilities.tidy_multiindex(df: DataFrame, sep: str = '.')

Convert a hierarchically indexed pandas.DataFrame to tidy formated one

Compress a hierarchically indexed dataframe to standardized tidy format. A unique sepperator sep is used to allow reversal. All levels of the index are appended together with a delimeter to allow reversals.

Args:

  • df:pandas.DataFrame := A pandas.DataFrame hierarchically indexed
  • sep:str=’_._’ := A delimenter delineating the different levels of the index. Ensure it is not present in any column name to avoid a malformed index

Returns:

  • ndf:pandas.DataFrame := The DataFrame with a single-level index
bayesian_models.utilities.undummify(df: DataFrame, cols: list[str, tuple[str]], ncol_name: str | tuple[str], sep: str | None = None, rmap: dict[int, Union[str, tuple[str]]] | None = None) DataFrame

Reverses hot-encoded variables in the DataFrame. A series of hot-encoded variable levels $(i_1, i2, dots, i_k)$ is mapped to a single new column $(k)$, whose name is specified by ncol_name, in the new dataframe. Previous level columns are dropped.

Args:

  • df:pandas.DataFrame := The DataFrame to operate upon

  • cols:list[str, tuple[str]] := A list of columns, representing

the levels of a categorical variable

  • sep:Optional[str] := sepperator for variable level. Currently

ignored

  • ncol_name:Union[str, tuple[str]] := Name of the new categorical

column

  • remap:Optional[dict[int, Union[str, tuple[str]]]] := A

dictionary mapping of categorical levels to values. Keys are the assumed to be levels, values are assumed to be values (i.e. strings). When provided, the previous levels will be replaced by the specified mappings in the new DataFrame

Returns:

  • ndf:pandas.DataFrame := The processed dataframe

Module contents