Griffiths 2011 - The Indian Buffet Process and Its Properties
Summary
The IBP is the sequential process: customer 1 takes dishes; customer takes each previously sampled dish with probability and then new dishes. The induced law on lof-classes is the infinite beta-Bernoulli limit; , each row has ones, and the matrix stays sparse.
Main Content
Indian buffet process
customers enter in order. Customer 1 samples dishes. Customer moves along the dishes already sampled by earlier customers and takes dish with probability ; then tries new dishes. iff customer took dish .
Probability of a generated matrix (Eq. 15)
With the number of new dishes of customer ,
Customers are not exchangeable under because the labelling depends on order. But generated matrices map to the same left-ordered form, and multiplying gives the exchangeable class probability of Eq. 14.
Exchangeable IBP. A variant that is directly exchangeable: customer makes one decision per set of dishes with the same history , taking of the dishes from the left, then new dishes; the result is in left-ordered form with probability .
Poisson representation (4.5). Collections of feature histories correspond to vectors . Setting independently reproduces Eq. 14, using (Eq. 16).
Properties (4.6)
(i) (sum of independent Poissons; equivalently sum of new-dish counts). (ii) Each object possesses features (by exchangeability, reduce to customer 1). (iii) , so remains sparse; this equals the limit of Eq. 11.
Examples
Expected number of features
: . A 500-draw simulation of the sequential process gave mean . The paper’s Figure 6 draw with : the first customer tried 17 dishes, the second took 7 of those and 3 new, the third took 3 shared, 5 from customer 1 only and 2 new.
import numpy as np
rng = np.random.default_rng(0)
def ibp(N, alpha):
counts, rows = [], []
for i in range(1, N + 1):
row = [k for k, m in enumerate(counts) if rng.random() < m / i]
new = rng.poisson(alpha / i)
row += list(range(len(counts), len(counts) + new))
counts += [0] * new
for k in row: counts[k] += 1
rows.append(row)
Z = np.zeros((N, len(counts)), int)
for i, r in enumerate(rows): Z[i, r] = 1
return Z
Ks = [ibp(20, 10.0).shape[1] for _ in range(500)]
print(np.mean(Ks), 10 * sum(1 / j for j in range(1, 21))) # ~36.2 vs 35.98Connections
Row-wise Poisson() is why both sets sparsity and dimensionality; the two-parameter IBP separates them (Griffiths 2011 - Two-Parameter IBP, Stick-Breaking and Beta Process).