#!/usr/bin/env python3 """Construit un dev DIFFICILE = proxy Phase 2 (nouveaux locuteurs). Prend les clips de validation dont le locuteur a le MOINS de clips au train (faible exposition). Ce sont les plus proches des locuteurs inconnus de la Phase 2. Sert d'oracle pour valider la robustesse SANS l'optimisme des locuteurs vus.""" import json from collections import Counter LANGS = ["lin", "lug", "sna"] MANIF = "/scratch/prep/manifests" def read(p): return [json.loads(l) for l in open(p, encoding="utf-8")] def main(): summary = {} for lang in LANGS: train = read(f"{MANIF}/waxal_{lang}_train.jsonl") val = read(f"{MANIF}/waxal_{lang}_validation.jsonl") # exposition = nb de clips train par locuteur expo = Counter(r.get("speaker", "") for r in train) # trier les clips val par exposition de leur locuteur (croissant = plus dur) val_scored = [(expo.get(r.get("speaker", ""), 0), r) for r in val if r["text"].strip()] val_scored.sort(key=lambda x: x[0]) # dev difficile = 40% des clips val a plus faible exposition n = len(val_scored) hard = [r for _, r in val_scored[:int(n * 0.4)]] with open(f"{MANIF}/waxal_{lang}_devhard.jsonl", "w", encoding="utf-8") as f: for r in hard: f.write(json.dumps(r, ensure_ascii=False) + "\n") expos = [e for e, _ in val_scored[:int(n * 0.4)]] summary[lang] = {"n_hard": len(hard), "expo_median": sorted(expos)[len(expos)//2] if expos else 0, "expo_max_in_hard": max(expos) if expos else 0} print(f"{lang}: dev difficile = {len(hard)} clips (locuteurs a expo <= {max(expos) if expos else 0} clips train)") # dev difficile mixte with open(f"{MANIF}/waxal_mix_devhard.jsonl", "w", encoding="utf-8") as f: for lang in LANGS: for l in open(f"{MANIF}/waxal_{lang}_devhard.jsonl", encoding="utf-8"): f.write(l) print("DEVHARD_DONE", summary) if __name__ == "__main__": main()