SPB Git

spb/wp37_uqo

Public
2.6 KB · 45 lines python
1"""Recall of the name-based tiers (B/C/D) against GTIN ground truth (tier A pairs, Metro <-> Super C).23Ground truth: listing pairs sharing a GS1-valid UPC across the two Metro Inc. banners. For each truth pair we ask4whether the name/brand/size rules would have linked it without the GTIN. Also reports *false links* among GTIN-bearing5listings: name-based pairs between metro and superc whose UPCs differ (a precision check on a labelled subset).6"""7import pandas as pd, numpy as np8from rapidfuzz import fuzz9from src.common import path, get_logger10from src.matching.match_products import prepare, num_tokens1112log = get_logger("recall")1314def main():15    prod = pd.read_parquet(path("processed") / "products.parquet"); ret = pd.read_parquet(path("processed") / "retailers.parquet")16    p = prepare(prod, ret); g = p[p.gtin.notna()].copy()17    pairs = pd.read_parquet(path("processed") / "product_matches.parquet")18    truth = pairs[(pairs.tier == "A")][["uid_a", "uid_b"]]19    idx = g.set_index("uid")20    rows = []21    for ua, ub in truth.itertuples(index=False):22        a, b = idx.loc[ua], idx.loc[ub]23        brand_ok = a.bkey != "" and a.bkey == b.bkey24        size_ok = a.skey != "" and a.skey == b.skey25        sim = fuzz.token_set_ratio(a.nkey, b.nkey) / 100.026        nums_ok = num_tokens(a.nkey) == num_tokens(b.nkey)27        tier = None28        if brand_ok and size_ok and nums_ok and sim >= 0.90: tier = "B"29        elif brand_ok and size_ok and nums_ok and sim >= 0.80: tier = "C"30        elif brand_ok and a.skey == "" and b.skey == "" and nums_ok and sim >= 0.95: tier = "C"31        rows.append(dict(uid_a=ua, uid_b=ub, brand_ok=brand_ok, size_ok=size_ok, nums_ok=nums_ok, sim=sim, recovered_tier=tier,32                         brand_missing=(a.bkey == "" or b.bkey == ""), size_missing=(a.skey == "" or b.skey == "")))33    r = pd.DataFrame(rows)34    log.info("GTIN truth pairs: %d ; recovered by B: %.3f ; by B+C: %.3f", len(r), (r.recovered_tier == "B").mean(), r.recovered_tier.notna().mean())35    log.info("failure reasons among non-recovered: brand missing %.3f, brand differs %.3f, size missing %.3f, size differs %.3f, numeric tokens differ %.3f, sim<0.80 %.3f",36             *(r[r.recovered_tier.isna()][c].mean() for c in ["brand_missing"]),37             ((~r.brand_ok) & (~r.brand_missing))[r.recovered_tier.isna()].mean(),38             r[r.recovered_tier.isna()].size_missing.mean(),39             ((~r.size_ok) & (~r.size_missing))[r.recovered_tier.isna()].mean(),40             (~r[r.recovered_tier.isna()].nums_ok).mean(), (r[r.recovered_tier.isna()].sim < 0.80).mean())41    r.to_csv(path("processed") / "recall_gtin_truth.csv", index=False)4243if __name__ == "__main__":44    main()45
Files · 89317422cb4dbea4320a6406686df61364732b72
Menu

Theme