File size: 2,449 Bytes
31dea96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python
"""
Inference untuk `Febriyansyah/phishing-email-classifier` — TF-IDF char_wb + LogReg.

Payload: model.joblib = {featurizer: hfhub.textfeat.Featurizer, learner: LogisticRegression, gateway: float}
Threshold operasional 0.488 (bukan 0.5).

Penggunaan:
    python predict.py "tempel-teks-email-di-sini"
    python predict.py --root ./models/phishing_model "Hello world"
"""

from __future__ import annotations

import argparse
import pickle
import sys
from pathlib import Path

# Pastikan hfhub.textfeat dapat di-import saat unpickle (lokal & Hub)
ROOT = Path(__file__).resolve().parents[1] if (Path(__file__).parent / "predict.py").exists() else Path.cwd()
for cand in [ROOT / "src", Path(__file__).resolve().parents[2] / "src", Path.cwd() / "src"]:
    if cand.exists() and str(cand) not in sys.path:
        sys.path.insert(0, str(cand))


def load_payload(model_root: Path):
    joblib = model_root / "model.joblib"
    meta = model_root / "metadata.json"
    if not joblib.exists():
        raise SystemExit(f"❌ '{joblib}' tidak ditemukan. Jalankan train_phishing_model.py dulu.")
    with joblib.open("rb") as fh:
        pl = pickle.load(fh)
    cfg = {}
    if meta.exists():
        import json
        cfg = json.loads(meta.read_text())
    return pl, cfg


def classify_one(root: Path, text: str) -> tuple[int, float, float]:
    """Return (label, proba_phishing, threshold)."""
    pl, _ = load_payload(root)
    featurizer = pl["featurizer"]
    clf = pl["learner"]
    thr = float(pl.get("gateway", 0.488))
    vec = featurizer.transform([text])
    proba = float(clf.predict_proba(vec)[0, 1])
    label = int(proba >= thr)
    return label, proba, thr


def main(argv=None):
    ap = argparse.ArgumentParser(description="Predict phishing probability")
    ap.add_argument("text", nargs="?", help="badan email")
    ap.add_argument("--root", default=str(Path(__file__).parent.parent /
                                          ".." / "models" / "phishing_model"))
    args = ap.parse_args(argv)

    txt = args.text or ""
    if not txt.strip():
        txt = ("URGENT!! Your account will be suspended today. Verify now: "
               "http://secure-login.bank-update.info/panel")

    lbl, pr, thr = classify_one(Path(args.root), txt)
    tag = "PHISHING" if lbl == 1 else "AMAN"
    print(f"\n[{tag}] prob-phishing={pr:.4f} (thr={thr:.3f})")
    return 0


if __name__ == "__main__":
    sys.exit(main())