Views
No views yet
| Class | Precision | Recall | F1 |
|---|---|---|---|
| Normal | 0.98 | 1.00 | 0.99 |
| DoS | 1.00 | 0.85 | 0.92 |
| PortScan | 0.95 | 1.00 | 0.97 |
| Brute Force | 0.99 | 0.99 | 0.99 |
| Web Attack | 0.86 | 0.91 | 0.88 |
| Macro F1 | 0.9518 |
| File | Description |
|---|---|
tier1_lgbm_calibrated.pkl | Calibrated LightGBM (isotonic, natural-dist cal set) |
scaler.pkl | StandardScaler fitted on training data only |
feature_selector.pkl | RF-based SelectFromModel (24 of 71 features kept) |
selected_features.pkl | List of 24 selected feature names |
feature_cols.pkl | Full list of 71 input features (pre-selection) |
label_encoder.pkl | LabelEncoder: Brute Force=0, DoS=1, Normal=2, PortScan=3, Web Attack=4 |
1import joblib, numpy as np
2
3le = joblib.load('label_encoder.pkl')
4scaler = joblib.load('scaler.pkl')
5selector = joblib.load('feature_selector.pkl')
6model = joblib.load('tier1_lgbm_calibrated.pkl')
7
8# flows: DataFrame with columns matching feature_cols (71 CICFlowMeter features)
9X = scaler.transform(flows.values.astype('float32'))
10X = selector.transform(X)
11preds = le.inverse_transform(model.predict(X))
12probas = model.predict_proba(X) # calibrated — P(Normal)~0.83 for benign traffic
13Key design decisions
14- **Temporal split**: per-class 80/20 chronological cut per daily file
15- **SMOTE**: Web Attack 1.5k→5k, Brute Force 7k→15k before undersampling
16- **Early stopping**: balanced resampled eval set (not natural-dist) so all 5 classes
17 contribute equally to the stopping signal
18- **Calibration**: `FrozenEstimator` + isotonic on natural-distribution val set (83% Normal)