Files
labs/Lab-3/Lab-3-Practical/01_Security_Features_Labels_Lab.ipynb

4.9 KiB

Module 3 — Lab 1: Security Features and Binary Labels

Topics: samples, features, labels, class distribution

Instructions: Run the cells in order. Complete every TODO, then run the Self-check cell. Do not open the Solution notebook before attempting the tasks yourself.

Learning objectives

After completing this lab, you will be able to:

  • identify samples, features, and labels in a security dataset;
  • inspect the schema and data types of a network-flow table;
  • convert multiple attack names into one binary target;
  • explain why class distribution matters before model training.
In [ ]:
from pathlib import Path
import numpy as np
import pandas as pd

DATA_PATH = Path("data/synthetic_security_flows.csv")
RANDOM_STATE = 42

1. Load and inspect the flow table

In [ ]:
# TODO 1: load DATA_PATH into a DataFrame named df
df = None

# TODO 2: display the first five rows
print("Shape:", None)
df

2. Identify the label and numeric features

In [ ]:
# TODO 3: store the original label column in y_text
y_text = None

# TODO 4: create X using only numeric columns and exclude Label
X = None

print("Feature matrix shape:", None)
print("Original labels:")
print(None)

3. Create a binary security target

In [ ]:
# BENIGN becomes 0. Every attack family becomes 1.
# TODO 5: normalize labels with strip() and upper(), then create y_binary
y_binary = None

# TODO 6: calculate class_counts sorted by class index
class_counts = None

print(class_counts)
print("Attack rate:", None)

4. Connect rows to feature vectors

In [ ]:
sample_index = 0

# TODO 7: select one row from X as sample_features and its target as sample_target
sample_features = None
sample_target = None

print("Selected feature vector:")
print(sample_features)
print("Binary target:", sample_target)

Self-check

In [ ]:
assert isinstance(df, pd.DataFrame)
assert "Label" not in X.columns
assert set(y_binary.unique()) == {0, 1}
assert len(X) == len(y_binary)
assert class_counts.loc[0] > class_counts.loc[1]
assert len(sample_features) == X.shape[1]
print("✓ Lab 1 completed")

Reflection questions

  1. Why is each row considered one sample while each column is considered one feature?
  2. What information is lost when several attack families are mapped to one ATTACK class?
  3. Why could high accuracy be misleading when BENIGN is the majority class?