dsp-repro-bundle / claim2.py
junwatu's picture
Upload folder using huggingface_hub
c881b77 verified
Raw
History Blame Contribute Delete
2.6 kB
"""Claim 2 verification: Proposition 5.1 & Corollary 5.2.
Prop 5.1: p_hat_{mu,K}(x_i) = 1/(N V_d mu_i^d) * (1/K Sum_k k^{1/d})^d is a local
density estimator (asymptotically p(x_i)).
Cor 5.2: at ICDM convergence, mu_i ~ mu_bar for all i => p_hat equal everywhere
(density uniformized).
We verify numerically:
(a) p_hat_{mu,K} correlates with the true density in a mixture of Gaussians.
(b) after ICDM, the spread of mu_i collapses (std -> ~0) while raw std is large,
confirming density gradient removal.
"""
import numpy as np
import sys, os
sys.path.insert(0, os.path.dirname(__file__))
from gicdm_core import pairwise_sq_dists, icdm_scaling, knn_distances
def unit_ball_volume(d):
from math import gamma, pi
return (pi ** (d / 2)) / gamma(d / 2 + 1)
def p_hat_mu_k(X, K):
D = pairwise_sq_dists(X)
mu = knn_distances(D, K, self_included=True).mean(axis=1)
N, d = X.shape
Vd = unit_ball_volume(d)
w = (np.sum([k ** (1.0 / d) for k in range(1, K + 1)]) / K) ** d
return 1.0 / (N * Vd * mu ** d) * w, mu
def run():
rng = np.random.default_rng(0)
# Mixture of two Gaussians with different variances -> different densities
d = 20
n1, n2 = 800, 800
X = np.vstack([
rng.normal(0, 0.5, size=(n1, d)),
rng.normal(3, 2.0, size=(n2, d)),
])
true_dens = np.concatenate([
(2 * np.pi * 0.25) ** (-d / 2) * np.ones(n1),
(2 * np.pi * 4.0) ** (-d / 2) * np.ones(n2),
])
K = 20
phat, mu = p_hat_mu_k(X, K)
# correlation between estimator and true density (log scale, robust)
log_corr = np.corrcoef(np.log(phat), np.log(true_dens))[0, 1]
# ICDM convergence: spread of mu before/after
mu_before = mu.copy()
delta, mu_after = icdm_scaling(pairwise_sq_dists(X), K, n_iter=10, return_mu=True)
res = dict(
d=d, N=len(X), K=K,
log_corr_density=float(log_corr),
mu_before_std=float(mu_before.std()),
mu_before_cv=float(mu_before.std() / mu_before.mean()),
mu_after_std=float(mu_after.std()),
mu_after_cv=float(mu_after.std() / mu_after.mean()),
)
print("Prop 5.1 log-correlation p_hat vs true density:", round(res['log_corr_density'], 3))
print("mu_i std before ICDM:", round(res['mu_before_std'], 4),
"| after ICDM:", round(res['mu_after_std'], 5))
print("mu_i CV before ICDM:", round(res['mu_before_cv'], 4),
"| after ICDM:", round(res['mu_after_cv'], 5))
return res
if __name__ == "__main__":
import json
res = run()
json.dump(res, open("results/claim2_density.json", "w"))