Update README.md
Browse files
README.md
CHANGED
|
@@ -26,13 +26,11 @@ tags:
|
|
| 26 |
|
| 27 |
---
|
| 28 |
|
| 29 |
-
##
|
| 30 |
|
| 31 |
-
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
I found this dataset surprisingly rich. The 4.1 million evidence rows compress into meaningful incident-level patterns that a classifier can actually learn. The main challenge was figuring out which features encode real threat signal versus which ones just memorize organizational patterns β and that distinction turned out to matter a lot for building a model that generalizes.
|
| 36 |
|
| 37 |
---
|
| 38 |
|
|
@@ -41,9 +39,10 @@ I found this dataset surprisingly rich. The 4.1 million evidence rows compress i
|
|
| 41 |
- **Source:** (https://archive.ics.uci.edu/dataset/498/incident+management+process+enriched+event+log)
|
| 42 |
- **Original size:** 4.1M evidence-level rows, 45 features
|
| 43 |
- **After cleaning:** 100K sampled rows, 35 features (10 dropped for >60% missing)
|
| 44 |
-
- **
|
| 45 |
-
-
|
| 46 |
-
-
|
|
|
|
| 47 |
|
| 48 |
## Feature Engineering
|
| 49 |
|
|
@@ -67,22 +66,18 @@ I also added clustering-derived features:
|
|
| 67 |
---
|
| 68 |
|
| 69 |
## Data Cleaning
|
|
|
|
| 70 |
|
| 71 |
### Missing Values
|
| 72 |
|
| 73 |
-
Ten columns had more than 60% missing values and were dropped immediately.
|
| 74 |
-
|
| 75 |
-
Dropped: `ActionGrouped`, `ActionGranular`, `ResourceType`, `ThreatFamily`, `AntispamDirection`, `Roles`, `EmailClusterId`, `SuspicionLevel`, `LastVerdict`, `MitreTechniques`
|
| 76 |
-
|
| 77 |
-
I also removed `OrgId` after discovering it caused data leakage β early models achieved RΒ² = 0.88 by memorizing which organizations generate more incidents rather than learning actual threat patterns. Dropping it brought RΒ² to 0.47, which is a real score on real signal.
|
| 78 |
|
| 79 |
### Duplicates
|
| 80 |
|
| 81 |
No duplicate rows found in the 100K sample.
|
| 82 |
|
| 83 |
### Outliers
|
| 84 |
-
|
| 85 |
-
I kept the outliers in `evidence_count`. The distribution is bimodal β incidents either have very few evidence items (5-10) or very many (100-200). This initially looked like outliers, but it's a real operational pattern: simple false alarms generate minimal evidence while real attacks generate cascading evidence chains. Removing them would have destroyed the main signal.
|
| 86 |
|
| 87 |
---
|
| 88 |
|
|
@@ -92,25 +87,28 @@ I kept the outliers in `evidence_count`. The distribution is bimodal β inciden
|
|
| 92 |
|
| 93 |

|
| 94 |
|
| 95 |
-
|
|
|
|
|
|
|
| 96 |
|
| 97 |
### Entity Type Patterns
|
| 98 |
|
| 99 |

|
| 100 |
|
| 101 |
-
|
|
|
|
|
|
|
| 102 |
|
| 103 |
### Threat Category Profiles
|
| 104 |
|
| 105 |

|
| 106 |
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
| 110 |
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
Real attacks leave a much larger forensic trail. TruePositive incidents average **117 evidence items** compared to 25 for FalsePositive β a **4.7Γ difference**. This confirmed that deriving `evidence_count` as a regression target was the right approach.
|
| 114 |
|
| 115 |
---
|
| 116 |
|
|
@@ -150,23 +148,39 @@ Real attacks leave a much larger forensic trail. TruePositive incidents average
|
|
| 150 |
|
| 151 |

|
| 152 |
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
### Regression Model Comparison
|
| 156 |
|
| 157 |

|
| 158 |
|
| 159 |

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |

|
| 162 |
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
### Classification Setup
|
| 166 |
|
| 167 |

|
| 168 |
|
| 169 |
-
|
|
|
|
|
|
|
| 170 |
|
| 171 |
### Classification Results
|
| 172 |
|
|
|
|
| 26 |
|
| 27 |
---
|
| 28 |
|
| 29 |
+
## The Problem
|
| 30 |
|
| 31 |
+
SOC analysts waste **40-60% of their time** reviewing false positives. Out of 1000 daily alerts, ~600 are noise. Real threats get buried.
|
| 32 |
|
| 33 |
+
**Goal:** Build ML models to automate triage β predict if an alert is a real attack (TP), harmless activity (BP), or false alarm (FP).
|
|
|
|
|
|
|
| 34 |
|
| 35 |
---
|
| 36 |
|
|
|
|
| 39 |
- **Source:** (https://archive.ics.uci.edu/dataset/498/incident+management+process+enriched+event+log)
|
| 40 |
- **Original size:** 4.1M evidence-level rows, 45 features
|
| 41 |
- **After cleaning:** 100K sampled rows, 35 features (10 dropped for >60% missing)
|
| 42 |
+
- **Targets:**
|
| 43 |
+
- Regression: `evidence_count` (attack complexity)
|
| 44 |
+
- Classification: `IncidentGrade` (TP/BP/FP)
|
| 45 |
+
- **Class split:** 42% BP / 36% TP / 22% FP
|
| 46 |
|
| 47 |
## Feature Engineering
|
| 48 |
|
|
|
|
| 66 |
---
|
| 67 |
|
| 68 |
## Data Cleaning
|
| 69 |
+
Removed `OrgId` β caused data leakage (RΒ² 0.88 β 0.47)
|
| 70 |
|
| 71 |
### Missing Values
|
| 72 |
|
| 73 |
+
Ten columns had more than 60% missing values and were dropped immediately. to prevent capturing more noise than signal.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
### Duplicates
|
| 76 |
|
| 77 |
No duplicate rows found in the 100K sample.
|
| 78 |
|
| 79 |
### Outliers
|
| 80 |
+
Kept outliers in `evidence_count` β bimodal distribution is real signal
|
|
|
|
| 81 |
|
| 82 |
---
|
| 83 |
|
|
|
|
| 87 |
|
| 88 |

|
| 89 |
|
| 90 |
+
**Shows:** Class distribution of incident grades
|
| 91 |
+
**Finding:** 42% BenignPositive, 36% TruePositive, 22% FalsePositive
|
| 92 |
+
**Why it matters:** Moderate imbalance β used macro F1 metric (equal weight to all classes)
|
| 93 |
|
| 94 |
### Entity Type Patterns
|
| 95 |
|
| 96 |

|
| 97 |
|
| 98 |
+
**Shows:** Which entity types (IP, User, Machine, etc.) appear in each grade
|
| 99 |
+
**Finding:** IP entities dominate TruePositive incidents (~11K count)
|
| 100 |
+
**Why it matters:** IP-based alerts deserve higher priority than User-based alerts
|
| 101 |
|
| 102 |
### Threat Category Profiles
|
| 103 |
|
| 104 |

|
| 105 |
|
| 106 |
+
**Shows:** Threat categories (InitialAccess, Malware, Exfiltration, etc.) by grade
|
| 107 |
+
**Finding:**
|
| 108 |
+
- InitialAccess: 54% TruePositive (high threat)
|
| 109 |
+
- Malware: 74% BenignPositive (mostly noise)
|
| 110 |
|
| 111 |
+
**Why it matters:** Not all alert categories are equal β category alone is a strong predictor
|
|
|
|
|
|
|
| 112 |
|
| 113 |
---
|
| 114 |
|
|
|
|
| 148 |
|
| 149 |

|
| 150 |
|
| 151 |
+
**Shows:** LinearRegression performance β residual plot
|
| 152 |
+
**Finding:** Two distinct peaks β bimodal distribution not captured
|
| 153 |
+
**Result:** RMSE = 96.1, RΒ² = 0.023 (failed)
|
| 154 |
+
**Why it matters:** Linear models can't handle this data β need tree models
|
| 155 |
|
| 156 |
### Regression Model Comparison
|
| 157 |
|
| 158 |

|
| 159 |
|
| 160 |

|
| 161 |
+
**Shows:** RandomForest feature importance for regression
|
| 162 |
+
**Finding:**
|
| 163 |
+
- AlertTitle: **61% importance**
|
| 164 |
+
- cluster_distance: 30%
|
| 165 |
+
- Category: 15%
|
| 166 |
+
|
| 167 |
+
**Why it matters:** Which detector fired is by far the strongest predictor
|
| 168 |
+
|
| 169 |
|
| 170 |

|
| 171 |
|
| 172 |
+
**Shows:** RandomForest actual vs predicted scatter plot
|
| 173 |
+
**Finding:** Good fit along diagonal β captures bimodal pattern
|
| 174 |
+
**Why it matters:** Tree splits naturally handle 25-item vs 117-item peaks
|
| 175 |
+
|
| 176 |
|
| 177 |
### Classification Setup
|
| 178 |
|
| 179 |

|
| 180 |
|
| 181 |
+
**Shows:** Target class distribution for classification task
|
| 182 |
+
**Finding:** Same 42/36/22 split as before
|
| 183 |
+
**Why it matters:** Confirms macro F1 is right metric (not accuracy)
|
| 184 |
|
| 185 |
### Classification Results
|
| 186 |
|