API Reference
bayesian_models package
Module contents
Submodules
bayesian_models.core module
- class bayesian_models.core.BESTCoreComponent(distributions: dict[str, bayesian_models.core.Distribution] = {}, model: Model | None = None, group_distributions=(), permutations=(), std_difference: bool = False, effect_magnitude: bool = False)
Bases:
CoreModelComponentCore Model Component for the BEST group comparison model
Injecting basic random variables into the model (the
distributionsargument) is delegated to the parentCoreModelComponent. This component inserts the following deterministics instead:\[\begin{array}{c} \Delta\mu_{i,j} =\ \mu_i-\mu_j \\ \Delta\sigma_{i, j} = \sigma_i-\sigma_j\\ E = \dfrac{\hat{x_i}-\hat{x_j}}{ \sqrt{ \frac{\sigma_i^2+\sigma_j^2}{2} } } \end{array}\]By default only the :math:
Deltamuquantity is added. Passstd_difference=Trueto include :math:Deltasigmaandeffect_size=Falseto add the effect size to the trace (will also automatically add :math:Deltamu). Used internally only. TheBESTclass handles the external API.Example Usage:
core_dists = dict( ν = distribution( pm.Exponential, "ν_minus_one", 1/29.0, transform = lambda e: e+1.0 ), "obs_0" = distribution( pm.Data, "y0", X0, mutable=False ), "obs_1" = distribution( pm.Data, "y1", X1, mutable=False ), μ_0 = distribution( pm.Normal, "μ_0", mu = X0.mean(), sigma = 2*X0.std(), shape = X0.shape[-1] ), σ_0 = distribution( pm.Uniform, 'σ_0', lower = 1e-1, upper = 10, shape=X0.shape[-1]), μ_1 = distribution( pm.Normal, "μ_1", mu = X1.mean(), sigma = 2*X1.std(), shape = X1.shape[-1] ), σ_1 = distribution( pm.Uniform, 'σ_1', lower = 1e-1, upper = 10, shape=X1.shape[-1]) } likelihoods = [ LikelihoodComponent( name = "y_obs_0", observed = "obs_0", distribution = pm.StudentT, var_mapping = dict( mu = 'μ_, sigma = 'σ_1', nu = 'ν', ) ), LikelihoodComponent( name = "y_obs_0", observed = "obs_0", distribution = pm.StudentT, var_mapping = dict( mu = 'μ_, sigma = 'σ_1', nu = 'ν', ) ), ] # Likelihoods passed to the builder instead BESTCoreComponent( distributions = core_dists, group_distributions = ..., permutations = ..., std_difference = False, effect_magnitude = False, )
Object Attributes:
- _group_distributions:tuple := Aggregated groupwise distributions
- _permutations:tuple := (Technically combinations) all possible unique pairs of levels for the categorical variable defining the groups. Tracks all possible pair-wise comparisons
- _derived_quantities:dict[str, str]=dict(means=[], stds = [], effect_magnitude = []) := Aggregated deterministics
- _std_difference:bool=False := If
Truecomputes the :math:Deltasigmadeterministic and adds it to the trace. Optional. Defaults toFalse - _effect_magnitude:bool=False := If
Truecompute the ‘effect_size’ deterministic quantity. Optional and defaults toFalse - variables:dict[str, Any] := A dictionary mapping internal variable names to a variable references. Added by the
CoreModelObjectparent class. Enables different components to access variables other than those in their context (i.e.LikelihoodComponentcan access the variables to be linked to its shape parameters)
- variables: dict
- class bayesian_models.core.CoreModelBuilder(*, core_model: ~bayesian_models.core.CoreModelComponent | None = None, likelihoods: list[bayesian_models.core.LikelihoodComponent] | None = None, free_vars: ~bayesian_models.core.FreeVariablesComponent | None = None, adaptor: ~bayesian_models.core.ModelAdaptorComponent | None = None, coords: dict[str, typing.Any] = <factory>, response: ~bayesian_models.core.ResponseFunctionComponent | None = None)
Bases:
ModelBuilderCore model builder object.
Sequentially composes the model object by inserting it’s various components. Every model should supply at least a subclass of
CoreModelComponentand a list ofLikelihoodcomponents. All available components, in order are:- core_model:CoreModelComponents := The basic structure of the model, including its equations and basic random variables (REQUIRED)
- link:LinkFunctionComponent := A link function to be applied to the model. (OPTIONAL)
- adaptors:ModeAdaptor := An ‘output adaptor’ component that splits the model output tensor into multiple subtensor and inserts them to the computation graph. (OPTIONAL)
- response:ResponseFunctionComponent := A response function whose model outputs will be passed through. (OPTIONAL)
- free_vars:FreeVariablesComponent := A additional variables component that inserts variables not explicitly involved in the models’ core equations. (OPTIONAL)
- likelihoods:Sequence[LikelihoodComponent] := A collection of likelihood components, to be added to the model. (REQUIRED)
Example usage:
from bayesian_models.core import CoreModelBuilder from bayesian_models.core import LikelihoodComponent from bayesian_models.core import ResponseFunctionComponent from bayesian_models.core import FreeVariablesComponent from bayesian_models.core import ModelAdaptorComponent # Should be called indirectly via the director d = CoreModelBuilder( core_model = CoreModelComponent(), likelihoods=[LikelihoodComponent(), ...], response = ResponseFunctionComponent(), free_vars = FreeVariablesComponent(), adaptor = ModelAdaptorComponent(), )
Object Attributes:
- core_model:Optional[CoreModelComponent] = None := The core model component. Should subclass
CoreModelComponent - likelihoods:Optional[list[LikelihoodComponent]] = None := The likelihood component object, defining the likelihood for the model
- model:Optional[pymc.Model] := The
pymc.Modelobject. Should be created elsewhere and handed to the builder - model_variables:dict[str, Any] := A general catalogue of all the models’ variables. Maps variable names to references to the variables, allowing for easy lookup
- free_vars:Optional[FreeVariablesComponent]=None := The component defining ‘extra’ random variables, i.e. those not directly participating in the models’ equations
- adaptor:Optional[ModelAdaptorComponent]=None := A model adaptor component which splits the models’ raw output into subtensors
- response:Optional[ResponseFunctionComponent]=None := The ResponseFunction component, defining functions that transform variables in the model to other variables
- coords:dict[str,Any] = field(default_factory=dict) := Coordinates for the model object itself. Passed as a dict to the
pymcallowing for label coordinates after inference. Collected from the data object itself
Object Methods:
__post_init__()->None := Validate that minimal components are present in the model
_validate_likelihoods()->None := Validate that all shape parameters of the specified likelihoods are defined in the model stack
Danger
At present, little validation is being done, to assume that all of the distributions’ parameters are correctly defined and the domains match. Responsibility for these validations in on the user
build()->None := Build the model by sequentially calling separate components to add their variables to the context stack. Will also update the builders’ internal catalogue of all variables present in the model
__call__()->None := Build the model updating or create the underlying
pymc.Modelobject
- adaptor: ModelAdaptorComponent | None
- build() None
Construct the model according to the specified components.
Call specified components, in order, to add the variables of each to the model. Maintains an internal catalogue of variable names mapped to refs to the objects
- coords: dict[str, Any]
- core_model: CoreModelComponent | None
- free_vars: FreeVariablesComponent | None
- likelihoods: list[bayesian_models.core.LikelihoodComponent] | None
- model: Model | None
- model_variables: dict
- response: ResponseFunctionComponent | None
- class bayesian_models.core.CoreModelComponent(*, distributions: dict[str, bayesian_models.core.Distribution] = <factory>, model: ~pymc.model.Model | None = None)
Bases:
objectCore model component.
Inserts basic random variables to the context stack, maintaining an internal catalogue of variables inserted for latter access. Concrete model objects should subclass this component and extend its call method by defining the models’ equations in deterministic nodes. If a concrete model produces some explicit quantity as an output, this should generally be named ‘f’.
Example usage:
core = CoreModelComponent( distributions = dict( beta0 = distribution(pymc.Normal, 'beta0', 0,1), beta1 = distribution(pymc.Normal, 'beta1', mu = 0, sigma=1), ) # OLS-like example, using convenience # method :code:`distribution` to access # the :code:`Distribution` class )
Object Attributes:
- distributions:dict[str, Distribution] := A dictionary mapping random variable names to their priors/ distributions. The
Distributionclass encapsulates all the information for a prior distribution. Can be accessed via the convenience methoddistribution - variables[str, Any] := A catalogue of basic random variables added to the model. Child classes extend this by adding their deterministics
- model:Optional[pymc.Model] := A reference to
pymc.Modelobject itself. Is created or defined by theModelBuildDirectorand handed to the builder to construct the model
Object Methods:
__call__()->None := Assumes a
pymc.Modelcontext stack is open. Adds all specified random variables to the model by calling them from thedistributionsdict and adds them to thevariablescatalogue
- distributions: dict[str, bayesian_models.core.Distribution]
- model: Model | None
- variables: dict
- class bayesian_models.core.Distribution(*, name: str = '', dist: ~typing.Type[~pymc.distributions.distribution.Distribution] | ~typing.Type[~typing.Callable] = <class 'pymc.distributions.distribution.Distribution'>, dist_args: tuple = (), dist_kwargs: dict = <factory>, dist_transform: ~typing.Callable | None = None)
Bases:
objectData container class for user-specified distributions.
Supply a distribution
distalong with any desired argumentsdist_argsanddist_kwargs. If the distribution needs to be modified, for example by shifting it by some amount, supply adist_transform:Callable. Optionally anamecan be provided. As a data container class, it has no methods.NOTE: For data nodes, the
distargument should by the functionpymc.DataExample usage:
dist = Distribution( dist=pymc.Normal, name='some_name', dist_args=(0,), dist_kwargs=dict(sigma=1) ) dist = Distribution( dist=pymc.Exponential, name='exp', dist_args=(1/29.0,), dist_transform=lambda d:d+1 ) dist = Distribution( name='inputs', dist=pymc.Data, dist_args=(np.random.rand(50,5), ), dist_kwargs=dict(mutable=True) )
Object Attributes:
- name:str=’’ := A name for the distribution / random variable. Technically optional but should be provided
- dist := For random variables the distribution to be used as a prior. Initially a reference to the class, will be latter swapped to an instance of the class. For data nodes, the function
pymc.Datacan be passed instead - dist_args:tuple := Positional arguments to the distribution
- dist_kwargs:dict := Keyword arguments to the distribution
- dist_transform:Optional[Callable]=None := A Callable that is used to perform a numerical transform to the variable. Will not be explicitly tracked by the model (its result will). Used to offset, and manipulate core distributions. Optional. Defaults to
None
- dist: Type[Distribution] | Type[Callable]
- dist_args: tuple
- dist_kwargs: dict
- dist_transform: Callable | None
- name: str
- class bayesian_models.core.FreeVariablesComponent(dists: dict[str, bayesian_models.core.Distribution] = <factory>)
Bases:
objectComponent representing additional variables to be inserted to the model.
Used for variables not explicitly involved in the core model itself, i.e. the equations describing the model. For example the noise parameter in linear regression:
\[\begin{array}{c} w0 \thicksim \mathcal{N}(0,1)\\ w1 \thicksim \mathcal{N}(0,1)\\ μ = X*w0+w1\\ σ \thicksim \mathcal{N}(0,1)\\ y \thicksim \mathcal{N}(μ, σ)\\ \end{array}\]The
distsargument supplied is adictof names toDistributioninstances, representing the distributions to be inserted to the model.Example usage:
fvars = FreeVariablesComponent( dict( sigma = Distribution(name='sigma', dist=pymc.Normal, dist_args=(0,1) ) ) # Insert random variable 'sigma' to the model
Object Attributes:
- variables:dict := A catalogue of variables inserted into the model. Is a dictionary mapping variable names to references to the appropriate object
- dists:dict[str, Distribution] := Distributions to be added to the model
Object Methods:
- __call__()->None := Expects to be executed with a
pymc.Modelcontext stack open. Adds all distributions to the model and updates thevariablesattribute
- dists: dict[str, bayesian_models.core.Distribution]
- variables: Any
- class bayesian_models.core.LikelihoodComponent(*, name: str = 'y_obs', observed: str = 'outputs', distribution: ~typing.Type[~pymc.distributions.distribution.Distribution] = <class 'pymc.distributions.continuous.Normal'>, var_mapping: dict[str, str] = <factory>)
Bases:
objectAdds a likelihood component to the model.
var_mappingmust be supplied, defining which model variables map to which likelihood shape parameters. For exampledistribution=pymc.Normaland var_mapping=dict(mu = ‘f’, sigma=’sigma’). The keys of thevar_mappingdict are strings which must exactly match the shape parameters of the likelihood. Values should be the internal names of model variables, specified during their creation.nameandobservedcorrespond to the name of the likelihood object itself and the name of the observed data node in the model. Should generally be left to their defaults, except when the model has multiple likelihood/observed nodes.Example usage:
like = LikelihoodComponent( name = 'y_obs', # Default likelihood name observed = 'observed', # Default name for # the name of the input data node distribution = pymc.Dirichlet, # Defaults # to pymc.Normal var_mapping = dict( a = 'f', ) # Mapping of distribution shape parameters # to model parameter names. 'f' is usually # the default name for the core model # output )
Object Attributes:
name:str=’y_obs’ := The name for the likelihood variable
- observed:str=’outputs’ := The internal name of the data node containing the observations. Should match the
nameattribute of theDistributionobject that defined the data node - distribution:Type[pymc.Distribution]=pymc.Normal := The distribution for the likelihood/observations
var_mapping:dict[str, str] := Mapping of the likelihoods’ shape parameters to internal names of model variables to be supplied to the respective parameter. The keys are shape arguments to the supplied distribution. The items are strings representing variable names that will be looked up in the variable catalogue
Object Methods:
- __call__(observed, var_mappingLdict)->None := Expects to be called with
pymc.Modelcontext open and wil add the likelihood to the model.observedis the result of a lookup to the models’variablescatalogue for theobservedattribute and is a reference the observations.var_mappinghas the same keys as the original and its items are the result of a lookup on thevar_mappingitem lookup into the modelsvariablescatalogue
- distribution: Type[Distribution]
- name: str
- observed: str
- var_mapping: dict[str, str]
- class bayesian_models.core.LinearRegressionCoreComponent(distributions: dict[str, bayesian_models.core.Distribution] = {}, var_names: dict[str, str] = {}, model: Model | None = None)
Bases:
CoreModelComponentCore model component for linear regression
Specifies the model as
\[f = XW+b\]Inserts the deterministic variable ‘f’ to the model. Delegates definition of the random variables to the
CoreModelComponentparent.NOTE: When all the priors and the likelihood are Normal this is analytically tractable and MCMC is not needed. Included here as a reference example mostly, though one could run a linear regression with an unusual likelihood / response functions etc
Class Attributes:
- var_names:dict[str, str] := Alternate names for the various variables of the model. Allows users to refer to the variables by a different name e.g. “b” instead of ‘W’
model_vars:set := The models’ variable names
Object Attributes:
- variables:dict[str, str] : Catalogue mapping variables names to references to the variables. Created by the parent and extended to include the deterministic ‘f’
- var_names:dict[str, str] := Mapping of internal variable names to user-defined names. Optional. Defaults to an empty dict. Any user supplied variables not corresponding to known model variables are ignored. Any variable aliases not supplied by the user are replaced with their defaults. Warns on any mismatch
Private Attributes:
Variables used internally, mainly for input validation
- s1:set[str] := User-defined/supplied variable names
- s2:set[str] := Model variables (class level attribute)
Object Methods:
- __call__()->None := Add the models’ equation to the model as a deterministic node. Assumes a
pymc.Modelcontext stack is open. Model output is namedvar_names['equation']‘f’ by default
- distributions: dict[str, bayesian_models.core.Distribution]
- model: Model | None
- model_vars = {'data', 'equation', 'intercept', 'slope'}
- var_names = {'data': 'inputs', 'equation': 'f', 'intercept': 'b', 'slope': 'W'}
- variables: dict
- class bayesian_models.core.ModelAdaptorComponent(*, record: bool = True, var_mapping: dict[str, typing.Callable] = <factory>)
Bases:
objectAdds an ‘output adaptor’ component to the model, which ‘splits’ the models output tensor into other variables.
The splitting logic is specified by the
var_mappingargument, which is a dict whose keys are strings representing variable names, and whose items are Callables that accept and returntheanotensors. Therecordboolean argument decides if the result of all “splits” will be wrapped in a deterministic node.Example usage:
adaptor = ModelAdaptorComponent( record = True, # Keep the new variables as # Deterministic nodes for later access var_mapping = dict( mu = lambda tensor: tensor.T[0,...], sigma = lambda tensor: tensor.T[1,...], ) # Split model output 'f', a tensor, into two # tensors named 'mu' and 'sigma', wrapped as # deterministics in the model.
Object Attributes:
- var_mapping:dict[str, Callable] := Mapping of variable names to Callable objects which return the variable. All Callables here receive exactly one argument, the tensor that is the output of the model and the Callable should execute the splitting, returning exactly one subtensor
- record:bool=True := If
True(default) records the subtensors as deterministic variables, adding them to the models posterior trace. Otherwise, they are treated as nuissance intermediates, accessible via the models’var_namescatalogue - variables:dict := Catalogue of new objects added to the model by this component. Keys are names, and items are references to the subtensor objects themselves. Allows ‘anonymous’ non-deterministic subtensors to be accessed by other components without being added to the models’ trace
Object Methods:
- __call__(output)->None := Creates and adds specified subtensors to the model. Assumes a
pymc.Modelcontext stack is open.outputis a reference to the models output. Also updates thevariablesattributed with all the subtensors created.outputwill be passed to all the Callables specified invar_mapping
- record: bool
- var_mapping: dict[str, Callable]
- variables: dict
- class bayesian_models.core.ModelBuilder
Bases:
ABCAbstract base class for model builders
- abstract property model_variables
- class bayesian_models.core.ModelDirector(core_component: CoreModelComponent, likelihood_component: list[bayesian_models.core.LikelihoodComponent], response_component: ResponseFunctionComponent | None = None, free_vars_component: FreeVariablesComponent | None = None, adaptor_component: ModelAdaptorComponent | None = None, coords: dict | None = {})
Bases:
objectModel construction object.
Delegates model construction to a specified model builder.
Example usage:
# Will not work with empty objects. All except the first # two arguments are optional and can be ignored d = ModelDirector( CoreModelComponent(), LikelihoodComponent(), response_component = ResponseFunctionComponent(), free_vars_component = FreeVariablesComponent(), adaptor_component = ModelAdaptorComponent(), )
Object Attributes:
builder:Type[ModelBuilder] := The model builder object. Should be left to the default as only a single Builder is implemented
Object Properties:
model:pymc.Model := The underlying
pymc.Modelobject, exposed to the user. Is not an actual object property, but exposes the one of the underlying builder object
Object Methods:
__call__()->None := Calls the underlying model builder object to construct the actual model object
- builder
alias of
CoreModelBuilder
- property model: Model | None
- class bayesian_models.core.Response(name, func, target, record)
Bases:
tupleContainer object for response functions
Response functions are model components that transform model variables into other model variables. This is a
collections.namedtuplecontainer and has no methodsObject Attributes:
- name:str := An internal name for the transformation and its result
- func:Callable := The
Callableobject that handles the actual transformation - target:str := Internal name for the variable that is to be transformed. The result of a lookup for this variable becomes the input to the
Callablein thefuncfield. This should be the only argument to the Callable - record:bool := If
Truethe result of the transformation will be wrapped in a deterministic variable and preserved in the posterior trace. Else they will be accessible only internally, via thevariablesproperty
- func
Alias for field number 1
- name
Alias for field number 0
- record
Alias for field number 3
- target
Alias for field number 2
- class bayesian_models.core.ResponseFunctionComponent(responses: ResponseFunctions)
Bases:
objectModel component representing Response functions.
Accepts response functions specified via the
ResponseFunctionsclass. Adds them to the model and maintains an internal catalogue for variables added asvariables.Example usage:
res_comp = ResponseFunctionComponent( ResponseFunctions( functions = dict( exp = pymc.math.exp, tanh = pymc.math.tanh ), records = dict(exp=True, tanh=False), application_targets = dict(exp="f", tanh="exp") ) )
Object Attributes:
- responses:ResponseFunctions := A
ResponseFunctionsobject encapsulating all the response functions to be added to the model - variables:dict[str, Any] := A catalogue of variables added to the model, stored as mappings of strings (names) to references to the underlying object
Object Methods:
- __call__(modelvars:dict[str, Any])->None := Add specified response functions to the model. Assumes a
pymc.Modelcontext is open. Updates thevariablesattribute.modelvarsis the general catalogue of variables present in the model as name:str to object mappings (supplied by the builder)
- responses: ResponseFunctions
- variables: dict
- class bayesian_models.core.ResponseFunctions(functions: dict[str, typing.Callable] = <factory>, application_targets: dict[str, str] = <factory>, records: dict[str, bool] = <factory>)
Bases:
objectData container for Response functions.
Accepts three mappings as dicts. All three map strings representing variable names for the result of the response to a parameter. The
functionsargument maps names to the actual functions themselves. Theapplication_targetsparameter maps transformed variable names to the variables that are inputs to the transformation. Therecordsparameter maps variable names to a boolean representing whether they should be recorded or not.Truewill wrap the result of the transform into a deterministic node, False will not. Theapplication_targetsand therecordsparameters can be partially or completely omitted. In this case, record defaults to True and the application_target default to ‘f’ a general name for the raw model output. If any variable is found in eitherapplication_targetsorrecordsbut not infunctionsan exception is raised, since not reasonable inference can be made for the transform function instead.Example usage:
# Pass all parameters explicitly (recommended) ResponseFunctions( functions = dict(exp = pymc.math.exp, tanh = pymc.math.tanh), records = dict(exp=True, tanh=False), application_targets = dict(exp="f", tanh="exp") ) # Partially omit application_targets using defaults 'f' ResponseFunctions( functions = dict(exp = pymc.math.exp, tanh = pymc.math.tanh), records = dict(exp=True, tanh=False), application_targets = dict(tanh="exp") ) # Pass the # desired Callables leaving everything to their # defaults. In this case two different response functions # are applied to the same input 'f'. Both are recorded # with :code:`pymc.Deterministic` the name is the key # provided ResponseFunctions( functions = dict(exp = pymc.math.exp, tanh = pymc.math.tanh) )
This object is an Iterable over response functions
Object Attributes:
- functions:dict[str, Callable] := A dictionary mapping internal variable names to Callable objects defining the transformation
- records:dict[str, bool] := A dictionary mapping internal variable names to booleans. If the boolean is
Truethe variable is wrapped in a deterministic node and preserved in the posterior trance. Else it accessible only internally. Optional. Anything not explicitly defined here is inferred to be true - application_targets:dict[str, str] := A dictionary mapping response names to the internal name of the variable to be transformed. Optional. Any keys missing are automatically mapped to ‘f’, the default name for core model output tensor
Private Attributes:
- _sf:set[str] := Set of function names specified
- _st:set[str] := Set of function targets specified (via application_targets keys)
- _missing_records:set[str] := Set of function records (keys) not explicitly specified by the user
- _missing_targets:set[str] := Set of function targets (keys of
application_targets) not explicitly set by the user - _iter:Optional[Iterable] := Iterator object over the specified
functionsused internally to make the object an iterable
- application_targets: dict[str, str]
- functions: dict[str, Callable]
- get_function(func: str) Response
Returns all data kept on a single response function as a namedtuple for ease of access. Looks up all specs for a response and returns a namedtuple with the results packaged. Fields provided are
name,func,targetandrecord
- records: dict[str, bool]
- bayesian_models.core.distribution(dist: Distribution, name: str, *args, transform: Callable | None = None, **kwargs) Distribution
Convenience method for fresh
Distributioninstance creation.Accepts a a distribution and a name, along with optional args and kwargs and returns a
Distributionobject matching those parameters.Example usage:
distribution(pymc.Normal, 'W', 0,1) # Equivalent to Distribution(dist = pymc.Normal, # dist_name = 'W', dist_args = (0,1), dist_kwargs=dict() # ) distribution(pymc.Beta, 'b', alpha=1,beta=1) # Equivalent to Distribution(dist=pymc.Beta, dist_name='b', # dist_args=tuple(), dist_kwargs=dict(alpha=1, beta=1)) distribution(pymc.StudentT, 'T', 0, sigma=1, nu=2) # Equivalent to Distribution(dist=pymc.StudentT, # dist_name='b', dist_args=(0,), dist_kwargs=dict(sigma=1, # nu=2))
bayesian_models.data module
- class bayesian_models.data.CommonDataProcessor(*, nan_handler_context: ~bayesian_models.data.NANHandlingContext = NANHandlingContext(_nan_strategy=<class 'bayesian_models.data.ExcludeMissingNAN'>, nan_handler=ExcludeMissingNAN(new_coords=None, new_dims=None, axis=0, constructor=None), kwargs={}), cast: ~numpy.dtype | None = None, type_spec: ~typing.Any | None = None, casting_kwargs: dict = <factory>)
Bases:
DataProcessorCommon use-case data pre processor.
Will handle the following data preprocessing tasks:
- converting the data structure to a common internal interface
handling of missing values
casting to data type (Optional)
validate data types (Incomplete)
Can be subclassed for extended functionality or overriden.
Object Attributes:
- nan_handler:NANHandlerContext := The missing values handler. Optional. Defaults to ExcludeMissingNAN. Initially a ref to the context class, will be replaced by a instance of that class.
- cast:Optional[np.dtype]=None := Attempt to forcefully cast all inputs to the specified type. Optional. Defaults to
np.float32. Setting this toNonewill disable typecasting - type_spec := Schema to validate. Not implemented and will be ignored
- casting_kwargs:dict={} := Keyword arguements to be forwarded to the underlying typecaster. See numpy for details. Defaults to an empty dict.
Danger
Typecasting is not fully implemented due to the limitations of numpy arrays (they are homogenuous structures, whereas pandas DataFrames are not). Use this option only to cast the entire structure to a certain dtype
Object Methods:
- __call__(data:InputData)->CommonDataStructureInterface := Preprocess the data according the set options and return the result.
- cast: dtype | None = None
- casting_kwargs: dict
- nan_handler_context: NANHandlingContext = NANHandlingContext(_nan_strategy=<class 'bayesian_models.data.ExcludeMissingNAN'>, nan_handler=ExcludeMissingNAN(new_coords=None, new_dims=None, axis=0, constructor=None), kwargs={})
- type_spec: Any = None
- class bayesian_models.data.CommonDataStructureInterface(*, _data_structure: DataStructure | None = None, _implementor: Type[DataStructure] | None = None)
Bases:
DataStructureInterfaceCore interface for supported data structures. Should be the only interface provided
Object Attributes:
- implementor:Type[DataStructure] := Class reference to the type of implementor
Caution
This attribute is deprecated and scheduled for removal
Object Properties:
- data_structure:DataStructure := The core data structure implementation
rank:int := The structures’ rank (number of axes)
shape:tuple[int] := The shape of the structure
dims:numpy.ndarray := Labels for the axes of the structure
- coords:dict[str, numpy.ndarray] := Labels for the coordinates of the structure. Stored as dictionary mapping axes labels to numpy arrays of labels in that axes. Keys should match elements of the
dimsproperty - values:numpy.ndarray := The underlying numpy array structure. Usefull for unpacking the structure for other software (like
pymc)
Object Methods:
Methods exposed by the tensor. Except where methods reduce the entire structure to 0D, all should return another
CommonDataStructureInterfacepermitting method chaining. Whenever a structure would be reduced to 1D, a 2D row-vector structure will be returned instead- transpose(axis:Optional[AXES_PERMUTATION] = None) := Return a tranposed version of the object. Signature is the same as numpy and must return the same default. Should always return the same type of object. The T attribute is an alias for this method
- isna(axis:Optional[int] = None) := Elementwise
isnan. Should default to returning the a boolean tensor of the same shape as the original tensor. Whenaxisis provided this is equivalent to ananyoperation over this axis. The axis is preseved in the return.Note
This does not actually use
numpy.isnaninternally. It extends its functionaly by allowing nan checks onobjecttype arrays.Danger
Will not work with strings as missing nan values automatically converted into strings
- any(axis:Optional[int] = None) := When
axis=Noneperformanyover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - all(axis:Optional[int] = None) := When
axis=Noneperformallover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - iterrows() := Iterate over the first axis of the structure Similar to
pandas.DataFrame.iterrows() - itercolumns() := Iterate over the second axis of the structure. Similar to
pandas.DataFrame.itercolumns - unique(axis:Optional[int] = None) := Return unique values of the structure. Returns a Generator object that yields length 2 tuples of the general form (Optional[label:str], array). The first element of the tuple is either None or an array of unique elements. When axis is None, (default) the Generator yields only a single element, whose first element is None, and whose other element is an array of all unique values in the array. When axis is provided as an integer, the resulting Generator, loops over the specified axis, yielding tuples of the label in the current iteration (coordinate of the specified axis) and numpy arrays of all unique values in the subtensor (as a vector)
- __getitem__(obj) := DataStructure indexing. All conventional indexing options are supported, including slicing with labels and mixed label/index based indexing and selecting. The
stepargument must be an integer (or None) all others can be any mix of label and index based indexers. For example:obj[0,0,0] obj[:5:2, "var1",0] obj['sample_0':'sample_10':2, 5,...] obj['sample_5',...] obj[0:15:"sample",...] # Illegal - step must be an integer
- mean(axis=None, keepdims=True, skipna=True) := Compute the arithmetic mean along the specified axis (or the entire structure if
None- default). Ifkeepdims=Truethe specified dimention is kept in the result with a single coordinate named ‘sum’, making the result correctly broadcastable to the original. Else the dimention is reduced. Ifskipna=TrueNaNvalues are ignored else, all coordinates with at least oneNaNwill returnNaN - ops := Basic operators are supported and generally delegated to the underlying library
== >= != > < <=
- T(axes: list[int] | tuple[int, ...] | None = None) CommonDataStructureInterface
- all(axis: int | None = None, **kwargs)
- any(axis: int | None = None, **kwargs) CommonDataStructureInterface | bool_
- astype(dtype, **kwargs)
- coords() dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]]
- property data_structure: DataStructure
- dims() tuple[str, ...]
- dtype()
- isna()
- itercolumns()
- iterrows()
- mean(axis: int | None = None, skipna: bool = True, keepdims: bool = True) float | CommonDataStructureInterface
Compute the arithmetic mean along the specified axis
Args:
- axis:Optional[int]=None := The axis along which to compute the mean. If
None(default) returns the mean along the entire structure - skipna:bool=True := If
True(default)NaNvalues will be ignored, else every coordinate along the specified axis with at least oneNaNwill returnNaN. - keepdims:bool=True := If
True(default), the axis along which the mean is computed is kept in the result with a single coordinate named ‘sum’, making the result correctly broadcastable agaist the original. Else reduce the dimension in the result. This argument is ignored if axis isNone
Returns:
- mean:float := The mean of the entire structure (if
axis=None) - means:CommonDataStructureInterface := A new structure of means. If
keepdims=Falsewould reduce the structure below 2D, a 2D structure is returned instead (equivalent tokeepdims=True)
- missing_nan_flag() bool | None
- rank() int
- shape() tuple[int, ...]
- transpose(axes: list[int] | tuple[int, ...] | None = None) CommonDataStructureInterface
- unique(axis: int | None = None, **kwargs)
- values() ndarray[Any, dtype[ScalarType]]
- class bayesian_models.data.Data(nan_handling: str = 'exclude', processor: ~typing.Type[~bayesian_models.data.DataProcessor] = <class 'bayesian_models.data.CommonDataProcessor'>, cast: ~typing.Any = <class 'numpy.float32'>, type_spec: dict = {}, casting_kwargs: dict = {})
Bases:
objectContainer for model data with optional preprocessing functionality.
Class Attributes:
- nan_handlers:set[str]=[‘exlude’, ‘impute’, ‘ignore’] := Valid strategies for missing value handling
- input_types:set[str]=[‘ndarray’, ‘DataFrame’, ‘DataArray’] := Supported input data structures
Object Attributes:
- nan_handling:str=’exclude’ := The missing data handling strategy. Has to be one of Data.nan_handlers. Optional. Defaults to ‘exclude’ and discards all axis=0 coordinates with missing values (i.e rows).
- cast:Any := A data type to force-cast the data to. Optional. Defaults to
numpy.float32. Set toNoneto disable casting - type_spec:dict={} := Dictionary specification data validation across the second dimention. Keys should be coordinates (labels) along the second axis(=1) and values should be valid numpy dtypes. Currently ignored
- casting_kwargs:dict={} := Optional keyword arguments to be forwarded to the type caster. Optional. Defaults to an empty dict. See the
numpydocumentation for further details. Ignored ifcast=None - processor:Type[DataProcessor]=CommonDataProcessor := The processor to be used for data processing. Optional and defaults to the generic data processor. Can be overriden to customized with a user specified processor that subclasses
DataProcessororCommonDataProcessor - process_director:Optional[DataProcessDirector] := The director for data processing. Optional
- nan_handler:Optional[NANHandler]=None := The class that handles missing values. None only when unset
Object Methods:
- __call__(data:InputData) := Process the data and return the result
- data_processor: Type[DataProcessor]
- input_types: set[str] = {'DataArray', 'DataFrame', 'ndarray'}
- nan_handler: Type[NANHandler] | None
- nan_handlers: set[str] = {'exclude', 'ignore', 'impute'}
- nan_handling: str
- process_director: DataProcessingDirector | None
- class bayesian_models.data.DataArrayStructure(obj: DataArray, dims: tuple[str, ...] | None = None, coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]] | None = None, dtype=None)
Bases:
DataStructure,UtilityMixinWrapper class around xarray.DataArray implementing the common interface.
Like all implementations this class implements a common, standardized interface for acceptable tensor data structures, as defined by the
DataStructureabstract base class.Class Properties:
- accepted_inputs:set := Set of input structured that can be converted into
xarray.DataArray. Acceptable classes for theobjattribute
Object Properties:
- obj:xarray.DataArray := The underlying
xarray.DataArrayobject shape:tuple[int,…] := The shape of the object
- dims:DIMS := Dimensions of the object. A
numpyvector of labels of the dimensions / axes of the object. If the object has dimentions these will be used else defaults are generated automatically. The default names are ‘dim_{i}’ where i the integer indexer of the axis - coords:COORDS := The coordinates of the object. Is a dictionary of strings, which are axes names (the same as those of
dims) mapped to numpy vectors of labels. These are the labels of the ‘steps’ in each axis. If the object has coordinates, these will be used, else defaults are used (as enumerated integers) rank:int := The structures’ rank i.e. the number of axes
dtype:np.dtype := The data type of the structure
- missing_nan_flag:Optional[bool] = None := Flag for existence of missing values. Should be set by the public interface class
Object Methods:
- isna()->DataArrayStructure := Return a boolean structure, of the same class and shape as the original, whose elements are booleans indicating if the corresponding element is nan or not. Unlike
numpy.isnanwill work on objects but not strings - any(axis:Optional[int]=None)-> Union[bool, DataArrayStructure] := If axis is
Nonereduce via element wise or the entire array. Else reduce over the axis specified - all(axis:Optional[int]=None)-> Union[bool, DataArrayStructure] := If axis is
Nonereduce via element wise and the entire array. Else reduce over the axis specified - transpose(axis:Optional[tuple[int,…]] )->DataArrayStructure := Return a transposed structure. If axes is
Nonereverses the dimentions. If provided,axisshould be a permutation of the objects’ axes (as a tuple), defining the transposition - iterrows()->(str, DataArrayStructure) := Returns an iterator over the zeroth axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:xarray.DataArray): for i in range(X.shape[0]): yield (X.coords[i], X[i,...])
- itercolumns()->(str, DataArrayStructure) := Returns an iterator over the first axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:xarray.DataArray): for i in range(X.shape[1]): yield (X.coords[i], X[:,i,...])
- cast(dtype:numpy.dtype)->DataArrayStructure := Casts the structure to the specified data type. Returns a fresh DataStrcture object
- unique(axis:Optional[int]=None)->DataArrayStrcture := Return a unique values in the structure. If axis is provided, unique values will over the specified axis are returned. Else unique values over the entire structure are returned. Is a Generator that yields unique values. If
axis=Nonethe Generator yields a single tuple of the form (None, vals) wherevalsis numpy vector of unique elements in the entire structure. If axis is provided, iterates over the specified axis yielding tuples of the form (coordinate_label, vals) wherecoordinate_labelis the label coordinate of the current iteration.valsis a numpy vector of unique values in the resulting sub structure. Loosely equivalent to:def unique(struct): i=0 while True: try: crd = struct.coords[axis][i] vals = numpy.unique(struct.transpose(axis)[i,...]) yield crd, vals except KeyError: raise StopIteration
- mean(axis:Optional[int]=None)->DataArrayStructure := Return the mean along the specified axis, or over the entire structure (if
axis=None)
- T(axes: list[int] | tuple[int, ...] | None = None)
- accepted_inputs: set = {<class 'pandas.core.series.Series'>, <class 'pandas.core.frame.DataFrame'>, <class 'xarray.core.dataarray.DataArray'>, <class 'numpy.ndarray'>}
- all(axis: int | None = None, **kwargs) bool | DataArrayStructure
- any(axis: int | None = None, **kwargs)
- cast(dtype, **kwargs)
- isna()
- itercolumns()
- iterrows()
- mean(axis: int | None = None, keepdims: bool = True, skipna: bool = True)
- transpose(axes: list[int] | tuple[int, ...] | None = None)
- unique(axis: int | None = None)
Return unique values of the NDArrayStructure as Generator of length 2 tuples.
When axis is None, the generator yields a single tuple of (None, vals) where vals are all the unique values in the array. When axis is specified, the Generator iterates over the specified axis yielding tuples of (label, unique_values)
- class bayesian_models.data.DataFrameStructure(obj: DataFrame, dims: tuple[str, ...] | None = None, coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]] | None = None, dtype=None)
Bases:
DataStructure,UtilityMixinWrapper class around
pandas.DataFrameimplementing the common interface.Like all implementations this class implements a common, standardized interface for acceptable tensor data structures, as defined by the
DataStructureabstract base class.Class Attributes:
- accepted_inputs:set := Valid inputs the constructor. Structures which can be converted are Series, DataFrames and numpy ndarrays
Object Properties:
- obj:pandas.DataFrame := The underlying
pandas.DataFrameobject shape:tuple[int,…] := The shape of the object
- dims:DIMS := Dimensions of the object. A
numpyvector of labels of the dimensions / axes of the object.The default names are ‘dim_{i}’ where i the integer indexer of the axis - coords:COORDS := The coordinates of the object. Is a dictionary of strings, which are axes names (the same as those of
dims) mapped to numpy vectors of labels. These are the labels of the ‘steps’ in each axis. If the object has index and columns, these will be used, else defaults are used (as enumerated integers) - rank:int := The structures’ rank i.e. the number of axes
dtype:np.dtype := The data type of the structure
- missing_nan_flag:Optional[bool] = None := Flag for existence of missing values. Should be set by the public interface class
Object Methods:
- isna()->DataFrameStructure := Return a boolean structure, of the same class and shape as the original, whose elements are booleans indicating if the corresponding element is nan or not.
- any(axis:Optional[int]=None)-> Union[bool, DataFrameStructure] := If axis is
Nonereduce the entire array via element wise or . Else reduce over the axis specified - all(axis:Optional[int]=None)-> Union[bool, DataFrameStructure] := If axis is
Nonereduce the entire array via element wise and. Else reduce over the axis specified - transpose(axis:Optional[tuple[int,…]] )->DataFrameStructure := Return a transposed structure. If axis is
Nonereverses the dimensions. If provided,axisshould be a permutation of the objects’ axes (as a tuple), defining the transposition - iterrows()->(str, DataFrameStructure) := Returns an iterator over the zeroth axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:pandas.DataFrame): for i in range(X.shape[0]): yield (X.index[i], X.iloc[i,...])
- itercolumns()->(str, DataFrameStructure) := Returns an iterator over the first axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:pandas.DataFrame): for i in range(X.shape[1]): yield (X.columns[i], X.iloc[:,i,...])
- cast(dtype:numpy.dtype)->DataArrayStructure := Casts the structure to the specified data type. Returns a fresh DataStrcture object
- unique(axis:Optional[int]=None)->DataFrameStructure := Return a unique values in the structure. If axis is provided, unique values will over the specified axis are returned. Else unique values over the entire structure are returned. Is a Generator that yields unique values. If
axis=Nonethe Generator yields a single tuple of the form (None, vals) wherevalsis numpy vector of unique elements in the entire structure. If axis is provided, iterates over the specified axis yielding tuples of the form (coordinate_label, vals) wherecoordinate_labelis the label coordinate of the current iteration.valsis a numpy vector of unique values in the resulting sub structure. Loosely equivalent to:def unique(struct): i=0 while True: try: crd = struct.coords[axis][i] vals = numpy.unique(struct.transpose(axis)[i,...]) yield crd, vals except KeyError: raise StopIteration
- mean(axis:Optional[int]=None)->DataFrameStructure := Return the mean along the specified axis, or over the entire structure (if
axis=None)
- T(axes: list[int] | tuple[int, ...] | None = None)
- accepted_inputs: set = [<class 'pandas.core.frame.DataFrame'>, <class 'pandas.core.series.Series'>, <class 'numpy.ndarray'>]
- all(axis: int | None = None, **kwargs)
- any(axis: int | None = None, **kwargs)
- cast(dtype, **kwargs)
- isna()
- itercolumns()
- iterrows()
- mean(axis: int | None = None, keepdims: bool = True, skipna: bool = True)
Compute the arithmetic mean along the specified axis
Args:
- axis:Optional[int]=None := The axis to compute the mean over. If
None(default), computes the mean over the entireDataFrame. Values are0(mean over the rows),1(mean over the columns) andNone(mean of the entire array) - skipna:bool=True := If
TrueignoresNaNvalues in the dataframe. Else returnsNaNfor coordinates with at least oneNaN - keepdims:bool=True := If
Truethe axis over which the mean is computed, is kept in the result with a single coordinate named ‘sum’ (default), making the result correctly broadcastable against the original. Otherwise, the result axis is reduced. SinceArrayStructureobject cannot be reduced past 2D the arguement if effectively ignored and alwaysTruefor DataFrames
Returns:
- mean:float := The mean of the entire dataframe (
axis=None) - means:DataFrameStructure := A DataFrame with a single row of means along the specified axis
Raises:
ValueError := If
axisis notNone,1or0
- transpose(axes: list[int] | tuple[int, ...] | None = None)
- unique(axis: int | None = None)
- class bayesian_models.data.DataProcessingDirector(*, processor: ~typing.Type[~bayesian_models.data.DataProcessor] | ~bayesian_models.data.DataProcessor = <class 'bayesian_models.data.CommonDataProcessor'>, nan_handler_context: ~bayesian_models.data.NANHandlingContext = NANHandlingContext(_nan_strategy=<class 'bayesian_models.data.ExcludeMissingNAN'>, nan_handler=ExcludeMissingNAN(new_coords=None, new_dims=None, axis=0, constructor=None), kwargs={}), processor_kwargs: dict = <factory>)
Bases:
objectMaster composite for data pre processing
Object Attributes:
- processor:CommonDataProcessor := A reference to the class that represents the data processor. Converted to an instance on said class. Optional. Defaults to
CommonDataProcessor - nan_handler_context:NANHanderContext := The missing nan handler
- processor_kwargs:dict = Keyword arguments to be forwarded to the processor instance
Object Methods:
- __call__(data:InputeData)->CommonDataStructureInterface := Call the processor and return the pre processed data
- nan_handler_context: NANHandlingContext = NANHandlingContext(_nan_strategy=<class 'bayesian_models.data.ExcludeMissingNAN'>, nan_handler=ExcludeMissingNAN(new_coords=None, new_dims=None, axis=0, constructor=None), kwargs={})
- processor
alias of
CommonDataProcessor
- processor_kwargs: dict
- class bayesian_models.data.DataProcessor
Bases:
ABCAbstract base class for Data Processors
- class bayesian_models.data.DataStructure
Bases:
ABCAbstract Base Class for Data Structure implementations
Object Properties:
Common properties exposed by the underlying object
- obj:DataStructure := The wrapped, underlying object
- shape:SHAPE := The shape property of the wrapped object
- dims:DIMS := Labels for the dimensions of the object - the axes
- coords:COORDS := Labels for each element in each axis i.e distinct row labels, column labels etc
rank:int := The tensors rank
- dtype := The datatype for the elements. For consistency all
DataStructureare coerced into homogenous types
Object Methods:
Methods exposed by the tensor
- transpose(axis:Optional[AXES_PERMUTATION] = None) := Return a transposed version of the object. Signature is the same as numpy and must return the same default. Should always return the same type of object. The T attribute is an alias for this method
- isna(axis:Optional[int] = None) := Elementwise
isnan. Should default to returning the a boolean tensor of the same shape as the original tensor. Whenaxisis provided should this is equivalent to ananyoperation over this axis. The axis should be preserved in the return - any(axis:Optional[int] = None) := When
axis=Noneperformanyover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - all(axis:Optional[int] = None) := When
axis=Noneperformallover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - iterrows() := Iterate over the first axis of the structure. Similar to
pandas.DataFrame.iterrows() - itercolumns() := Iterate over the second axis of the structure. Similar to
pandas.DataFrame.itercolumns - cast(dtype, **kwargs) := Attempt to cast tensor elements to
dtype. All kwargs are forwarded tonumpy. Returns a new copy of the tensor (as a DataStructure object) with the update data type - __getitem__(self, obj) := Slice the object in any number of ways. Integer and label based, slices should be acceptable along with arbitrary combinations thereof. Acceptable slice inputs should be: int, str, slice, Ellipsis, list[int,str], tuple[int,str] and all combinations of these. Slice should accept label based specs or integers based ones, or mixes of the two. The step argument only accept integers and raise otherwise. All of the following should be valid:
obj[5,6] obj["sample_0", 7] obj["sample_7":10:1, ...] obj[[6,9], "var1":10:2,...]
If the object would be reduced below a 2d structure, it should padded into 2D as a row-vector
- unique(axis=None) := Return a the unique values of the data structure as a generator of length 2 tuples. When axis is specified as an integer, the generator iterates over the specified axis, yielding tuples of the label and the unique values of the subtensor. When axis is None (default) return a single element Generator which yields exactly one tuple of (None, UNIQUES), where UNIQUES is a vector of all the unique values in the structure
- mean(axis:Optional[int] = None, keepdims:bool=True, skipna:bool=True) := Compute the mean along the specified axis. If axis is
Nonethe mean will be computed over the entire structure and a numeric is returned. Otherwise a data structure of the same type as the original is returned. If axis is not None, the mean is computed over the specified axis. Ifkeepdims=True(default) the axis is reduced and removed. Ifkeepdims=Truethen the axis is maintained (and the result is broadcastable to the original) with a single coordinate named “sum”. Ifskipna=Trueany invalid elements will be ignored (default) otherwisenanis returned where mean would otherwise be. - ops := Elementwise comparison operations such as ‘>’, ‘>=’, ‘==’, ‘<=’, ‘<’ and ‘neq’ are included in the interface but generally delegated to the underlying library
- abstract T(axes: list[int] | tuple[int, ...] | None = None)
- abstract all(axis: int | None = None) bool | DataStructure
- abstract any(axis: int | None = None) bool | DataStructure
- abstract cast(typ_spec) DataStructure
- property coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]]
- property dims: tuple[str, ...]
- property dtype: Any
- abstract isna() DataStructure
- abstract itercolumns() DataStructure
- abstract iterrows() DataStructure
- abstract mean(axis: int | None = None, keepdims: bool = True, skipna: bool = True)
- property missing_nan_flag: bool | None
- property obj: DataStructure
- property rank: int
- property shape: tuple[int, ...]
- abstract transpose(axes: list[int] | tuple[int, ...] | None = None) DataStructure
- property values: ndarray[Any, dtype[ScalarType]]
- class bayesian_models.data.DataStructureInterface
Bases:
ABCAbstract Base Class for the external interface (The bridge Abstraction)
Object Properties:
- data_structure:DataStructure := The core data structure implementation
Object Methods:
Methods exposed by the tensor
- transpose(axis:Optional[AXES_PERMUTATION] = None) := Return a tranposed version of the object. Signature is the same as numpy and must return the same default. Should always return the same type of object. The T attribute is an alias for this methods
- isna(axis:Optional[int] = None) := Elementwise
isnan. Should default to returning the a boolean tensor of the same shape as the original tensor. Whenaxisis provided should this is equivalent to ananyoperation over this axis. The axis should be preseved in the return - any(axis:Optional[int] = None) := When
axis=Noneperformanyover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - all(axis:Optional[int] = None) := When
axis=Noneperformallover the entire array and return a boolean. Otherwise perform the operation over the specified axis, preserving the axis - iterrows() := Iterate over the first axis of the structure. Similar to
pandas.DataFrame.iterrows() - itercolumns() := Iterate over the second axis of the structure. Similar to
pandas.DataFrame.itercolumns - __gettitem__(indexer) := Return the values specified by the
indexer. Mix and matching label and integer based indexing is supported. If a slice is provided, the start and stop arguments can be labels, but the step argument must be an integer - unique(axis=None) := Return all the unique values in the tensor as a Generator that yields length 2 tuples. If axis is None the Generator yields a single tuple of the form (None, values), where values is a vector of unique values. If axis is provided, the generator iterates over the specified dimention, yielding tuples of the form (label, values) where values is a vector of unique values for the flattened subtensor.
- mean(axis=None, keepdims=True, skipna=True) := Compute the arithmetic mean along the specified axis (or the entire structure if
None- default). Ifkeepdims=Truethe specified dimention is kept in the result with a single coordinate named ‘sum’, making the result correctly broadcastable to the original. Else the dimention is reduced. Ifskipna=TrueNaNvalues are ignored else, all coordinates with at least oneNaNwill returnNaN - ops := Elementwise operations ‘>’, ‘<’, ‘>=’, ‘<=’, ‘==’, ‘!=’ are delegated to the underlying library but a wrapped object is returned for ‘pointwise’ operations, i.e. obj==5, otherwise a boolean is returned
- abstract all() DataStructureInterface | bool | bool_
- abstract any() DataStructureInterface | bool | bool_
- abstract astype(dtype, kwargs) DataStructureInterface
- abstract coords() dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]]
- abstract property data_structure: DataStructure
- abstract dims() tuple[str, ...]
- abstract dtype() Any
- abstract isna() DataStructureInterface | bool | bool_
- abstract itercolumns() DataStructureInterface
- abstract iterrows() DataStructureInterface
- abstract mean(axis: int | None = None, keepdims: bool = True, skipna: bool = False) None
- abstract rank() int
- abstract shape() tuple[int, ...]
- abstract transpose() DataStructureInterface
- abstract values() ndarray
- class bayesian_models.data.ExcludeMissingNAN(new_coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]] | None = None, new_dims: tuple[str, ...] | None = None, axis: int = 0, constructor: DataStructure | None = None)
Bases:
NANHandlerExclude missing values
Common use-case for missing value handling. Discards all coordinates on the first dimention (i.e. rows) along which there are any missing values - updating the objects’ metadata
Object Attributes:
- new_coords:Optional[COORDS]=None := Updated object coordinates
- new_dims:Optional[DIMS]=None := Updated object dimentions
- axis:int=0 := The dimention along which to exclude. Optional. Defaults to 0 (‘rows’). Currently no other options are implemeted and other values are ignored.
- constructor:Optional[DataStructure]=None := The DataStructure of the object to convert after processing
Object Methods:
- __call__(data:DataStructureInterface )->DataStructureInterface := Handle missing values and return the updated object
- axis: int = 0
- constructor: DataStructure | None = None
- new_coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]] | None = None
- new_dims: tuple[str, ...] | None = None
- class bayesian_models.data.IgnoreMissingNAN
Bases:
NANHandlerIdentity strategy for nan handling the does nothing.
Only included for completeness’ sake. Returns the object unmodified
Object Methods:
- __call__(data:DataStructureInterface )->DataStructureInterface
:= Returns the data unchanged
- class bayesian_models.data.ImputeMissingNAN
Bases:
NANHandlerImputation missing data handler
Performs imputation, replacing missing
nanvalues with dummy ones that do not distort the underlying distribution. NotImplemented and will raise
- class bayesian_models.data.NANHandler
Bases:
ABCAbstract Base Class for missing value handlers
- class bayesian_models.data.NANHandlingContext(*, _nan_strategy: ~typing.Type[~bayesian_models.data.NANHandler] = <class 'bayesian_models.data.ExcludeMissingNAN'>, nan_handler: ~bayesian_models.data.NANHandler | None = None, kwargs: dict = <factory>)
Bases:
objectComposite for missing values handling. Defines the external interface
Object Properties:
- nan_handler:NANHandler := The nan handling strategy to apply
Object Methods:
- __call__(data:DataStructureInterface))->DataStructureInterace := Delegate missing value handling to the handler and return the results
- kwargs: dict
- nan_handler: NANHandler | None = None
- class bayesian_models.data.NDArrayStructure(obj: ndarray[Any, dtype[ScalarType]] | DataStructure, dims: tuple[str, ...] | None = None, coords: dict[str, numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]] | None = None, dtype: Any | None = None)
Bases:
DataStructure,UtilityMixinWrapper class around numpy arrays implementing the common interface.
Like all implementations this class implements a common, standardized interface for acceptable tensor data structures, as defined by the
DataStructureabstract base classObject Properties:
- obj:numpy.typing.NDArray := The underlying
numpy.ndarrayobject shape:tuple[int,…] := The shape of the object
- dims:DIMS := Dimensions of the object. A
numpyvector of labels of the dimensions / axes of the object. For numpy arrays defaults are typically used (since numpy arrays have no labels). The default names are ‘dim_{i}’ where i the integer indexer of the axis - coords:COORDS := The coordinates of the object. Is a dictionary of strings, which are axes names (the same as those of
dims) mapped to numpy vectors of labels. These are the labels of the ‘steps’ in each axis rank:int := The structures’ rank i.e. the number of axes
dtype:np.dtype := The data type of the structure
- missing_nan_flag:Optional[bool] = None := Flag for the existence of missing values. Should be set by the public interface class
Object Methods:
- isna()->NDArrayStructure := Return a boolean structure, of the same class and shape as the original, whose elements are booleans indicating if the corresponding element is nan or not. Unlike
numpy.isnanwill work on objects but not strings - any(axis:Optional[int]=None)-> Union[bool, NDArrayStructure] := If axis is
Nonereduce via element wise or the entire array. Else reduce over the axis specified - all(axis:Optional[int]=None)-> Union[bool, NDArrayStructure] := If axis is
Nonereduce via element wise and the entire array. Else reduce over the axis specified - transpose(axis:Optional[tuple[int,…]] )->NDArrayStructure := Return a transposed structure. If axes is
Nonereverses the dimensions. If provided,axisshould be a permutation of the objects’ axes (as a tuple), defining the transposition - iterrows()->(str, NDArrayStructure) := Returns an iterator over the zeroth axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:NDArrayStructure): for i in range(X.shape[0]): yield (X.coords[i], X[i,...])
- itercolumns()->(str, NDArrayStructure) := Returns an iterator over the first axis of the structure. Yields tuples of coordinates to substructures. Loosely equivalent to:
def iterrows(X:NDArrayStructure): for i in range(X.shape[1]): yield (X.coords[i], X[:,i,...])
- cast(dtype:numpy.dtype)->NDArrayStructure := Casts the structure to the specified data type. Returns a fresh DataStrcture object
- unique(axis:Optional[int]=None)->NDArrayStructure := Return unique values in the structure. If axis is provided, unique values over the specified axis are returned. Else unique values over the entire structure are returned. Is a Generator that yields unique values. If
axis=Nonethe Generator yields a single tuple of the form (None, vals) wherevalsis numpy vector of unique elements in the entire structure. If axis is provided, iterates over the specified axis yielding tuples of the form (coordinate_label, vals) wherecoordinate_labelis the label coordinate of the current iteration.valsis a numpy vector of unique values in the resulting sub structure. Loosely equivalent to:def unique(struct): i=0 while True: try: crd = struct.coords[axis][i] vals = numpy.unique(struct.transpose(axis)[i,...]) yield crd, vals except KeyError: raise StopIteration
- mean(axis:Optional[int]=None)->Union[ float, NDArrayStructure] := Return the mean along the specified axis, or over the entire structure (if
axis=None)
- T(axes: list[int] | tuple[int, ...] | None = None) NDArrayStructure
Transpose the tensor structure
If
axesis not provided, reverse the order of the axes. If provided it should be a valid permutation of the structures’ axes, defining how the transposition should be performedExample usage
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure(np.random.rand(20,5,3)) print(struct.tranpose().shape) # Output # (3,5,20) By default, reverse the order of the axes print(struct.tranpose().shape) # Output # (3,5,20) By default, reverse the order of the axes print(struct.tranpose((1,0,2)).shape) # Reverse the # first two axes # Output # (5,20,3) # Axes permutations must be explicit struct.tranpose((1,0, ...) # TypeError: 'ellipsis' object cannot be interpreted as # an integer
Args:
- axes:Optional[AXIS_PERMUTATION]=None := Define how the transposition operation should be performed. If
None(default) reverse the order of the axes. If provided, it should be a valid permutation of the structures’ axes, defining the transposition
Returns:
- nobj:NDArrayStructure := The transposed object
- all(axis: int | None = None, **kwargs)
Elementwise and across the structure.
If
axis=Nonereturn a single boolean across the entire structure equivalent toandacross the entire structure. Ifaxisis provided, operate across the axis, reducing it.Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure( np.random.randint(0,2, size=(10,3), dtype=bool) ) print(struct.values) # Output # array([[False, False, True], # [False, False, True], # [ True, False, True], # [False, True, True], # [False, True, True], # [ True, False, False], # [False, False, False], # [ True, True, False], # [ True, False, True], # [ True, True, False]]) print(struct.any(axis=1).values) # Output: # array([False, False, False, False, True, False, # False, False, True, False])
Args:
- axis:Optional[int]=None := The axis across which to operate. If
Noneoperate across the entire structure
Returns:
- any:bool := If
axis=Nonea single boolean across the entire structure - anys:NDArrayStructure := If
axisis an integer, return a structure with the axis reduced, operating along the axis
- any(axis: int | None = None, **kwargs)
Elementwise “or” across the structure.
If
axis=Nonereturn a single boolean across the entire structure equivalent tooracross the entire structure. Ifaxisis provided reduce the axis equivalent to elementwiseoracross the axisExample usage:
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure( np.random.randint(0,2, size=(10,3), dtype=bool) ) print(struct.values) # Output # array([[False, False, True], # [False, False, True], # [ True, False, True], # [False, True, True], # [False, True, True], # [ True, False, False], # [False, False, False], # [ True, True, False], # [ True, False, True], # [ True, True, False]]) print(struct.any(axis=1).values) # Output: # array([ True, True, True, True, True, True, # True, True, True, True])
Args:
- axis:Optional[int]=None := The axis across which to operate. If
Noneoperate across the entire structure
Returns:
- any:bool := If
axis=Nonea single boolean across the entire structure - anys:NDArrayStructure := If
axisis an integer, return a structure with the axis reduced, operating along the axis
- cast(dtype: dtype, **kwargs)
Change the data type of the structure
Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure obj = NDArrayStructure( np.random.rand(20,3) ) # Change the data type to 32-bit floats obj.cast(np.float32)
Args:
- dtype:numpy.dtype := The
dtypeto convert the structure to - **kwargs:dict[str, Any] := Keyword arguements to be forwarded to
.astype. See thenumpydocs for more information
Returns:
- nstruct:NDArrayStructure := The structure converted to the specified
dtype
- isna()
Check if the structure has missing or
nanvaluesThis implementation works with
objectdtypes but not strings. Returns a structure of booleans showing if the respective element isnanor notExample usage:
import numpy as np from bayesian_models.data import NDArrayStructure X = np.random.rand(10,3) X[0,0] = np.nan obj = NDArrayStructure(X) print(obj.isna().values) # Output #[[ True False False] # [False False False] # [False False False] # [False False False] # [False False False] # [False False False] # [False False False] # [False False False] # [False False False] # [False False False]] # Returns an NDArrayStructure so methods can be chain # called print(obj.isna().any()) # Output: # True
- itercolumns()
Iterate over the zeroth dimension of the structure
Is a Generator that yields coordinates of the first axis as a tuple (coordinate:str, substructure). Coordinate is label of the coordinate of the current iteration.
substructureare the unique values of the iteration, loosely equivalent toX[:,i,...].Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure for step in struct.itercolumns(): print(f"{struct[0]}th iteration") print(struct[1].values) # Output # 0 iteration # [[0.87129834 0.52058713 0.3262019 0.77032967 # 0.12151855 0.04655757, ... 0.58081613]] # ... # 4 iteration # [[0.24766219 0.87327094 0.20295554 0.57563816 0.776743 # ... 0.15798941]]
- iterrows()
Iterate over the zeroth dimension of the structure
Is a Generator that yields coordinates of the zeroth axis as a tuple (coordinate:str, substructure). Coordinate is label of the coordinate of the current iteration.
substructureare the values of the iteration, loosely equivalent toX[i,...].Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure for step in struct.iterrows(): print(f"{struct[0]}th iteration") print(struct[1].values) # Output # 0th iteration # [[0.87129834 0.28525984 0.8024876 0.22648149 # 0.24766219]] # 1th iteration # [[0.52058713 0.64226276 0.54973852 0.02149187 # 0.87327094]] # ... # 28th iteration # [[0.09227537 0.72935584 0.36943861 0.72009057 # 0.83315441]] # 29th iteration # [[0.58081613 0.51312354 0.9158358 0.93393108 # 0.15798941]]
- mean(axis: int | None = None, keepdims: bool = True, skipna: bool = True)
Compute the arithmetic mean along the specified axis.
Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure(np.random.rand(10,3)) # Mean of the entire structure print(struct.mean().values) # Output # 0.4621622294767996 # Mean over some columns print(struct.mean(axis=1).values) # Output # array([[0.54527681], # [0.35284086], # [0.25491467], # [0.41629867], # [0.47454723], # [0.5965149 ], # [0.73069869], # [0.42783913], # [0.21808277], # [0.60460858]]) print(struct.mean(axis=1).coords) # Output # {'dim_0': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), # 'dim_1': #array(['sum'], dtype='<U3')} print(struct1.mean(axis=1, keepdims=False).coords) # Output # {'dim_0': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), # 'dim_1': #array(['sum'], dtype='<U3')} # DataStructure objects cannot fall below 2D # For higher dimentional tensors :code:`keepdims=False` will # reduce the axis struct1 = NDArrayStructure(np.random.rand(10,3,2)) print(struct1.mean(axis=1, keepdims=False).coords) # Output # {'dim_0': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), # 'dim_2': array([0, 1])}
Args:
- axis:Optional[int]=None : = When
axis=Nonereturn the scalar mean of the entire structure (default). Otherwise computes the mean along the specified axis. - keepdims:bool=True := If
keepdims=Truethe dimention is maintained in the resulting structure with a single coordinate named ‘sum’ (default). Otherwise, the dimention is reduced and removed from the resulting structure. - skipna:bool=True := If
skipna=TrueNaNvalues will be ignored in the result, otherwiseNaNis returned for coordinates with at least oneNaN
Returns:
- nstruct:NDArray := Returns a new NDArrayStructure of means
- mean:float := If
axis=Nonethe mean of the entire structure
- transpose(axes: list[int] | tuple[int, ...] | None = None) NDArrayStructure
Transpose the tensor structure
If
axesis not provided, reverse the order of the axes. If provided it should be a valid permutation of the structures’ axes, defining how the transposition should be performedExample usage
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure(np.random.rand(20,5,3)) print(struct.tranpose().shape) # Output # (3,5,20) By default, reverse the order of the axes print(struct.tranpose().shape) # Output # (3,5,20) By default, reverse the order of the axes print(struct.tranpose((1,0,2)).shape) # Reverse the # first two axes # Output # (5,20,3) # Axes permutations must be explicit struct.tranpose((1,0, ...) # TypeError: 'ellipsis' object cannot be interpreted as # an integer
Args:
- axes:Optional[AXIS_PERMUTATION]=None := Define how the transposition operation should be performed. If
None(default) reverse the order of the axes. If provided, it should be a valid permutation of the structures’ axes, defining the transposition
Returns:
- nobj:NDArrayStructure := The transposed object
- unique(axis: int | None = None) tuple[typing.Optional[numpy.ndarray[str]], numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]]
Return the unique elements in the structure.
Return unique values of the NDArrayStructure as Generator of length 2 tuples. When axis is None, the generator yields a single tuple of (None, vals) where vals are all the unique values in the array. When axis is specified, the Generator iterates over the specified axis, yielding tuples of label, unique_values.
Example usage:
import numpy as np from bayesian_models.data import NDArrayStructure struct = NDArrayStructure( np.random.randint( 0, 4, size=(10,3) ) ) items:tuple[None, np.ndarray] = next(struct.unique()) # Unique # items in the entire structure # Unique items across an axis for coordinate in struct.unique(axis=1): print( "Found these unique items {items} in this coordinate {crd}".format(crd= coordinate[0], items=coordinate[1]) ) # Output # Found these unique items [0 1 3] in this coordinate 0 # Found these unique items [0 1 2 3] in this coordinate # 1 # Found these unique items [0 1 2 3] in this # coordinate 2
Args:
- axis:Optional[int]=None := The axis along which to return unique values. If
None, return unique elements along the entire structure
Yields:
- unique:tuple[None, np.ndarray] := If
axis=Noneyield a single typle of (None, val_array), whereval_arrayanumpyvector of all unique elements in the structure - unique:tuple[np.ndarray[str], np.ndarray] := If
axisis provided yield tuples of (coordinate, values).coordinateis the current value of the coordinate.valuesis anumpyvector of unique values along the coordinate
- property values: ndarray[Any, dtype[ScalarType]]
Return the underlying structure as a
numpy.ndarrayExample usage:
import numpy as np from bayesian_models.data import NDArrayStructure A = np.random.rand(10,3) print(A) # Output # array([[0.92696729, 0.85774767, 0.74036172], # [0.04296317, 0.65726312, 0.97758067], # [0.56289662, 0.28891003, 0.62563431], # [0.55779293, 0.8921344 , 0.07295159], # [0.63069955, 0.48854109, 0.5674133 ], # [0.41642828, 0.45982703, 0.22005397], # [0.75317745, 0.11725162, 0.46697631], # [0.48607453, 0.30890712, 0.41480661], # [0.06220708, 0.3917841 , 0.66493793], # [0.23265062, 0.28742938, 0.06959736]]) obj = NDArrayStructure(A) print(obj.values) # array([[0.92696729, 0.85774767, 0.74036172], # [0.04296317, 0.65726312, 0.97758067], # [0.56289662, 0.28891003, 0.62563431], # [0.55779293, 0.8921344 , 0.07295159], # [0.63069955, 0.48854109, 0.5674133 ], # [0.41642828, 0.45982703, 0.22005397], # [0.75317745, 0.11725162, 0.46697631], # [0.48607453, 0.30890712, 0.41480661], # [0.06220708, 0.3917841 , 0.66493793], # [0.23265062, 0.28742938, 0.06959736]])
- class bayesian_models.data.UtilityMixin
Bases:
objectConvenience mixin class to to disseminate common functionality. Used for inheritance only
Object Methods:
- _cut_dims_(axis:Optional[int]=None)->tuple[DIMS, COORDS] := In cases where an axis is reduced (eliminated) in the result, this returns the updated
dimsandcoordsas a tuple - _dimshuffle_(axes_permutation:AXES_PERMUTATION)->tuple := Given an axes permutation (for transposing structures) permute the dims an coords and return them as tuple
bayesian_models.math module
- bayesian_models.math.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.math.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.math.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.math.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 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:
BESTBaseBayesian 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’ :=
numpyroparameter for alternate sampling. Controls which devicenumpyrowill use - jax_device_count: int =1 :=
numpyrosetting. Number of devices to be used for HMC sampling (parallel)
Attention
Due to persistent problems with the
numpyrodependency these parameters are ignoredObject Attributes:
- group_var:str := Coordinate label for the categorical variable to group by
Danger
Due to issues with the underlying
pymcimplementation and limitations ofnumpy.isnanthe 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 apandas.DataFramebe 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=Truethis 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
savemethod may be called without an explicitsave_pathargument. - idata:Optional[arviz.InferenceData]=None :=
arviz.InferenceDataobject containing the results of model inference. Becomes set after calling thefitmethod - trained:bool=False := Sentinel signaling whether the model has been trained or not. Defaults to False. Should be switched on after calling
fit. Preventspredictfrom 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
fitandpredictfrom 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 ofgroup_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_shapeisFalse. - num_levels:Optional[int]=None := The number of unique groups/ values of
group_var. - coords := dict-like of dimension labels
xarraycoords. 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.Modelobject
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.
sampleris valid sampler, i.e.pymc.sampleorpymc.sampling.jax.sample_numpyro_nuts. All other arguments are forwarded to the sampler. Returns aarviz.InferenceDataobject containing the results of inference. Sets thetrainedandidataattributes - 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.DataFrameobjects containing inference summary. Decisions are made using theROPE+HDIrule. 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
datamodule 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_upperclass attribute - set_std_lower(val:float)->None := Update the
std_lowerclass attribute - set_shape_offset(val:float)->None := Update the
ν_offsetclass attributeCaution
Should generally not be modified
- set_jax_device(device:str)->None := Update the
jax_deviceclass attribute - set_jax_device_count(val:int)->None := Update the
jax_device_countclass attribute - set_diffusion_factor(val:float)->None := Update the
std_diffusion_factorattribute - set_degrees_of_freedom(val:int)->None := Update the
ddofclass 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.
inferis an alias forfitArgs:
Returns:
idata:arviz.InferenceData := The results of inference
Raises:
- RuntimeError := If called before
fithas 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.
inferis an alias forfitArgs:
Returns:
idata:arviz.InferenceData := The results of inference
Raises:
- RuntimeError := If called before
fithas 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_pathhas 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_posteriorPlot Posterior densities in the style of John K. Kruschke’s book.
Args:
Returns:
graph:Any := The posterior plot object
- plot_trace(*args, **kwargs)
Wrapper for
arviz.plot_tracePlot 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:
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+HDIrule: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.
pymcby 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.DataFrameobject containing summary results (like those returned byarviz.summary) with an additional column, namedSignificancecontaining 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_pathhas 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:
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
transformone 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.DataFrameto the underlyingnumpy.NDArrayobject. 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:
BayesianModelAbstract 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:
ABCAbstract 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.Datacontainers. The data received should be placed in aDatacontainer, supplied by thedatasubmodule 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 thepredictmethod should invokepymc.set_data(inputs)to replace the input tensor with a new one. For other special cases see thepredictmethod. Should return the object itself for easy method chaining. Should set the objects’initializedproperty to signal that the fit method can be called. - fit := Sample from the posterior according to the
samplerargument. Forwards all other arguments to the sampler, sets the models’idataandtrainedflag, signaling thepredictand other posterior methods can be called.inferis 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 sampley_obsfrom 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 invokepymc.set_datato replace the previous inputs with the new ones followed bypymc.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
predictshould perform the equivalent operation for these models (i.e. render importance decisions), yield augmented or rebalanced datasets etc.
plot_trace := Wrapper for
arviz.plot_posteriorplot_posterior := Wrapper for
arviz.plot_posteriorsummary := 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.typing module
bayesian_models.utilities module
- class bayesian_models.utilities.DictTable
Bases:
dictJupyter 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:
objectExtend 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.DataFrameto tidy formated oneCompress 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