Skip to content

Possible bug in LKJ ?? #873

@agoldin

Description

@agoldin

I tried to use LKJ distribution to sample correlation (and then covariance) matrix for MvNorm and, if I sample long enough, I always stumble into problem. It regularly happens with number of columns ~16, does not happen with 4 and I am not completely sure where the cutoff is.

import pymc3 as pm,numpy as np
from theano import tensor as T
import scipy as sp

def triIndex(N):
    n_elem = int(N * (N - 1) / 2) # move into function
    tri_index = np.zeros([N, N], dtype=int)
    tri_index[np.triu_indices(N, k=1)] = np.arange(n_elem)
    tri_index[np.triu_indices(N, k=1)[::-1]] = np.arange(n_elem)
    return tri_index    


import scipy as sp
N = 100
Nf = 16

mu_actual = sp.stats.uniform.rvs(-5, 10, size=Nf)
cov_actual_sqrt = sp.stats.uniform.rvs(0, 1, size=(Nf, Nf))
cov_actual = np.dot(cov_actual_sqrt.T, cov_actual_sqrt)

x = sp.stats.multivariate_normal.rvs(mu_actual, cov_actual, size=N)

#cov_actual

np.random.seed(3264602) 
tri = triIndex(Nf)
with pm.Model() as model:
     sigma = pm.Lognormal('sigma', np.zeros(Nf), np.ones(Nf), shape=Nf)


     C_triu = pm.LKJCorr('C_triu', 1, Nf) 

     C = C_triu[tri]
     C = T.fill_diagonal(C, 1)



     sigma_diag = pm.Deterministic('sigma_mat', T.nlinalg.diag(sigma))
     cov = pm.Deterministic('cov', T.nlinalg.matrix_dot(sigma_diag, C, sigma_diag))
     tau = pm.Deterministic('tau', T.nlinalg.matrix_inverse(cov))
     mu = pm.MvNormal('mu', 0, tau, shape=Nf)

     x_ = pm.MvNormal('x', mu, tau, observed=x)

     s = pm.Metropolis()
     trace = pm.sample(1000, s)

Symptoms of the problem:

from matplotlib import pyplot as plt
lp = [model.logp(trace[i]) for i in range(0,200)]
plt.plot(lp)

and you will see that logp becomes vertical.

tr16 = triIndex(Nf)
cr = trace[-1]['C_triu'][tr16]
np.fill_diagonal(cr,1)

np.linalg.eig(cr)[0]

array([-0.09574   , -0.01150316,  0.22189297,  1.98412337,  1.87778831,
    0.47466721,  0.57414119,  1.71681892,  1.58021031,  1.45534505,
    1.33115075,  1.20560476,  0.79869473,  1.0230756 ,  0.91071542,
    0.95301458])

Some of eigenvalues of reconstructed correlation matrix are negative, which, I suspect, is not correct.

model.logp() for LKJ happily calculates logp for all steps in a trace, except that for last values value of log() is ~ 10^156, and certainly not -np.inf

theano.version = '0.7.0.dev-RELEASE'
Mac OS, CUDA 7.5

$nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_15:14:46_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17

Am I doing something wrong?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions