adyoi commited on
Commit
aec8784
·
verified ·
1 Parent(s): b05971d

Upload audit_kamus.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. audit_kamus.py +117 -0
audit_kamus.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import json
3
+ import os
4
+ import random
5
+ import time
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+
9
+ ROOT = Path(__file__).resolve().parent
10
+ UA = {"User-Agent": "Mozilla/5.0 (audit-kamus-indigo)"}
11
+
12
+
13
+ def cek_pypi(word):
14
+ try:
15
+ from kbbi import KBBI, TidakDitemukan
16
+ except ImportError:
17
+ return None
18
+ try:
19
+ KBBI(word)
20
+ return True
21
+ except TidakDitemukan:
22
+ return False
23
+ except Exception:
24
+ return None
25
+
26
+
27
+ def cek_web(word):
28
+ import requests
29
+
30
+ try:
31
+ from urllib.parse import quote
32
+
33
+ r = requests.get(
34
+ f"https://kbbi.web.id/{quote(word)}", timeout=15, headers=UA
35
+ )
36
+ if r.status_code != 200:
37
+ return None
38
+ marker = "Maaf, tidak ditemukan kata yang dicari"
39
+ jumlah = r.text.count(marker)
40
+ if jumlah == 0:
41
+ return None
42
+ return jumlah < 3
43
+ except Exception:
44
+ return None
45
+
46
+
47
+ def main():
48
+ ap = argparse.ArgumentParser(
49
+ description="Audit wordlist kamus terhadap KBBI daring (sampling acak)"
50
+ )
51
+ ap.add_argument("--kamus", default=str(ROOT / "data" / "kamus_id.txt"))
52
+ ap.add_argument("--n", type=int, default=200, help="jumlah kata yang diambil sampel")
53
+ ap.add_argument("--seed", type=int, default=1337)
54
+ ap.add_argument("--delay", type=float, default=0.8, help="jeda antar-permintaan (detik)")
55
+ ap.add_argument("--backend", choices=["auto", "pypi", "web"], default="auto",
56
+ help="web: kbbi.web.id (heuristik jumlah marker; rapuh)")
57
+ ap.add_argument("--apply", action="store_true",
58
+ help="hapus kata TIDAK-DIKENAL dari kamus (backup otomatis)")
59
+ ap.add_argument("--out", default=None, help="path laporan json")
60
+ args = ap.parse_args()
61
+
62
+ kamus_path = Path(args.kamus)
63
+ kata_semua = [w.strip() for w in kamus_path.read_text(encoding="utf-8").splitlines() if w.strip()]
64
+ rng = random.Random(args.seed)
65
+ sampel = sorted(rng.sample(kata_semua, min(args.n, len(kata_semua))))
66
+ print(f"kamus={kamus_path.name} ({len(kata_semua):,} kata) | sampel={len(sampel)} | seed={args.seed}")
67
+
68
+ hasil = {}
69
+ n_ada = n_tidak = n_gagal = 0
70
+ t0 = time.time()
71
+ for i, w in enumerate(sampel, 1):
72
+ status = None
73
+ if args.backend in ("auto", "pypi"):
74
+ status = cek_pypi(w)
75
+ if status is None and args.backend in ("auto", "web"):
76
+ status = cek_web(w)
77
+ hasil[w] = status
78
+ if status is True:
79
+ n_ada += 1
80
+ elif status is False:
81
+ n_tidak += 1
82
+ else:
83
+ n_gagal += 1
84
+ if i % 10 == 0 or i == len(sampel):
85
+ print(f" {i}/{len(sampel)} | ada={n_ada} tidak={n_tidak} gagal={n_gagal} | {time.time() - t0:.0f}s")
86
+ time.sleep(args.delay)
87
+
88
+ ditolak = sorted(w for w, s in hasil.items() if s is False)
89
+ laporan = {
90
+ "timestamp": datetime.now().isoformat(timespec="seconds"),
91
+ "kamus": str(kamus_path),
92
+ "ukuran_kamus": len(kata_semua),
93
+ "sampel": len(sampel),
94
+ "seed": args.seed,
95
+ "ada": n_ada,
96
+ "tidak_dikenal": n_tidak,
97
+ "gagal_ceks": n_gagal,
98
+ "estimasi_entri_tidak_valid": round(n_tidak / max(1, len(sampel) - n_gagal) * len(kata_semua)),
99
+ "kata_ditolak": ditolak,
100
+ }
101
+ out = Path(args.out) if args.out else ROOT / "runs" / f"kamus_audit_{datetime.now():%Y%m%d_%H%M%S}.json"
102
+ out.parent.mkdir(parents=True, exist_ok=True)
103
+ out.write_text(json.dumps(laporan, ensure_ascii=False, indent=2), encoding="utf-8")
104
+ print(f"laporan -> {out}")
105
+ print(f"ringkasan: ada={n_ada} | tidak-dikenal={n_tidak} | gagal={n_gagal} "
106
+ f"| estimasi entri tak-valid di kamus: ~{laporan['estimasi_entri_tidak_valid']:,}")
107
+
108
+ if args.apply and ditolak:
109
+ backup = kamus_path.with_suffix(".bak.txt")
110
+ backup.write_text("\n".join(sorted(kata_semua)) + "\n", encoding="utf-8")
111
+ bersih = [w for w in kata_semua if w not in set(ditolak)]
112
+ kamus_path.write_text("\n".join(bersih) + "\n", encoding="utf-8")
113
+ print(f"--apply: {len(ditolak)} kata dihapus, kamus {len(kata_semua):,} -> {len(bersih):,}, backup={backup.name}")
114
+
115
+
116
+ if __name__ == "__main__":
117
+ main()