| """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 = {} |
|
|
| |
| Xr = rng.normal(0, 1, size=(n, d)); Xg0 = rng.normal(0, 1, size=(n, d)) |
| scenarios['gauss_mean_equal'] = (Xr.copy(), Xg0.copy()) |
|
|
| |
| Xg_std = rng.normal(0, 1.5, size=(n, d)) |
| scenarios['gauss_std_1p5'] = (Xr.copy(), Xg_std.copy()) |
|
|
| |
| sr = sphere(d, n, 1.0, rng); sg = sphere(d, n, 1.0, rng) |
| scenarios['hypersphere_equal'] = (sr, sg) |
|
|
| |
| 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()) |
|
|
| |
| st = sphere(d, n, 1.0, rng) + 3.0 |
| 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() |
|
|