โ๏ธ 10-06: Building & Training the IDS Model¶
๐ From Theory to Practice¶
We've now covered every concept needed to build a real classifier:
- Why ML helps with intrusion detection (10-03: Intro to ML for Security)
- How to prepare a dataset like NSL-KDD (encoding, scaling) (10-04: Feature Engineering (NSL-KDD))
- How an SVM makes its classification decision (10-05: SVMs for Classification)
This lesson walks through the full, generic workflow for building and training an IDS classifier end-to-end, from a raw CSV file to a trained model making predictions.
๐งฑ Step 1: Import the Necessary Libraries¶
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix, classification_report, f1_score, accuracy_score
| Library | Role |
|---|---|
pandas |
Loading and manipulating the tabular dataset |
numpy |
Numeric array operations under the hood |
matplotlib / seaborn |
Visualizing data and results |
sklearn.preprocessing |
Encoding categorical labels, scaling numeric features |
sklearn.model_selection |
Splitting data into training and test sets |
sklearn.svm |
The SVM classifier itself (SVC = Support Vector Classifier) |
sklearn.metrics |
Evaluating how good the trained model is |
๐ Step 2: Load the Dataset¶
This loads a CSV file (structured the way NSL-KDD is: one row per connection, one column per feature, plus a label column) into a pandas DataFrame โ a table-like structure that's easy to filter, transform, and feed into scikit-learn.
๐งน Step 3: Clean the Data and Separate Features from the Label¶
# Drop rows with missing values
dataset = dataset.dropna()
# Separate independent variables (features) from the dependent variable (label)
X = dataset.drop("label", axis=1)
y = dataset["label"]
# Drop columns that add no useful signal
X = X.drop(["num_outbound_cmds", "is_host_login"], axis=1)
Xholds every feature the model will learn from (duration, protocol type, byte counts, etc.)yholds only the answer we want the model to predict:normalorattack- Irrelevant or constant-valued columns are dropped so they don't add noise
๐ค Step 4: Encode Categorical Data¶
# Encode the label into two numeric classes: 0 = normal, 1 = attack
y = LabelEncoder().fit_transform(y)
# One-hot encode categorical feature columns (protocol_type, service, flag, etc.)
X = pd.concat(
[pd.get_dummies(X.select_dtypes(include="object")),
X.select_dtypes(exclude="object")],
axis=1
)
As covered in 10-04: Feature Engineering (NSL-KDD), the SVM can only work with numbers, so every text-based column has to become numeric before training.
โ๏ธ Step 5: Split Into Training and Test Sets¶
test_size=0.3means 70% of the data trains the model, and 30% is held back purely for testing โ a common, standard split for datasets of this size.random_state=42fixes the random seed used to shuffle and split the data, so that re-running the code produces the exact same split every time โ this makes results reproducible and lets you fairly compare different models or settings later.
๐ก Why hold back a test set at all? If you trained and tested on the same data, the model could simply memorize the answers instead of learning generalizable patterns. Testing on unseen data is the only way to know if the model will work on real, future traffic.
๐ Step 6: Scale the Features¶
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train) # learn scaling from training data
X_test_scaled = scaler.transform(X_test) # apply the same scaling to test data
As explained in 10-04: Feature Engineering (NSL-KDD), SVMs are sensitive to the scale of input features. StandardScaler transforms every numeric feature so it has mean 0 and standard deviation 1, putting features like duration and src_bytes on comparable footing.
๐ก Notice fit_transform() is used on the training data (learns the mean/std and applies it), while only transform() is used on the test data (applies the already-learned scaling โ no peeking at test data statistics).
๐ง Step 7: Train the SVM Model¶
SVC()creates a Support Vector Classifier using scikit-learn's default settings (an RBF kernel, as discussed in 10-05: SVMs for Classification).fit(X_train_scaled, y_train)is where the actual learning happens: the model looks at every training example's features and its true label, and works out the maximum-margin hyperplane that best separatesnormalfromattack
๐ฎ Step 8: Predict on the Test Set¶
This runs the trained model on the held-out test features (X_test_scaled), producing a predicted label (0 or 1) for each test connection. Crucially, the model never saw these rows โ or their true labels โ during training.
y_pred (the model's guesses) can now be compared against y_test (the actual, correct answers) to see how well the model performs โ which is exactly the subject of the next lesson, 10-07: Evaluating Detection Models.
๐งพ Full Workflow at a Glance¶
import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 1. Load
dataset = pd.read_csv("network_traffic.csv").dropna()
# 2. Split features/label
X = dataset.drop("label", axis=1)
y = dataset["label"]
X = X.drop(["num_outbound_cmds", "is_host_login"], axis=1)
# 3. Encode
y = LabelEncoder().fit_transform(y)
X = pd.concat([pd.get_dummies(X.select_dtypes(include="object")),
X.select_dtypes(exclude="object")], axis=1)
# 4. Train/test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 5. Scale
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 6. Train
svc = SVC(random_state=42)
svc.fit(X_train_scaled, y_train)
# 7. Predict
y_pred = svc.predict(X_test_scaled)
๐ Key Takeaways¶
- Building an IDS classifier follows a consistent pipeline: load โ clean โ encode โ split โ scale โ train โ predict.
- A 70/30 train/test split with a fixed
random_stateis a standard, reproducible way to hold back unseen data for fair evaluation. - Always
fit_transform()the scaler on training data only, thentransform()the test data with those same learned parameters. SVC()from scikit-learn implements the Support Vector Machine classifier discussed conceptually in 10-05: SVMs for Classification..fit()trains the model on labeled data;.predict()produces guesses on new, unlabeled data.- The model's predictions (
y_pred) are only useful once compared against the true test labels (y_test) โ covered next in 10-07: Evaluating Detection Models.