utlvce.score

The utlvce.score module contains the implementation of the alternating optimization procedure described in the paper, which is used to fit a UT-LVCE model to the data and compute its likelihood.

The procedure is accessed through the utlvce.score.Score class, which contains a caching mechanism (see class utlvce.score._Cache) to avoid re-running the procedure for the same DAG / intervention targets. For more details on the implementation please refer to section 4.1 of the paper and to the source-code.

class utlvce.score.Score(data, num_latent, psi_max, psi_fixed, max_iter, threshold_dist_B, threshold_fluctuation, max_fluctuations, threshold_score, learning_rate, B_solver='grad', cache=True)

Contains the implementation of the alternating optimization procedure described in the paper; which fits a UT-LVC model given a DAG adjacency and intervention targets I.

Parameters
  • sample_covariances (numpy.ndarray) – A 3-dimensional array containing the estimated sample covariances of the observed variables for each environment.

  • n_obs (list of ints) – The number of observations available from each environment (i.e. the sample size).

  • num_latent (int) – The assumed number of hidden variables.

  • psi_max (float, default = None) – The maximum allowed change in variance between environments for the hidden variables. If None, psis are unconstrained.

  • psi_fixed (bool) – If True, impose the additional constraint that the hidden variables have all the same variance.

  • max_iter (int) – The maximum number of iterations allowed for the alternating minimization procedure.

  • threshold_dist_B (float) – If the change in B between successive iterations of the alternating optimization procedure is lower than this threshold, stop the procedure and return the estimate.

  • threshold_fluctuation (float) – For the alternating optimization routine, if the score worsens by more than this value, consider the iteration a fluctuation.

  • max_fluctuations (int) – For the alternating optimization routine, the maximum number of fluctuations(see above) allowed before stopping the subroutine.

  • threshold_score (float) – For the gradient descent subroutines, if change in score between successive iterations is below this threshold, stop.

  • learning_rate (float) – The initial learning rate(factor by which gradient is multiplied) for the gradient descent subroutines.

  • cache (_Cache or None) – The cache used to store results of calls to score_dag().

__init__(data, num_latent, psi_max, psi_fixed, max_iter, threshold_dist_B, threshold_fluctuation, max_fluctuations, threshold_score, learning_rate, B_solver='grad', cache=True)

Create a new instance of a Score object.

Parameters
  • data (list of numpy.ndarray or tuple or numpy.ndarray) –

    Can be either:
    1. A list with the samples from each environment, where each sample is an array with columns corresponding to variables and rows to observations.

    2. A tuple containing the precomputed sample covariances and number of observations from each environment.

  • num_latent (int) – The assumed number of hidden variables.

  • psi_max (float, default = None) – The maximum allowed change in variance between environments for the hidden variables. If None, psis are unconstrained.

  • psi_fixed (bool) – If True, impose the additional constraint that the hidden variables have all the same variance.

  • max_iter (int) – The maximum number of iterations allowed for the alternating minimization procedure.

  • threshold_dist_B (float) – If the change in B between successive iterations of the alternating optimization procedure is lower than this threshold, stop the procedure and return the estimate.

  • threshold_fluctuation (float) – For the alternating optimization routine, if the score worsens by more than this value, consider the iteration a fluctuation.

  • max_fluctuations (int) – For the alternating optimization routine, the maximum number of fluctuations(see above) allowed before stopping the subroutine.

  • threshold_score (float) – For the gradient descent subroutines, if change in score between successive iterations is below this threshold, stop.

  • learning_rate (float) – The initial learning rate(factor by which gradient is multiplied) for the gradient descent subroutines.

  • B_solver ({'grad', 'adaptive', 'cvx'}, default='grad') – Sets the solver for the connectivity matrix B, where the options are (ordered by decreasing speed and increasing stability) grad, adaptive and cvx.

  • cache (bool, default=True) – If results from calling the score_dag function should be cached.

Raises
  • ValueError : – If the given data is not valid, i.e. (different number of variables per sample, or one sample with a single observation). Also if the given B_solver is not valid.

  • TypeError : – If the given data is of invalid type.

Examples

Initializing the utlvce.score.Score using the “raw” data:

>>> score_params = {'psi_max': None,
...                 'psi_fixed': False,
...                 'max_iter': 1000,
...                 'threshold_dist_B': 1e-4,
...                 'threshold_fluctuation': 1,
...                 'max_fluctuations': 10,
...                 'threshold_score': 1e-5,
...                 'learning_rate': 1,
...                 'cache': True}
>>> data = list(rng.uniform(size=(5,1000,20)))
>>> Score(data, num_latent=2, **score_params) 
<__main__.Score object at 0x...>

Or passing pre-computed sample covariances:

>>> n_obs = np.array([len(sample) for sample in data])
>>> sample_covariances = np.array([np.cov(sample, rowvar=False) for sample in data])
>>> Score((sample_covariances, n_obs), num_latent=2, **score_params) 
<__main__.Score object at 0x...>

Errors are raised when not all samples have the same number of variables:

>>> bad_data = data.copy()
>>> bad_data[0] = bad_data[0][:,:-1]
>>> Score(bad_data, num_latent=2, **score_params)
Traceback (most recent call last):
...
ValueError: All samples must have the same number of variables.
>>> n_obs = np.array([len(sample) for sample in bad_data])
>>> sample_covariances = np.array([np.cov(sample, rowvar=False) for sample in bad_data])
>>> Score((sample_covariances, n_obs), num_latent=2, **score_params)
Traceback (most recent call last):
...
ValueError: All samples must have the same number of variables.

Or when one sample has a single observation:

>>> bad_data = data.copy()
>>> bad_data[0] = bad_data[0][[0], :]
>>> Score(bad_data, num_latent=2, **score_params)
Traceback (most recent call last):
...
ValueError: Each sample must contain at least two observations to estimate the covariance matrix.

Error when wrongly selecting the solver for B: >>> Score(data, num_latent=2, B_solver=’test’, **score_params) Traceback (most recent call last): … ValueError: Unrecognized value “test” for parameter B_solver.

score_dag(A, I, init_model=None, verbose=0)

Score the given DAG while allowing interventions on certain variables.

Parameters
  • A (numpy.ndarray) – The adjacency of the given DAG, where A[i, j] != 0 implies i -> j.

  • I (set) – The observed variables for which interventions are allowed, i.e. for which the noise term distribution is allowed to change between environments.

  • init_model (utlvce.Model, default = None) – To set a set of parameters, encoded by an instance of utlvce.model.Model as the starting point of the procedure.

  • verbose (int, default = 0) – If debug and execution traces should be printed. 0 corresponds to no traces, higher values correspond to higher verbosity.

Raises

ValueError: – If the given adjacency does not correspond to a DAG.

Returns

  • model (utlvce.Model) – The estimated model with all nuisance parameters. model.B returns the connectivity(weight) matrix found to maximize the score.

  • score (float) – The score attained by the given DAG adjacency.