Skip to content
leakcheck
Security ML · dataset audit

How much of a 99% score is the test set copying the training set?

leakcheck finds duplicated rows, contradictory labels, future data and one-column shortcuts across train/test splits, then retrains the standard models without them.

KDD Cup 99 · real rows same features, both sides
TRAIN · sample of 12,000
#2 · neptune · tcp/private/S0
#6801 · normal · tcp/http/SFcopied
#1 · smurf · icmp/ecr_i/SFcopied
#1 · smurf · icmp/ecr_i/SFcopied
#3 · smurf · icmp/ecr_i/SF
TEST · sample of 4,000
#3 · neptune · tcp/private/REJ
#1 · normal · tcp/http/SF= #6801
#2 · smurf · icmp/ecr_i/SF= #1
#4 · smurf · icmp/ecr_i/SF= #1
#5 · neptune · tcp/private/REJ

Row numbers from the KDD sample you can load in the scanner.

68.4%exact copies

of KDD Cup 99's test rows have exactly the same features as a training row. Removing leaked rows costs up to 17.5 macro-F1 points.

8 benchmarks audited9,498,817 rows
5 of 8 leak ≥ 5% of their test setexact copies of training rows
0 errors on 720 planted-leak testssynthetic validation
01The problem

A high score can be a lookup, not a detector

Security benchmarks make high scores easy: on a random split of CIC-IDS2017, untuned baseline models reach 97.1–99.9% macro-F1. Many benchmarks put identical or near-identical rows on both sides of the train/test split, mix future data into training, or contain a single column that gives the label away.

A model can then score by recognising rows it has already seen. That says little about how it handles traffic or files it has not seen, which is the thing a deployment needs.

What leakcheck measures
How much of a benchmark's score is earned on rows the model has already seen, and how much remains once they are removed.
02What it checks

Six checks on every split

L1 · EXACT COPIES Test rows identical to a training row, after canonical hashing.
L2 · NEAR COPIES Test rows within a tiny distance of a training row (tabular), or Jaccard >= 0.8 (text, MinHash + exact check), compared with how close training rows sit to each other.
L3 · LABEL CONFLICTS Identical features with different labels, and the accuracy ceiling they impose.
L4 · TIME LEAKAGE Training rows newer than test rows, and the timestamp as a one-feature classifier.
L5 · SHORTCUTS A single feature that predicts the label on its own, and identifier-like columns.
L6 · GROUP OVERLAP The same host, family or session on both sides of the split.

leakcheck clean removes the leakage, then re-reads its own output and re-checks every row. If anything remains, it fails.

03The audit

Eight benchmarks, one audit

Highlighted: exact copies ≥ 5% · single feature ≥ 95%
leakcheck audit of eight security benchmarks
DatasetDomainSplit Test rowsExact copies Near copies (× train baseline)Best single feature
KDD Cup 99 Network intrusion official 311,029 68.4% 14.8% (×1.37) src_bytes (93.8%)
NSL-KDD Network intrusion official 22,544 2.9% 30.1% (×0.60) src_bytes (83.0%)
UNSW-NB15 Network intrusion official 82,332 10.4% 7.5% (×1.35) smean (79.1%)
CIC-IDS2017 Network intrusion random 80/20 566,149 14.1% 62.7% (×0.98) Destination Port (90.2%)
EMBER 2018 Malware (PE files) official 200,000 0.009% 20.0% (×0.79) sec_entropy_max (71.7%)
UCI Phishing Websites Phishing random 80/20 2,211 64.4% 0.0% SSLfinal_State (90.3%)
PhiUSIIL Phishing URLs random 80/20 47,159 0.0% 0.31% (×1.32) URLSimilarityIndex 99.6%
SMS Spam Collection Spam random 80/20 1,115 11.0% — —

× train baseline above 1 means test rows sit closer to training rows than training rows sit to each other. Best single feature is the balanced accuracy of a small tree on that one column.

04What the leakage is worth

Same copying, very different damage

KDD Cup 99 loses 17.5 macro-F1 points when its leaked test rows are removed. UCI Phishing, with as much copying, loses 1.5.

Macro-F1 points lost
Logistic regressionGradient boosting
KDD Cup 99 17.515.0
NSL-KDD 11.98.8
SMS Spam Collection 3.12.5
EMBER 2018 (random split) 2.41.3
UNSW-NB15 2.01.0
UCI Phishing Websites 1.50.8
PhiUSIIL 0.00.0
CIC-IDS2017 -0.3-0.1
05101520 pts

Four untuned baselines × 5 seeds; this chart shows two of them. Over the five seeds the 95% interval for KDD Cup 99's logistic-regression gap is 16.9–18.2 points; small gaps are less certain: UCI Phishing's gradient-boosting gap of 0.8 has an interval of -0.1 to 1.7, which includes zero. All four models, with 95% intervals, are in RESULTS.md.

05Pre-registered

9 hypotheses, decided by rules fixed before the runs

H1
At least half of the benchmarks leak ≥ 5% of their test set into training. 5 of 8 datasets.
SUPPORTED
H2
Removing the copies costs ≥ 5 macro-F1 points on the two most-copied benchmarks. KDD99 loses 15.0–17.5 points; UCI Phishing loses at most 1.7.
NOT SUPPORTED
H3
A time-based split hurts more than removing copies. EMBER: the time split costs 1.9–2.6 points vs 1.3–2.4 for removing near-copies; a margin of 0.3–0.9.
SUPPORTED
H4
Weaker models lean harder on leaked rows. LR gap > HistGB gap on 6 of 6 eligible datasets; the paired 95% interval is above zero on 4 of 6 (KDD Cup 99, NSL-KDD, UNSW-NB15, EMBER 2018).
SUPPORTED
H5
Some benchmark is solved by a single feature. PhiUSIIL: URLSimilarityIndex alone reaches 99.6% balanced accuracy.
SUPPORTED
H6
Tuning and all the training data do not make the copies stop mattering. Tuned gradient boosting on all 4,898,431 KDD Cup 99 training rows still loses 22.2 points; NSL-KDD 8.6. Every seed's interval is above 5.
SUPPORTED
H7
Weaker models lean harder on copies, with intervals and a tuned model. Logistic regression's gap exceeds tuned boosting's on 4 of 4 large benchmarks, with the paired interval above zero in every seed.
SUPPORTED
H8
Whether a gap clears one point does not depend on the near-copy threshold. The same in 32 of 40 cells; every change is a gap near one point. The large gaps hold at every threshold.
NOT SUPPORTED
H9
On network traffic, a time split costs more than removing copies. Raw UNSW-NB15: the time split costs 0.2–0.5 points, removing near-copies 4.3–6.5.
NOT SUPPORTED

Each decision rule was committed to PLAN.md before the experiment it judges was run.

06What we learned

Four findings

FINDING 01

Copying is not the same as inflation.

UCI Phishing copies about as much as KDD Cup 99 (64.4% vs 68.4% of test rows) but loses only 1.5 macro-F1 points when the copies go, against 17.5 for KDD Cup 99. With 30 features of 2–3 values each, a UCI Phishing copy is just a common pattern a model gets right anyway; KDD Cup 99's copies are memorised exceptions, and 73% of its gap comes from near-copies rather than exact ones.

Logistic regression: KDD99 −17.5 vs UCI −1.5
FINDING 02

The control comes back clean.

EMBER 2018's official split is by time. leakcheck finds 0.009% exact copies, 0.0% of training files newer than the test period, and test rows further from training than training rows are from each other (×0.79). The audit does not flag everything.

EMBER 2018: 0.009% copies · no future data
FINDING 03

Too easy to rank models.

Every baseline scores at least 99.99% macro-F1 on PhiUSIIL. Removing the four features that each reach 95% on their own still leaves at least 99.95%. A test that easy cannot tell models apart.

Best single feature: URLSimilarityIndex 99.6%
FINDING 04

Random splits can hide a collapse.

On CIC-IDS2017 the baselines score 97.1–99.9% macro-F1 on a random split, and 46.2–56.5% when trained on earlier capture days and tested on the last ones, whose attack types (PortScan, DDoS) never appear in training.

Gradient boosting: random split 99.9% → later days 46.2%
07Validation

Checked against the literature

KDD Cup 99 records / distinct records, against Tables I and II of Tavallaee et al. (2009), the paper that introduced NSL-KDD:

SlicePaperleakcheckStatus
Train · total 4,898,431 / 1,074,992 4,898,431 / 1,074,992 exact
Train · attack 3,925,650 / 262,178 3,925,650 / 262,178 exact
Train · normal 972,781 / 812,814 972,781 / 812,814 exact
Test · total 311,027 / 77,289 311,029 / 77,291 +2 records
Test · attack 250,436 / 29,378 250,436 / 29,378 exact
Test · normal 60,591 / 47,911 60,593 / 47,913 +2 records

The two-record difference is in the paper's test-set normal count (60,591); the published file has 60,593.

Synthetic validation
720 / 720planted-leak configurations recovered with zero counting error
97%of 95% intervals cover the true near-copy rate
100%text near-copy recall at Jaccard ≥ 0.8, zero false positives
08Reproduce

Reproduce every number

bash · laptop CPU, no GPU
# 1. Install, then fetch every dataset (SHA-256 verified)
> python -m venv .venv
# then activate it: .venv\Scripts\activate (Windows) or source .venv/bin/activate
> python -m pip install -e ".[dev]"
> python scripts/fetch.py
# 2. Validate, audit, retrain, ablate
> python -m experiments.e0_sources && python -m experiments.e0_sources_week4
> python -m experiments.e0_synthetic && python -m experiments.e0_kdd
> python -m experiments.e1_audit
> python -m experiments.e2_retrain kdd99 nslkdd unsw_nb15 cicids2017 ember2018 uci_phishing phiusiil sms_spam
> python -m experiments.e4_ablation phiusiil cicids2017
# 3. Regenerate the report and this page's numbers
> python scripts/report.py
Every run appends a line to an append-only ledger; this page is generated from it. 21 ledger lines behind this page
09Scope

Limitations

  • A copy is not always a bug: real traffic repeats. Both the original and the cleaned score are reported.
  • The cleaned test set is harder by construction; the gap measures how much of a score was earned on copies.
  • Near-copy thresholds (0.01 RMS, Jaccard 0.8) are fixed choices; a curve and a training-set baseline are reported alongside.
  • Baselines are untuned standard models, and training sets are capped at 300,000 rows.
  • EMBER is scanned on leakcheck's own numeric view, not the official 2,381-dimension feature vector.
  • CIC-IDS2017's time split is confounded with unseen attack types, so H3 was decided on EMBER.