Poisson-truncated normal data

Table of Contents

Introduction

Zihao Wang shared an example simulated data set where ash gives a surprising result.

Setup

import numpy as np
import scipy.stats as st
import scmodes
%matplotlib inline
%config InlineBackend.figure_formats = set(['retina'])
import matplotlib.pyplot as plt
plt.rcParams['figure.facecolor'] = 'w'
plt.rcParams['font.family'] = 'Nimbus Sans'

Example

np.random.seed(1)
N = 5000
lam = np.clip(np.random.normal(loc=10, scale=5, size=N), 0, None)
x = np.random.poisson(lam=lam)
s = np.ones(x.shape)
grid = np.linspace(x.min(), x.max(), 1000)
F = st.norm(loc=10, scale=5)
true_cdf = F.cdf(0) + F.sf(0) * F.cdf(grid)
cm = plt.get_cmap('Dark2')
plt.clf()
fig, ax = plt.subplots(2, 1)
fig.set_size_inches(5, 4)

ax[0].hist(x, bins=np.arange(x.max() + 1), color='k')
ax[0].set_xlabel('$x$')
ax[0].set_ylabel('$n_x$')

for i, (method, t) in enumerate(zip(['zig', 'unimodal'], ['Point-Gamma', 'Unimodal'])):
  ax[1].plot(*getattr(scmodes.deconvolve, f'fit_{method}')(x, s), label=t, c=cm(i), lw=1)
ax[1].plot(grid, true_cdf, label='Ground truth', c=cm(2), lw=1)
ax[1].legend(frameon=False)
ax[1].set_xlabel('$\lambda$')
ax[1].set_ylabel('CDF')

fig.tight_layout()

example.png

The grid we used to parameterize the unimodal distribution is:

np.exp(np.arange(np.log(1 / s.mean()), np.log((x / s).max()), step=.5 * np.log(2)))
array([ 1.        ,  1.41421356,  2.        ,  2.82842712,  4.        ,
5.65685425,  8.        , 11.3137085 , 16.        , 22.627417  ,
32.        ])

Author: Abhishek Sarkar

Created: 2019-10-23 Wed 12:20

Validate