tensorflow / tensorflow/probability

Conflicting behaviour in Copula distribution example

Open
#807 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Jupyter Notebook
Stars
4.4k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

I am just exploring the Copula example provided in the documentation. I noticed some strange behaviour while computing the joint pdfs. Most of the code is copied from the example without any variation - just made changes to the marginals; I input Gaussian marginals with modified means and variances as below. Both copula.prob(coordinates[0][27]) and probs[0][0][27] should ideally give the same output (which happens in most of the cases). However, sometimes (as illustrated below), copula.prob outputs inf and probs outputs nan


from __future__ import print_function
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions

import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v2 as tf
tf.enable_v2_behavior()
tfd = tfp.distributions
tfb = tfp.bijectors

class GaussianCopulaTriL(tfd.TransformedDistribution):
  """Takes a location, and lower triangular matrix for the Cholesky factor."""
  def __init__(self, loc, scale_tril):
    super(GaussianCopulaTriL, self).__init__(
        distribution=tfd.MultivariateNormalTriL(
            loc=loc,
            scale_tril=scale_tril),
        bijector=tfb.NormalCDF(),
        validate_args=False,
        name="GaussianCopulaTriLUniform")


class WarpedGaussianCopula(tfd.TransformedDistribution):
  
  def __init__(self, loc, scale_tril, marginal_bijectors, block_sizes=None):
    super(WarpedGaussianCopula, self).__init__(
        distribution=GaussianCopulaTriL(loc=loc, scale_tril=scale_tril),
        bijector=tfb.Blockwise(bijectors=marginal_bijectors,
                               block_sizes=block_sizes),
        validate_args=False,
        name="GaussianCopula")
x_axis_interval = np.linspace(-3., 3., num=30, dtype=np.float32)
y_axis_interval = np.linspace(-3., 3., num=30, dtype=np.float32)
x_grid, y_grid = np.meshgrid(x_axis_interval, y_axis_interval)

coordinates = np.concatenate(
    [x_grid[..., np.newaxis], y_grid[..., np.newaxis]], -1)


def create_gaussian_copula(correlation):
  # Use Gaussian Copula to add dependence.
  return WarpedGaussianCopula(
      loc=[0.,  0.],
      scale_tril=[[1., 0.], [correlation, tf.sqrt(1. - correlation ** 2)]],
   
      marginal_bijectors=[
          tfb.Invert(tfb.NormalCDF() (tfb.Shift(-0.87498456*0.7276069)(tfb.Scale(1/0.7276069)))  ),
          tfb.Invert(tfb.NormalCDF() (tfb.Shift(-0.0044924864*0.21490721)(tfb.Scale(1/0.2149)))) ])


# Note that the zero case will correspond to independent marginals!
correlations = [0.]
copulas = []
probs = []
for correlation in correlations:
  copula = create_gaussian_copula(correlation)
  copulas.append(copula)
  probs.append(copula.prob(coordinates))


# Plot it's density

for correlation, copula_prob in zip(correlations, probs):
  plt.figure()
  plt.contour(x_grid, y_grid, copula_prob, 100, cmap=plt.cm.jet)
  plt.title('Correlation {}'.format(correlation))

print("direct prob computation",copula.prob(coordinates[0][27])) # gives inf
print(" appended prob",probs[0][0][27]) # gives nan

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is identified; start by running the pasted Copula example and comparing the batched copula.prob(coordinates) call with the direct copula.prob(coordinates[0][27]) call. Trace the TransformedDistribution, NormalCDF, and marginal bijector paths involved in both computations. Done means identifying why the two results differ and adding a regression test or documented reproduction for the corrected behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.