#!/usr/bin/env python3 """Kural tabanlı aday süzgeci (DeBERTa yok): görünür + etkileşimli etiketler + metni dolu yaygın etiketler, TF-IDF sırasıyla en fazla K aday. pos_idx yeniden hesaplanır. Kullanım: python m2w_filter.py --data m2w_full_all --out m2w_v2 --K 128""" import argparse, gzip, json, os import numpy as np INTER = {"a", "button", "input", "select", "textarea", "option", "label", "summary"} EXTRA = {"li", "img", "svg", "i", "span", "div", "td", "tr", "th", "h1", "h2", "h3", "h4", "p"} def level(c): """0 = görünür + etkileşimli etiket (öncelikli), 1 = görünür + metni dolu yaygın etiket, None = at.""" b = c.get("bbox") if b is None or b[2] <= 0 or b[3] <= 0: return None if c["tag"] in INTER: return 0 if c["tag"] in EXTRA and "|" in c["text"] and len(c["text"].split("|")[-1].strip()) > 0: return 1 return None def select(cands, K): """Önce seviye 0 (TF-IDF sırasıyla, en çok K), yer kalırsa seviye 1; sonra özgün TF-IDF sırasına döndür.""" lv = [level(c) for c in cands] first = [i for i, l in enumerate(lv) if l == 0][:K] rest = [i for i, l in enumerate(lv) if l == 1][: K - len(first)] return sorted(first + rest) def main(): ap = argparse.ArgumentParser() ap.add_argument("--data", default="m2w_full_all") ap.add_argument("--out", default="m2w_v2") ap.add_argument("--K", type=int, default=160) ap.add_argument("--splits", nargs="+", default=["train", "val", "test_task", "test_website", "test_domain"]) a = ap.parse_args() os.makedirs(a.out, exist_ok=True) summ = {} for s in a.splits: p = os.path.join(a.data, f"{s}.jsonl.gz") if not os.path.exists(p): continue n = hit = 0 sizes = [] with gzip.open(p, "rt", encoding="utf-8") as f, gzip.open(os.path.join(a.out, f"{s}.jsonl.gz"), "wt", encoding="utf-8") as g: for l in f: ex = json.loads(l) pos = set(ex["pos_idx"]) keep = select(ex["cands"], a.K) new = dict(ex) new["cands"] = [ex["cands"][i] for i in keep] new["pos_idx"] = [r for r, i in enumerate(keep) if i in pos] new["n_total_before"] = len(ex["cands"]) new["dropped_pos"] = [ex["cands"][i] for i in sorted(pos) if i not in set(keep)] # eğitimde "doğruyu ekle" için g.write(json.dumps(new, ensure_ascii=False) + "\n") n += 1; hit += len(new["pos_idx"]) > 0; sizes.append(len(keep)) summ[s] = {"n": n, f"recall@K": hit / n, "aday_ortanca": int(np.median(sizes)), "aday_p90": int(np.percentile(sizes, 90))} print(f" {s}: n={n} | doğru kalıyor (tavan)={hit/n:.3f} | aday ortanca={summ[s]['aday_ortanca']} p90={summ[s]['aday_p90']}") json.dump(summ, open(os.path.join(a.out, "filtre_ozet.json"), "w"), indent=2) if __name__ == "__main__": main()