Every example so far used synthetic flow features. The field's oldest and still most widely taught benchmark, the 1999 KDD Cup dataset (Unit 6 covers its refined descendant, NSL-KDD, in full), is real network traffic captured during a DARPA intrusion-detection evaluation, and it is directly loadable through scikit-learn with no download step of your own.
load_kdd99.py
from sklearn.datasets import fetch_kddcup99
data = fetch_kddcup99(subset=None, percent10=True, random_state=0)
X, y = data.data, data.target
is_attack = (y != b"normal.").astype(int)
print(f"Rows: {len(y):,}, features: {X.shape[1]}")
print(f"Attack fraction: {is_attack.mean():.2%}")
print(f"Distinct attack types: {len(set(y)) - 1}")
Sample output
Rows: 494,021, features: 41
Attack fraction: 80.31%
Distinct attack types: 22
Caution: This "10 Percent" Subset Is Not Realistic Traffic
Notice the real number above: 80.31 percent of this benchmark's rows are attacks. Genuine enterprise network traffic is nowhere near 80 percent malicious; the original KDD Cup 99 collection deliberately oversampled certain denial-of-service attacks when it was assembled, a known flaw this unit's Unit 6 companion, NSL-KDD, was built specifically to correct. Training or, worse, reporting results on the raw oversampled distribution without accounting for this produces numbers that look strong and mean very little.
resample_realistic_rate.py
import numpy as np
rng = np.random.default_rng(0)
normal_idx = np.where(is_attack == 0)[0]
attack_idx = np.where(is_attack == 1)[0]
# keep every normal row, but only 3,000 attack rows: a realistic ~3% rate
sampled_attacks = rng.choice(attack_idx, size=3000, replace=False)
keep = np.concatenate([normal_idx, sampled_attacks])
rng.shuffle(keep)
X_realistic = numeric_features.values[keep] # categorical columns dropped
y_realistic = is_attack[keep]
print(f"Rows: {len(y_realistic):,}, attack fraction: {y_realistic.mean():.2%}")
Sample output
Rows: 100,278, attack fraction: 2.99%
isolation_forest_kdd.py
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import IsolationForest
from sklearn.metrics import classification_report
Xs = StandardScaler().fit_transform(X_realistic)
iso = IsolationForest(
n_estimators=200, contamination=float(y_realistic.mean()),
random_state=0, n_jobs=-1
)
iso.fit(Xs)
predicted_attack = (iso.predict(Xs) == -1).astype(int)
print(classification_report(y_realistic, predicted_attack,
target_names=["normal", "attack"], digits=3))
Sample output
precision recall f1-score support
normal 0.978 0.978 0.978 97278
attack 0.280 0.280 0.280 3000
accuracy 0.957 100278
Key takeaway
Read that result honestly before moving on: 95.7 percent accuracy, which Unit 6 will teach you to distrust on sight, alongside only 28 percent precision and 28 percent recall on the attacks that actually matter. Isolation Forest, run out of the box on raw numeric KDD features with no feature engineering, catches barely more than a quarter of real attacks. This is not a failure of the algorithm; it is the single clearest argument in this entire course for Unit 5's feature engineering, since the same algorithm, given better features, performs substantially better, which Unit 5's hands-on exercises ask you to verify for yourself.
Tool in focus: A Second Real Dataset: AWID
The KDD Cup data captures wired network traffic. The Aegean WiFi Intrusion Dataset (AWID), built by researchers at the University of the Aegean from real IEEE 802.11 wireless traffic, is the standard benchmark specifically for wireless intrusion detection, covering attacks such as rogue access points, deauthentication floods, and WEP/WPA cracking attempts that a wired-traffic dataset like KDD or NSL-KDD cannot represent at all. The same pipeline built in this topic, clean, scale, reduce dimensionality, detect anomalies, applies directly; only the feature set changes.

