Deepnar commited on
Commit
6a0de05
·
verified ·
1 Parent(s): 63ffc79

Upload folder using huggingface_hub

Browse files
README.md ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: xgboost
3
+ tags:
4
+ - fraud-detection
5
+ - phishing
6
+ - xgboost
7
+ - nexus
8
+ license: mit
9
+ ---
10
+
11
+ # NEXUS Fraud Detection — model artifacts
12
+
13
+ Trained heads for [NEXUS Fraud Detection](https://github.com/Deepnar/NEXUS-Fraud-Detection)
14
+ (forked from [Rishit1769/NEXUS-Fraud-Detection](https://github.com/Rishit1769/NEXUS-Fraud-Detection)).
15
+ Each folder is a drop-in `ml/artifacts/<task>/<version>/` directory: copy it into the
16
+ repo's `ml/artifacts/` (or point `MODEL_ARTIFACT_ROOT` at this repo) and the
17
+ FastAPI model service (`ml/service.py`) picks it up with no code changes.
18
+
19
+ | Head | Folder | Model | Unseen-data result |
20
+ |---|---|---|---|
21
+ | Transaction fraud (XGBoost + isotonic, Optuna-tuned) | `transaction/` | `model.json` + `calibration_model.joblib` | Fresh-seed PR-AUC 0.689; future-years slice 0.847 |
22
+ | Message phishing (TF-IDF char+word + lexical, XGB) | `message-tfidf/` | `model.json` + `vectorizer.joblib` | 18/18 hand-crafted probes |
23
+ | Message count baseline (XGB, fallback) | `message/` | `model.json` | advisory-only fallback |
24
+ | URL phishing (lexical XGB) | `url/` | `model.json` | 19/20 probes |
25
+
26
+ `eval_unseen.json` is the full unseen-data ledger. Per-head `metrics.json`,
27
+ `thresholds.json` (recall>=0.80 operating points), `feature_manifest.json`,
28
+ `split_manifest.json`, and `training_manifest.json` document provenance.
29
+
30
+ **Note:** deterministic rules stay authoritative in NEXUS — these heads are
31
+ advisory and never override a critical rule. Transaction data is synthetic
32
+ (IBM); retrain on real adjudicated cases before production use.
eval_unseen.json ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "created_at": "2026-09-23T18:02:04.813737+00:00",
3
+ "transaction_fresh": {
4
+ "artifact": "20260923T173528Z",
5
+ "n": 200000,
6
+ "seed": 123,
7
+ "fraud": 244,
8
+ "raw": {
9
+ "threshold": 0.5,
10
+ "precision": 0.4940828402366864,
11
+ "recall": 0.6844262295081968,
12
+ "f1": 0.5738831615120275,
13
+ "confusion_matrix": [
14
+ [
15
+ 199585,
16
+ 171
17
+ ],
18
+ [
19
+ 77,
20
+ 167
21
+ ]
22
+ ],
23
+ "pr_auc": 0.6889825876513987,
24
+ "roc_auc": 0.9883624004892526
25
+ },
26
+ "calibrated": {
27
+ "threshold": 0.5,
28
+ "precision": 0.7311320754716981,
29
+ "recall": 0.6352459016393442,
30
+ "f1": 0.6798245614035089,
31
+ "confusion_matrix": [
32
+ [
33
+ 199699,
34
+ 57
35
+ ],
36
+ [
37
+ 89,
38
+ 155
39
+ ]
40
+ ],
41
+ "pr_auc": 0.619499090899653,
42
+ "roc_auc": 0.8279988471180743
43
+ },
44
+ "op_recall80_raw": {
45
+ "mode": "recall>=0.8",
46
+ "threshold": 0.1666218638420105,
47
+ "precision": 0.15030674846625766,
48
+ "recall": 0.8032786885245902,
49
+ "f1": 0.2532299741602067,
50
+ "max_f1": 0.6984924623115578,
51
+ "max_f1_threshold": 0.8513908982276917,
52
+ "pr_auc": 0.6889825876513987
53
+ },
54
+ "future_2015+": {
55
+ "n": 73031,
56
+ "fraud": 95,
57
+ "raw": {
58
+ "threshold": 0.5,
59
+ "precision": 0.5785714285714286,
60
+ "recall": 0.8526315789473684,
61
+ "f1": 0.6893617021276596,
62
+ "confusion_matrix": [
63
+ [
64
+ 72877,
65
+ 59
66
+ ],
67
+ [
68
+ 14,
69
+ 81
70
+ ]
71
+ ],
72
+ "pr_auc": 0.8467382384273724,
73
+ "roc_auc": 0.998987432384845
74
+ },
75
+ "calibrated": {
76
+ "threshold": 0.5,
77
+ "precision": 0.7623762376237624,
78
+ "recall": 0.8105263157894737,
79
+ "f1": 0.7857142857142857,
80
+ "confusion_matrix": [
81
+ [
82
+ 72912,
83
+ 24
84
+ ],
85
+ [
86
+ 18,
87
+ 77
88
+ ]
89
+ ],
90
+ "pr_auc": 0.7654057891294648,
91
+ "roc_auc": 0.911895937606438
92
+ }
93
+ }
94
+ },
95
+ "url_probes": [
96
+ {
97
+ "url": "http://192.168.1.1/verify-login",
98
+ "expected": 1,
99
+ "p": 0.9995,
100
+ "correct": true
101
+ },
102
+ {
103
+ "url": "http://10.0.0.5/secure/update",
104
+ "expected": 1,
105
+ "p": 0.9996,
106
+ "correct": true
107
+ },
108
+ {
109
+ "url": "https://hdfc-bank-verify.tk/login",
110
+ "expected": 1,
111
+ "p": 0.9013,
112
+ "correct": true
113
+ },
114
+ {
115
+ "url": "https://xn--sbi-bank.com/login",
116
+ "expected": 1,
117
+ "p": 0.9062,
118
+ "correct": true
119
+ },
120
+ {
121
+ "url": "https://amaz0n-gift-winner.ml/claim-prize",
122
+ "expected": 1,
123
+ "p": 0.7169,
124
+ "correct": true
125
+ },
126
+ {
127
+ "url": "http://bit.ly/3xK9mQ2",
128
+ "expected": 1,
129
+ "p": 0.9998,
130
+ "correct": true
131
+ },
132
+ {
133
+ "url": "https://support-microsoft.tk/verify?user=admin@x",
134
+ "expected": 1,
135
+ "p": 0.4697,
136
+ "correct": false
137
+ },
138
+ {
139
+ "url": "https://login form.ga/secure@phish.com",
140
+ "expected": 1,
141
+ "p": 0.9955,
142
+ "correct": true
143
+ },
144
+ {
145
+ "url": "https://paytm-kyc-update%bank.com",
146
+ "expected": 1,
147
+ "p": 0.9991,
148
+ "correct": true
149
+ },
150
+ {
151
+ "url": "http://sbi--online.surge.sh/login",
152
+ "expected": 1,
153
+ "p": 0.9997,
154
+ "correct": true
155
+ },
156
+ {
157
+ "url": "https://income-tax-refund-goi.ml/claim",
158
+ "expected": 1,
159
+ "p": 0.8181,
160
+ "correct": true
161
+ },
162
+ {
163
+ "url": "https://flipkart-big-billion-day.ga/winner",
164
+ "expected": 1,
165
+ "p": 0.7265,
166
+ "correct": true
167
+ },
168
+ {
169
+ "url": "https://www.google.com/search?q=hello",
170
+ "expected": 0,
171
+ "p": 0.0386,
172
+ "correct": true
173
+ },
174
+ {
175
+ "url": "https://github.com/anomalyco/opencode",
176
+ "expected": 0,
177
+ "p": 0.1533,
178
+ "correct": true
179
+ },
180
+ {
181
+ "url": "https://www.hdfcbank.com/personal/payments",
182
+ "expected": 0,
183
+ "p": 0.1051,
184
+ "correct": true
185
+ },
186
+ {
187
+ "url": "https://en.wikipedia.org/wiki/Phishing",
188
+ "expected": 0,
189
+ "p": 0.1002,
190
+ "correct": true
191
+ },
192
+ {
193
+ "url": "https://www.amazon.in/gp/your-account/order-history",
194
+ "expected": 0,
195
+ "p": 0.0989,
196
+ "correct": true
197
+ },
198
+ {
199
+ "url": "https://stackoverflow.com/questions/12345",
200
+ "expected": 0,
201
+ "p": 0.0924,
202
+ "correct": true
203
+ },
204
+ {
205
+ "url": "https://www.rbi.org.in/Scripts/FAQView.aspx",
206
+ "expected": 0,
207
+ "p": 0.3015,
208
+ "correct": true
209
+ },
210
+ {
211
+ "url": "https://mail.google.com/mail/u/0/#inbox",
212
+ "expected": 0,
213
+ "p": 0.0762,
214
+ "correct": true
215
+ }
216
+ ],
217
+ "message_probes": [
218
+ {
219
+ "text": "URGENT: Your HDFC account will be BLOCKED in 2 hours. Share your OTP now to veri",
220
+ "expected": 1,
221
+ "p": 0.9827,
222
+ "correct": true
223
+ },
224
+ {
225
+ "text": "Dear customer your SBI netbanking password expired. Login immediately at https:/",
226
+ "expected": 1,
227
+ "p": 0.8327,
228
+ "correct": true
229
+ },
230
+ {
231
+ "text": "Congratulations! You won a Rs.50000 Flipkart gift voucher. Claim FREE prize now,",
232
+ "expected": 1,
233
+ "p": 0.9979,
234
+ "correct": true
235
+ },
236
+ {
237
+ "text": "Income Tax Dept: you have a refund of Rs.18,450. Share bank details + OTP confid",
238
+ "expected": 1,
239
+ "p": 0.9764,
240
+ "correct": true
241
+ },
242
+ {
243
+ "text": "Your parcel is held at customs. Pay Rs.250 fee via UPI and share screenshot, do ",
244
+ "expected": 1,
245
+ "p": 0.9179,
246
+ "correct": true
247
+ },
248
+ {
249
+ "text": "Hi mom this is my new number, I lost my phone. Please transfer Rs.20000 urgently",
250
+ "expected": 1,
251
+ "p": 0.9464,
252
+ "correct": true
253
+ },
254
+ {
255
+ "text": "KYC expired! Your Paytm wallet will be suspended today. Install this APK to veri",
256
+ "expected": 1,
257
+ "p": 0.9089,
258
+ "correct": true
259
+ },
260
+ {
261
+ "text": "Bank manager here, share the OTP you just received to stop the fraudulent transa",
262
+ "expected": 1,
263
+ "p": 0.9421,
264
+ "correct": true
265
+ },
266
+ {
267
+ "text": "Part-time job offer: earn Rs.5000/day from home, pay Rs.500 registration fee fir",
268
+ "expected": 1,
269
+ "p": 0.9627,
270
+ "correct": true
271
+ },
272
+ {
273
+ "text": "Your electricity bill is overdue, connection cut tonight. Call now and share car",
274
+ "expected": 1,
275
+ "p": 0.9249,
276
+ "correct": true
277
+ },
278
+ {
279
+ "text": "Hey, are we still on for lunch tomorrow? Let me know what time works for you",
280
+ "expected": 0,
281
+ "p": 0.0007,
282
+ "correct": true
283
+ },
284
+ {
285
+ "text": "Your OTP for Swiggy login is 482913. Do not share it with anyone.",
286
+ "expected": 0,
287
+ "p": 0.0043,
288
+ "correct": true
289
+ },
290
+ {
291
+ "text": "Meeting moved to 3pm in conference room B. Agenda attached in the calendar invit",
292
+ "expected": 0,
293
+ "p": 0.0358,
294
+ "correct": true
295
+ },
296
+ {
297
+ "text": "Happy birthday! Hope you have a wonderful day. Dinner at our place on Sunday?",
298
+ "expected": 0,
299
+ "p": 0.0099,
300
+ "correct": true
301
+ },
302
+ {
303
+ "text": "Your Amazon order #402-1234567 has shipped and will arrive Thursday. Track in th",
304
+ "expected": 0,
305
+ "p": 0.0339,
306
+ "correct": true
307
+ },
308
+ {
309
+ "text": "Reminder: dentist appointment tomorrow at 10am. Reply YES to confirm.",
310
+ "expected": 0,
311
+ "p": 0.0464,
312
+ "correct": true
313
+ },
314
+ {
315
+ "text": "The bill for dinner was Rs.2400, your share is Rs.800. UPI me when free, no rush",
316
+ "expected": 0,
317
+ "p": 0.1077,
318
+ "correct": true
319
+ },
320
+ {
321
+ "text": "Photos from the trek are uploaded, check the shared album when you get time!",
322
+ "expected": 0,
323
+ "p": 0.0112,
324
+ "correct": true
325
+ }
326
+ ]
327
+ }
message-tfidf/feature_manifest.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "feature_version": "message-tfidf-1",
3
+ "lexical_columns": [
4
+ "message_length",
5
+ "word_count",
6
+ "url_count",
7
+ "email_count",
8
+ "phone_count",
9
+ "digit_count",
10
+ "uppercase_ratio",
11
+ "special_ratio",
12
+ "urgency_terms",
13
+ "credential_terms",
14
+ "payment_terms",
15
+ "impersonation_terms",
16
+ "secrecy_terms",
17
+ "reward_terms",
18
+ "attachment_terms",
19
+ "share_request_terms",
20
+ "code_receipt_terms",
21
+ "no_share_advice_terms"
22
+ ],
23
+ "n_tfidf_features": 50000
24
+ }
message-tfidf/metrics.json ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "message-tfidf",
3
+ "method": "tfidf char_wb(3,5)+word(1,2) + 18 lexical, XGB",
4
+ "rows": 12843,
5
+ "class_balance": {
6
+ "0": 10249,
7
+ "1": 2594
8
+ },
9
+ "validation": {
10
+ "threshold": 0.5,
11
+ "precision": 0.9945205479452055,
12
+ "recall": 0.9355670103092784,
13
+ "f1": 0.9641434262948207,
14
+ "confusion_matrix": [
15
+ [
16
+ 1535,
17
+ 2
18
+ ],
19
+ [
20
+ 25,
21
+ 363
22
+ ]
23
+ ],
24
+ "pr_auc": 0.9859947462223423,
25
+ "roc_auc": 0.9930913749505329
26
+ },
27
+ "test": {
28
+ "threshold": 0.5,
29
+ "precision": 0.9945945945945946,
30
+ "recall": 0.9460154241645244,
31
+ "f1": 0.9696969696969697,
32
+ "confusion_matrix": [
33
+ [
34
+ 1534,
35
+ 2
36
+ ],
37
+ [
38
+ 21,
39
+ 368
40
+ ]
41
+ ],
42
+ "pr_auc": 0.996182276471391,
43
+ "roc_auc": 0.998712979327335
44
+ },
45
+ "operating_recall80": {
46
+ "mode": "recall>=0.8",
47
+ "threshold": 0.5573006272315979,
48
+ "precision": 1.0,
49
+ "recall": 0.9357326478149101,
50
+ "f1": 0.9667994687915007,
51
+ "max_f1": 0.9781771501925547,
52
+ "max_f1_threshold": 0.12930667400360107,
53
+ "pr_auc": 0.996182276471391
54
+ }
55
+ }
message-tfidf/model.json ADDED
The diff for this file is too large to render. See raw diff
 
message-tfidf/split_manifest.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "strategy": "grouped_stratified",
3
+ "groups": "normalized-text-hash",
4
+ "sizes": {
5
+ "train": 8993,
6
+ "validation": 1925,
7
+ "test": 1925
8
+ }
9
+ }
message-tfidf/thresholds.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "mode": "recall>=0.8",
3
+ "threshold": 0.5573006272315979,
4
+ "precision": 1.0,
5
+ "recall": 0.9357326478149101,
6
+ "f1": 0.9667994687915007,
7
+ "max_f1": 0.9781771501925547,
8
+ "max_f1_threshold": 0.12930667400360107,
9
+ "pr_auc": 0.996182276471391
10
+ }
message-tfidf/training_manifest.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "message-tfidf",
3
+ "created_at": "20260923T180128Z",
4
+ "python": "3.12.13",
5
+ "platform": "Linux-7.2.6-1-cachyos-x86_64-with-glibc2.44",
6
+ "config": {
7
+ "seed": 42,
8
+ "output_dir": "ml/artifacts",
9
+ "data": {
10
+ "url_dataset": "PhiUSIIL_Phishing_URL_Dataset.csv",
11
+ "phishtank_dataset": "verified_online.csv",
12
+ "benign_domains": "top-1m.csv",
13
+ "message_dataset": "Dataset_5971.csv",
14
+ "sms_collection": "SMSSpamCollection",
15
+ "transaction_n_sample": 1000000,
16
+ "transaction_cache": "ml/.txn-cache"
17
+ },
18
+ "split": {
19
+ "train": 0.7,
20
+ "validation": 0.15,
21
+ "test": 0.15
22
+ },
23
+ "model": {
24
+ "n_estimators": 300,
25
+ "max_depth": 5,
26
+ "learning_rate": 0.04,
27
+ "min_child_weight": 3,
28
+ "subsample": 0.85,
29
+ "colsample_bytree": 0.85,
30
+ "reg_alpha": 0.2,
31
+ "reg_lambda": 2.0,
32
+ "tree_method": "hist"
33
+ },
34
+ "transaction_model": {
35
+ "n_estimators": 200,
36
+ "max_depth": 6,
37
+ "learning_rate": 0.1,
38
+ "min_child_weight": 3,
39
+ "subsample": 0.9,
40
+ "colsample_bytree": 0.9,
41
+ "reg_alpha": 0.2,
42
+ "reg_lambda": 2.0,
43
+ "tree_method": "hist"
44
+ }
45
+ }
46
+ }
message-tfidf/vectorizer.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64c191b6d964b6a167db275470fdbd1b52e0e968fd7d1cf83202967ff66c2d9b
3
+ size 1799782
message/feature_defaults.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "message_length": 64.0,
3
+ "word_count": 12.0,
4
+ "url_count": 0.0,
5
+ "email_count": 0.0,
6
+ "phone_count": 0.0,
7
+ "digit_count": 0.0,
8
+ "uppercase_ratio": 0.05,
9
+ "special_ratio": 0.044444444444444446,
10
+ "urgency_terms": 0.0,
11
+ "credential_terms": 0.0,
12
+ "payment_terms": 0.0,
13
+ "impersonation_terms": 0.0,
14
+ "secrecy_terms": 0.0,
15
+ "reward_terms": 0.0,
16
+ "attachment_terms": 0.0,
17
+ "share_request_terms": 0.0,
18
+ "code_receipt_terms": 0.0,
19
+ "no_share_advice_terms": 0.0
20
+ }
message/feature_manifest.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "feature_version": "message-features-1",
3
+ "columns": [
4
+ "message_length",
5
+ "word_count",
6
+ "url_count",
7
+ "email_count",
8
+ "phone_count",
9
+ "digit_count",
10
+ "uppercase_ratio",
11
+ "special_ratio",
12
+ "urgency_terms",
13
+ "credential_terms",
14
+ "payment_terms",
15
+ "impersonation_terms",
16
+ "secrecy_terms",
17
+ "reward_terms",
18
+ "attachment_terms",
19
+ "share_request_terms",
20
+ "code_receipt_terms",
21
+ "no_share_advice_terms"
22
+ ],
23
+ "dtypes": {
24
+ "message_length": "float64",
25
+ "word_count": "float64",
26
+ "url_count": "float64",
27
+ "email_count": "float64",
28
+ "phone_count": "float64",
29
+ "digit_count": "float64",
30
+ "uppercase_ratio": "float64",
31
+ "special_ratio": "float64",
32
+ "urgency_terms": "float64",
33
+ "credential_terms": "float64",
34
+ "payment_terms": "float64",
35
+ "impersonation_terms": "float64",
36
+ "secrecy_terms": "float64",
37
+ "reward_terms": "float64",
38
+ "attachment_terms": "float64",
39
+ "share_request_terms": "float64",
40
+ "code_receipt_terms": "float64",
41
+ "no_share_advice_terms": "float64"
42
+ }
43
+ }
message/metrics.json ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "message",
3
+ "rows": 12143,
4
+ "class_balance": {
5
+ "0": 9969,
6
+ "1": 2174
7
+ },
8
+ "train": {
9
+ "threshold": 0.5,
10
+ "precision": 0.9905341446923597,
11
+ "recall": 0.9619172685489166,
12
+ "f1": 0.9760159893404398,
13
+ "confusion_matrix": [
14
+ [
15
+ 6966,
16
+ 14
17
+ ],
18
+ [
19
+ 58,
20
+ 1465
21
+ ]
22
+ ],
23
+ "pr_auc": 0.996749294134677,
24
+ "roc_auc": 0.999207189851127
25
+ },
26
+ "validation": {
27
+ "threshold": 0.5,
28
+ "precision": 0.9737704918032787,
29
+ "recall": 0.9138461538461539,
30
+ "f1": 0.9428571428571428,
31
+ "confusion_matrix": [
32
+ [
33
+ 1487,
34
+ 8
35
+ ],
36
+ [
37
+ 28,
38
+ 297
39
+ ]
40
+ ],
41
+ "pr_auc": 0.981019973792235,
42
+ "roc_auc": 0.9938893748392076
43
+ },
44
+ "test": {
45
+ "threshold": 0.5,
46
+ "precision": 0.976897689768977,
47
+ "recall": 0.9079754601226994,
48
+ "f1": 0.9411764705882353,
49
+ "confusion_matrix": [
50
+ [
51
+ 1487,
52
+ 7
53
+ ],
54
+ [
55
+ 30,
56
+ 296
57
+ ]
58
+ ],
59
+ "pr_auc": 0.9829470354932671,
60
+ "roc_auc": 0.9945220555021723
61
+ },
62
+ "baseline_logistic": {
63
+ "validation": {
64
+ "threshold": 0.5,
65
+ "precision": 0.841225626740947,
66
+ "recall": 0.9292307692307692,
67
+ "f1": 0.8830409356725147,
68
+ "confusion_matrix": [
69
+ [
70
+ 1438,
71
+ 57
72
+ ],
73
+ [
74
+ 23,
75
+ 302
76
+ ]
77
+ ],
78
+ "pr_auc": 0.9541509594868397,
79
+ "roc_auc": 0.9820097761770002
80
+ },
81
+ "test": {
82
+ "threshold": 0.5,
83
+ "precision": 0.8559077809798271,
84
+ "recall": 0.911042944785276,
85
+ "f1": 0.8826151560178306,
86
+ "confusion_matrix": [
87
+ [
88
+ 1444,
89
+ 50
90
+ ],
91
+ [
92
+ 29,
93
+ 297
94
+ ]
95
+ ],
96
+ "pr_auc": 0.9653032775140513,
97
+ "roc_auc": 0.9904238631417285
98
+ }
99
+ }
100
+ }
message/model.json ADDED
The diff for this file is too large to render. See raw diff
 
message/split_manifest.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "strategy": "grouped_stratified",
3
+ "groups": "domain-or-normalized-text",
4
+ "sizes": {
5
+ "train": 8503,
6
+ "validation": 1820,
7
+ "test": 1820
8
+ }
9
+ }
message/training_manifest.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "message",
3
+ "created_at": "20260923T175009Z",
4
+ "python": "3.12.13",
5
+ "platform": "Linux-7.2.6-1-cachyos-x86_64-with-glibc2.44",
6
+ "config": {
7
+ "seed": 42,
8
+ "output_dir": "ml/artifacts",
9
+ "data": {
10
+ "url_dataset": "PhiUSIIL_Phishing_URL_Dataset.csv",
11
+ "phishtank_dataset": "verified_online.csv",
12
+ "benign_domains": "top-1m.csv",
13
+ "message_dataset": "Dataset_5971.csv",
14
+ "sms_collection": "SMSSpamCollection",
15
+ "transaction_n_sample": 1000000,
16
+ "transaction_cache": "ml/.txn-cache"
17
+ },
18
+ "split": {
19
+ "train": 0.7,
20
+ "validation": 0.15,
21
+ "test": 0.15
22
+ },
23
+ "model": {
24
+ "n_estimators": 300,
25
+ "max_depth": 5,
26
+ "learning_rate": 0.04,
27
+ "min_child_weight": 3,
28
+ "subsample": 0.85,
29
+ "colsample_bytree": 0.85,
30
+ "reg_alpha": 0.2,
31
+ "reg_lambda": 2.0,
32
+ "tree_method": "hist"
33
+ },
34
+ "transaction_model": {
35
+ "n_estimators": 200,
36
+ "max_depth": 6,
37
+ "learning_rate": 0.1,
38
+ "min_child_weight": 3,
39
+ "subsample": 0.9,
40
+ "colsample_bytree": 0.9,
41
+ "reg_alpha": 0.2,
42
+ "reg_lambda": 2.0,
43
+ "tree_method": "hist"
44
+ }
45
+ }
46
+ }
transaction/calibration.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "isotonic",
3
+ "fit_on": "validation",
4
+ "calibrated": true,
5
+ "X_min": [
6
+ 1.2015421816613525e-05
7
+ ],
8
+ "n_thresholds": 28
9
+ }
transaction/calibration_model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:65853c1509299376d124f05dee740b1fb3431cbc1737ca5ab1122d1a821cf689
3
+ size 775
transaction/feature_defaults.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Amount": 30.15,
3
+ "LogAmount": 3.4388142452334622,
4
+ "Hour": 12.0,
5
+ "Minute": 30.0,
6
+ "Year": 2013.0,
7
+ "Month": 7.0,
8
+ "Day": 16.0,
9
+ "Zip": 40906.0,
10
+ "MCC": 5499.0,
11
+ "IsOnline": 0.0,
12
+ "StateMissing": 0.0,
13
+ "StateRisky": 0.0,
14
+ "HasError": 0.0,
15
+ "IsNight": 0.0,
16
+ "CreditLimit": 13325.0,
17
+ "CardOnDarkWeb": 0.0,
18
+ "FicoScore": 700.0
19
+ }
transaction/feature_manifest.json ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "feature_version": "transaction-features-1",
3
+ "columns": [
4
+ "Amount",
5
+ "LogAmount",
6
+ "Hour",
7
+ "Minute",
8
+ "Year",
9
+ "Month",
10
+ "Day",
11
+ "Zip",
12
+ "MCC",
13
+ "IsOnline",
14
+ "StateMissing",
15
+ "StateRisky",
16
+ "HasError",
17
+ "IsNight",
18
+ "CreditLimit",
19
+ "CardOnDarkWeb",
20
+ "FicoScore"
21
+ ],
22
+ "dtypes": {
23
+ "Amount": "float64",
24
+ "LogAmount": "float64",
25
+ "Hour": "float64",
26
+ "Minute": "float64",
27
+ "Year": "float64",
28
+ "Month": "float64",
29
+ "Day": "float64",
30
+ "Zip": "float64",
31
+ "MCC": "float64",
32
+ "IsOnline": "float64",
33
+ "StateMissing": "float64",
34
+ "StateRisky": "float64",
35
+ "HasError": "float64",
36
+ "IsNight": "float64",
37
+ "CreditLimit": "float64",
38
+ "CardOnDarkWeb": "float64",
39
+ "FicoScore": "float64"
40
+ }
41
+ }
transaction/metrics.json ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "transaction",
3
+ "method": "xgboost-optuna-isotonic (Person2 Tuning4 family)",
4
+ "rows": 1000000,
5
+ "n_sample_requested": 1000000,
6
+ "trials": 10,
7
+ "best_params": {
8
+ "n_estimators": 401,
9
+ "max_depth": 8,
10
+ "learning_rate": 0.030392898611614688,
11
+ "subsample": 0.9875376798995805,
12
+ "colsample_bytree": 0.6856947435981403,
13
+ "min_child_weight": 4,
14
+ "reg_alpha": 0.9715538656755343,
15
+ "reg_lambda": 2.009496629328365,
16
+ "scale_pos_weight": 50,
17
+ "tree_method": "hist"
18
+ },
19
+ "best_val_pr_auc": 0.6350730656911171,
20
+ "class_balance": {
21
+ "0": 998780,
22
+ "1": 1220
23
+ },
24
+ "test_calibrated": {
25
+ "threshold": 0.5,
26
+ "precision": 0.7515923566878981,
27
+ "recall": 0.6483516483516484,
28
+ "f1": 0.6961651917404129,
29
+ "confusion_matrix": [
30
+ [
31
+ 149727,
32
+ 39
33
+ ],
34
+ [
35
+ 64,
36
+ 118
37
+ ]
38
+ ],
39
+ "pr_auc": 0.6088987134136661,
40
+ "roc_auc": 0.8276938764399203
41
+ },
42
+ "test_raw": {
43
+ "threshold": 0.5,
44
+ "precision": 0.48314606741573035,
45
+ "recall": 0.7087912087912088,
46
+ "f1": 0.5746102449888643,
47
+ "confusion_matrix": [
48
+ [
49
+ 149628,
50
+ 138
51
+ ],
52
+ [
53
+ 53,
54
+ 129
55
+ ]
56
+ ],
57
+ "pr_auc": 0.7071943534022936,
58
+ "roc_auc": 0.9920050003279842
59
+ },
60
+ "operating_recall80": {
61
+ "mode": "max-F1 (min-recall unreachable)",
62
+ "threshold": 0.5333333611488342,
63
+ "precision": 0.8014184397163121,
64
+ "recall": 0.6208791208791209,
65
+ "f1": 0.6996904024767802,
66
+ "max_f1": 0.6996904024767802,
67
+ "max_f1_threshold": 0.5333333611488342,
68
+ "pr_auc": 0.6088987134136661
69
+ }
70
+ }
transaction/model.json ADDED
The diff for this file is too large to render. See raw diff
 
transaction/split_manifest.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "strategy": "grouped_stratified",
3
+ "groups": "User-Card",
4
+ "sizes": {
5
+ "train": 700009,
6
+ "validation": 150043,
7
+ "test": 149948
8
+ }
9
+ }
transaction/thresholds.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "mode": "max-F1 (min-recall unreachable)",
3
+ "threshold": 0.5333333611488342,
4
+ "precision": 0.8014184397163121,
5
+ "recall": 0.6208791208791209,
6
+ "f1": 0.6996904024767802,
7
+ "max_f1": 0.6996904024767802,
8
+ "max_f1_threshold": 0.5333333611488342,
9
+ "pr_auc": 0.6088987134136661
10
+ }
transaction/training_manifest.json ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "transaction",
3
+ "created_at": "20260923T173528Z",
4
+ "python": "3.12.13",
5
+ "platform": "Linux-7.2.6-1-cachyos-x86_64-with-glibc2.44",
6
+ "config": {
7
+ "seed": 42,
8
+ "output_dir": "ml/artifacts",
9
+ "data": {
10
+ "url_dataset": "PhiUSIIL_Phishing_URL_Dataset.csv",
11
+ "phishtank_dataset": "verified_online.csv",
12
+ "benign_domains": "top-1m.csv",
13
+ "message_dataset": "Dataset_5971.csv",
14
+ "sms_collection": "SMSSpamCollection",
15
+ "transaction_n_sample": 1000000,
16
+ "transaction_cache": "ml/.txn-cache"
17
+ },
18
+ "split": {
19
+ "train": 0.7,
20
+ "validation": 0.15,
21
+ "test": 0.15
22
+ },
23
+ "model": {
24
+ "n_estimators": 300,
25
+ "max_depth": 5,
26
+ "learning_rate": 0.04,
27
+ "min_child_weight": 3,
28
+ "subsample": 0.85,
29
+ "colsample_bytree": 0.85,
30
+ "reg_alpha": 0.2,
31
+ "reg_lambda": 2.0,
32
+ "tree_method": "hist"
33
+ },
34
+ "transaction_model": {
35
+ "n_estimators": 200,
36
+ "max_depth": 6,
37
+ "learning_rate": 0.1,
38
+ "min_child_weight": 3,
39
+ "subsample": 0.9,
40
+ "colsample_bytree": 0.9,
41
+ "reg_alpha": 0.2,
42
+ "reg_lambda": 2.0,
43
+ "tree_method": "hist"
44
+ }
45
+ },
46
+ "best_params": {
47
+ "n_estimators": 401,
48
+ "max_depth": 8,
49
+ "learning_rate": 0.030392898611614688,
50
+ "subsample": 0.9875376798995805,
51
+ "colsample_bytree": 0.6856947435981403,
52
+ "min_child_weight": 4,
53
+ "reg_alpha": 0.9715538656755343,
54
+ "reg_lambda": 2.009496629328365,
55
+ "scale_pos_weight": 50,
56
+ "tree_method": "hist"
57
+ }
58
+ }
url/feature_defaults.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "lex_url_length": 30.0,
3
+ "lex_host_length": 19.0,
4
+ "lex_path_ratio": 0.0,
5
+ "lex_query_ratio": 0.0,
6
+ "lex_has_ip_host": 0.0,
7
+ "lex_has_punycode": 0.0,
8
+ "lex_dot_density": 0.07142857142857142,
9
+ "lex_hyphen_density": 0.0,
10
+ "lex_digit_density_host": 0.0,
11
+ "lex_at_count": 0.0,
12
+ "lex_percent_count": 0.0,
13
+ "lex_has_https": 1.0,
14
+ "lex_subdomain_count": 1.0,
15
+ "lex_uses_shortener": 0.0,
16
+ "lex_has_query": 0.0
17
+ }
url/feature_manifest.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "feature_version": "url-features-1",
3
+ "columns": [
4
+ "lex_url_length",
5
+ "lex_host_length",
6
+ "lex_path_ratio",
7
+ "lex_query_ratio",
8
+ "lex_has_ip_host",
9
+ "lex_has_punycode",
10
+ "lex_dot_density",
11
+ "lex_hyphen_density",
12
+ "lex_digit_density_host",
13
+ "lex_at_count",
14
+ "lex_percent_count",
15
+ "lex_has_https",
16
+ "lex_subdomain_count",
17
+ "lex_uses_shortener",
18
+ "lex_has_query"
19
+ ],
20
+ "dtypes": {
21
+ "lex_url_length": "float64",
22
+ "lex_host_length": "float64",
23
+ "lex_path_ratio": "float64",
24
+ "lex_query_ratio": "float64",
25
+ "lex_has_ip_host": "float64",
26
+ "lex_has_punycode": "float64",
27
+ "lex_dot_density": "float64",
28
+ "lex_hyphen_density": "float64",
29
+ "lex_digit_density_host": "float64",
30
+ "lex_at_count": "float64",
31
+ "lex_percent_count": "float64",
32
+ "lex_has_https": "float64",
33
+ "lex_subdomain_count": "float64",
34
+ "lex_uses_shortener": "float64",
35
+ "lex_has_query": "float64"
36
+ }
37
+ }
url/metrics.json ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "url",
3
+ "rows": 265795,
4
+ "class_balance": {
5
+ "0": 164850,
6
+ "1": 100945
7
+ },
8
+ "train": {
9
+ "threshold": 0.5,
10
+ "precision": 0.9934578065274919,
11
+ "recall": 0.9563131527553707,
12
+ "f1": 0.9745316623642578,
13
+ "confusion_matrix": [
14
+ [
15
+ 114950,
16
+ 445
17
+ ],
18
+ [
19
+ 3087,
20
+ 67575
21
+ ]
22
+ ],
23
+ "pr_auc": 0.9950598196654774,
24
+ "roc_auc": 0.9954755812752186
25
+ },
26
+ "validation": {
27
+ "threshold": 0.5,
28
+ "precision": 0.9940553467714384,
29
+ "recall": 0.9606444796619124,
30
+ "f1": 0.977064374223446,
31
+ "confusion_matrix": [
32
+ [
33
+ 24641,
34
+ 87
35
+ ],
36
+ [
37
+ 596,
38
+ 14548
39
+ ]
40
+ ],
41
+ "pr_auc": 0.9958790243223578,
42
+ "roc_auc": 0.9963766503274593
43
+ },
44
+ "test": {
45
+ "threshold": 0.5,
46
+ "precision": 0.9918386941910706,
47
+ "recall": 0.955281062157342,
48
+ "f1": 0.9732166890982503,
49
+ "confusion_matrix": [
50
+ [
51
+ 24608,
52
+ 119
53
+ ],
54
+ [
55
+ 677,
56
+ 14462
57
+ ]
58
+ ],
59
+ "pr_auc": 0.9949988385310375,
60
+ "roc_auc": 0.9956094566805189
61
+ },
62
+ "baseline_logistic": {
63
+ "validation": {
64
+ "threshold": 0.5,
65
+ "precision": 0.8875435144543666,
66
+ "recall": 0.774432118330692,
67
+ "f1": 0.8271387262853517,
68
+ "confusion_matrix": [
69
+ [
70
+ 23242,
71
+ 1486
72
+ ],
73
+ [
74
+ 3416,
75
+ 11728
76
+ ]
77
+ ],
78
+ "pr_auc": 0.933550849183027,
79
+ "roc_auc": 0.9421230430293426
80
+ },
81
+ "test": {
82
+ "threshold": 0.5,
83
+ "precision": 0.8950725450339946,
84
+ "recall": 0.8435167448312306,
85
+ "f1": 0.8685302319254573,
86
+ "confusion_matrix": [
87
+ [
88
+ 23230,
89
+ 1497
90
+ ],
91
+ [
92
+ 2369,
93
+ 12770
94
+ ]
95
+ ],
96
+ "pr_auc": 0.946916161484859,
97
+ "roc_auc": 0.9527697172724541
98
+ }
99
+ }
100
+ }
url/model.json ADDED
The diff for this file is too large to render. See raw diff
 
url/split_manifest.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "strategy": "grouped_stratified",
3
+ "groups": "domain-or-normalized-text",
4
+ "sizes": {
5
+ "train": 186057,
6
+ "validation": 39872,
7
+ "test": 39866
8
+ }
9
+ }
url/training_manifest.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "url",
3
+ "created_at": "20260923T174835Z",
4
+ "python": "3.12.13",
5
+ "platform": "Linux-7.2.6-1-cachyos-x86_64-with-glibc2.44",
6
+ "config": {
7
+ "seed": 42,
8
+ "output_dir": "ml/artifacts",
9
+ "data": {
10
+ "url_dataset": "PhiUSIIL_Phishing_URL_Dataset.csv",
11
+ "phishtank_dataset": "verified_online.csv",
12
+ "benign_domains": "top-1m.csv",
13
+ "message_dataset": "Dataset_5971.csv",
14
+ "sms_collection": "SMSSpamCollection",
15
+ "transaction_n_sample": 1000000,
16
+ "transaction_cache": "ml/.txn-cache"
17
+ },
18
+ "split": {
19
+ "train": 0.7,
20
+ "validation": 0.15,
21
+ "test": 0.15
22
+ },
23
+ "model": {
24
+ "n_estimators": 300,
25
+ "max_depth": 5,
26
+ "learning_rate": 0.04,
27
+ "min_child_weight": 3,
28
+ "subsample": 0.85,
29
+ "colsample_bytree": 0.85,
30
+ "reg_alpha": 0.2,
31
+ "reg_lambda": 2.0,
32
+ "tree_method": "hist"
33
+ },
34
+ "transaction_model": {
35
+ "n_estimators": 200,
36
+ "max_depth": 6,
37
+ "learning_rate": 0.1,
38
+ "min_child_weight": 3,
39
+ "subsample": 0.9,
40
+ "colsample_bytree": 0.9,
41
+ "reg_alpha": 0.2,
42
+ "reg_lambda": 2.0,
43
+ "tree_method": "hist"
44
+ }
45
+ }
46
+ }