dsp-repro-bundle / claim5_official.py
junwatu's picture
Upload folder using huggingface_hub
c881b77 verified
Raw
History Blame Contribute Delete
3.12 kB
"""Claim 5 (faithful, scaled): Raisa et al. synthetic benchmark mechanism.
Uses the OFFICIAL GICDM repo (github.com/nicolassalvy/GICDM) Clipped Density /
Clipped Coverage with the standard vs GICDM DataProcessor. We run representative
Raisa scenarios on modest synthetic data (scaled down N,d) and tally whether each
metric behaves correctly with/without GICDM. We report the *direction* of change
and note the paper's full pass counts (Clipped Density Purpose 8/14 -> 10/14,
Bounds 8/13 -> 11/13; Clipped Coverage 8/14->10/14, 9/13->11/13).
"""
import numpy as np
import sys, os
sys.path.insert(0, "/Users/equan_p/Developer/playground/ICML-2/official/GICDM")
from metrics.hubness_processor.standard import DataProcessorStandard
from metrics.hubness_processor.gicdm import GICDM
from metrics.metrics.clipped_density_coverage import ClippedDensityCoverage
def make_processor(Xr, use_gicdm, K=5):
if use_gicdm:
return GICDM(Xr, K=K, n_jobs=4, scale_factor=10)
return DataProcessorStandard(Xr, K=K, n_jobs=4)
def cd_cc(Xr, Xg, use_gicdm, K=5):
dp = make_processor(Xr, use_gicdm, K)
cdc = ClippedDensityCoverage(dp)
cd = cdc.clipped_density(Xg)
cc = cdc.clipped_coverage(Xg)
return float(cd), float(cc)
def sphere(d, n, r, rng):
v = rng.normal(size=(n, d)); v /= np.linalg.norm(v, axis=1, keepdims=True)
return v * r
def main():
rng = np.random.default_rng(0)
d, n = 100, 1500
rows = []
scenarios = {}
# 1. GAUSSIAN MEAN DIFFERENCE: shift=0 -> identical -> CD,CC should be ~1
Xr = rng.normal(0, 1, size=(n, d)); Xg0 = rng.normal(0, 1, size=(n, d))
scenarios['gauss_mean_equal'] = (Xr.copy(), Xg0.copy())
# 2. GAUSSIAN STD DEVIATION DIFFERENCE: scale mismatch
Xg_std = rng.normal(0, 1.5, size=(n, d))
scenarios['gauss_std_1p5'] = (Xr.copy(), Xg_std.copy())
# 3. HYPERSPHERE SURFACE equal radius (should be ~1)
sr = sphere(d, n, 1.0, rng); sg = sphere(d, n, 1.0, rng)
scenarios['hypersphere_equal'] = (sr, sg)
# 4. MODE COLLAPSE: gen collapses to one of 5 modes
centers = rng.normal(0, 5, size=(5, d))
Xr_m = centers[rng.integers(0, 5, n)] + rng.normal(0, 0.3, (n, d))
Xg_mc = centers[0] + rng.normal(0, 0.3, (n, d))
scenarios['mode_collapse'] = (Xr_m.copy(), Xg_mc.copy())
Xg_mf = centers[rng.integers(0, 5, n)] + rng.normal(0, 0.3, (n, d))
scenarios['mode_full'] = (Xr_m.copy(), Xg_mf.copy())
# 5. SPHERE vs TORUS-like (sphere vs scaled sphere offset)
st = sphere(d, n, 1.0, rng) + 3.0 # offset sphere -> out of manifold
scenarios['sphere_offset'] = (sr.copy(), st.copy())
results = {}
for name, (Xr_, Xg_) in scenarios.items():
cd0, cc0 = cd_cc(Xr_, Xg_, False)
cdg, ccg = cd_cc(Xr_, Xg_, True)
results[name] = dict(cd_raw=cd0, cc_raw=cc0, cd_gicdm=cdg, cc_gicdm=ccg)
print(f"{name:18s} CD raw={cd0:.3f} GICDM={cdg:.3f} | CC raw={cc0:.3f} GICDM={ccg:.3f}")
import json
json.dump(results, open("/Users/equan_p/Developer/playground/ICML-2/repro_gicdm/results/claim5_official.json", "w"))
if __name__ == "__main__":
main()