De Blasi 2015 - EPPF and Predictive Structure
Summary
An exchangeable sequence has a de Finetti measure on random probability measures . If is discrete, samples have ties and induce a random partition whose law is the exchangeable partition probability function (EPPF). The EPPF determines the predictive distribution by ratios; DP and PY have closed-form EPPFs.
Main Content
Exchangeability. is exchangeable iff there exists on with , (Eq. 1). Parametric if lives on a finite-dimensional subspace; nonparametric if its support is infinite-dimensional. The one-step predictive equals the posterior mean (Eq. 2).
)
A discrete random probability measure (Eq. 3) with , a.s., diffuse, independent of the weights. With such that , : observations are species labels, and .
EPPF (Eq. 5) and addition rule (Eq. 6)
A sample of size with distinct values and frequencies has probability
It satisfies .
Closed-form EPPFs and predictive distributions (Eqs. 7-11)
Dirichlet process (parameters ): , with . Pitman-Yor (, or with , ): . Generic: and
PY: and ; recovers the DP/CRP.
The addition rule guarantees the predictive probabilities sum to one.
Applications (1.2). Species sampling: with an observed sample of labels one may want the number of new distinct species in an additional sample of size , the number of species with a given frequency or below a threshold, and the probability that the next draw has a species of frequency . Mixtures: , , (Eq. 12); with a DP this is Lo’s DP mixture; in the latent ‘s is the number of clusters.
Examples
Numerically verify the PY EPPF sums to one
For , , : summing the EPPF over all 52 set partitions of gives 1 (brute-force check, as in E30).
import numpy as np
from scipy.special import gammaln
def lrise(x, m): return gammaln(x + m) - gammaln(x) # log (x)_m
def log_eppf_py(sizes, sigma, theta):
k, n = len(sizes), sum(sizes)
return (np.log(theta + sigma*np.arange(1, k)).sum() - lrise(theta + 1, n - 1)
+ sum(lrise(1 - sigma, s - 1) for s in sizes))
def partitions(n):
def rec(i, blocks):
if i == n: yield [len(b) for b in blocks]; return
for b in blocks:
b.append(i); yield from rec(i + 1, blocks); b.pop()
blocks.append([i]); yield from rec(i + 1, blocks); blocks.pop()
yield from rec(0, [])
print(sum(np.exp(log_eppf_py(p, 0.4, 1.3)) for p in partitions(5))) # 1.0000000000000009PyMC-style sketch (untested; the E30 “no latent assignments” idea)
import pymc as pm, pytensor.tensor as pt
# Mi[i-1] = number of species seen exactly i times; n = sum(i*Mi), k = sum(Mi)
with pm.Model():
sigma = pm.Beta("sigma", 1, 1) # discount in [0,1)
theta = pm.Gamma("theta", 2, 0.1) # concentration > -sigma
lrise = lambda x, m: pt.gammaln(x + m) - pt.gammaln(x)
i = pt.arange(1, k) # product over i = 1..k-1
logp = (pt.log(theta + sigma * i).sum() - lrise(theta + 1, n - 1)
+ (Mi * lrise(1 - sigma, np.arange(Mi.size))).sum()) # (1-sigma)_{i-1}
pm.Potential("eppf", logp) # NUTS on (sigma, theta) onlyConnections
Teh 2010 - Blackwell-MacQueen Urn and Chinese Restaurant Process (DP case with proof of the number of clusters); IBP derivation by limits: Griffiths 2011 - Infinite Mixtures and the CRP Review.