Files
labs/Lab-3/Lab-3-Solution/01_Security_Features_Labels_Solution.ipynb
T

228 lines
5.3 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "ce4d0249",
"metadata": {},
"source": [
"# Module 3 — Lab 1: Security Features and Binary Labels\n",
"\n",
" \n",
"**Topics:** samples, features, labels, class distribution\n",
"\n",
"> **Solution version:** This notebook contains the complete solution. Run the cells in order and compare the results with your Lab notebook.\n"
]
},
{
"cell_type": "markdown",
"id": "c70b2987",
"metadata": {},
"source": [
"## Learning objectives\n",
"\n",
"After completing this lab, you will be able to:\n",
"\n",
"- identify samples, features, and labels in a security dataset;\n",
"- inspect the schema and data types of a network-flow table;\n",
"- convert multiple attack names into one binary target;\n",
"- explain why class distribution matters before model training.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dd82f5a2",
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"DATA_PATH = Path(\"data/synthetic_security_flows.csv\")\n",
"RANDOM_STATE = 42\n"
]
},
{
"cell_type": "markdown",
"id": "6345844b",
"metadata": {},
"source": [
"## 1. Load and inspect the flow table\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b8d885cb",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv(DATA_PATH)\n",
"\n",
"print(\"Shape:\", df.shape)\n",
"df.head()\n"
]
},
{
"cell_type": "markdown",
"id": "19535e33",
"metadata": {},
"source": [
"## 2. Identify the label and numeric features\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f87f05f8",
"metadata": {},
"outputs": [],
"source": [
"y_text = df[\"Label\"].astype(str).str.strip()\n",
"X = df.drop(columns=\"Label\").select_dtypes(include=\"number\")\n",
"\n",
"print(\"Feature matrix shape:\", X.shape)\n",
"print(\"Original labels:\")\n",
"print(y_text.value_counts())\n"
]
},
{
"cell_type": "markdown",
"id": "59f3f674",
"metadata": {},
"source": [
"## 3. Create a binary security target\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4d0c24e",
"metadata": {},
"outputs": [],
"source": [
"normalized_labels = y_text.str.strip().str.upper()\n",
"y_binary = normalized_labels.ne(\"BENIGN\").astype(int)\n",
"class_counts = y_binary.value_counts().sort_index()\n",
"\n",
"print(class_counts.rename(index={0: \"BENIGN\", 1: \"ATTACK\"}))\n",
"print(\"Attack rate:\", round(y_binary.mean(), 3))\n"
]
},
{
"cell_type": "markdown",
"id": "28d40643",
"metadata": {},
"source": [
"## 4. Connect rows to feature vectors\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0506346",
"metadata": {},
"outputs": [],
"source": [
"sample_index = 0\n",
"sample_features = X.iloc[sample_index]\n",
"sample_target = int(y_binary.iloc[sample_index])\n",
"\n",
"print(\"Selected feature vector:\")\n",
"print(sample_features)\n",
"print(\"Binary target:\", sample_target)\n"
]
},
{
"cell_type": "markdown",
"id": "3d4855d6",
"metadata": {},
"source": [
"## Self-check\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4159047f",
"metadata": {},
"outputs": [],
"source": [
"assert isinstance(df, pd.DataFrame)\n",
"assert \"Label\" not in X.columns\n",
"assert set(y_binary.unique()) == {0, 1}\n",
"assert len(X) == len(y_binary)\n",
"assert class_counts.loc[0] > class_counts.loc[1]\n",
"assert len(sample_features) == X.shape[1]\n",
"print(\"✓ Lab 1 completed\")\n"
]
},
{
"cell_type": "markdown",
"id": "a66bcc4e",
"metadata": {},
"source": [
"## Reflection questions\n",
"\n",
"1. Why is each row considered one sample while each column is considered one feature?\n",
"2. What information is lost when several attack families are mapped to one `ATTACK` class?\n",
"3. Why could high accuracy be misleading when `BENIGN` is the majority class?\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5b4575cc-2166-474b-bd0e-b49d94d1cfc2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d03b205-5584-41c8-baaf-272b32bdf0b2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ecfa6b2-cb34-45cc-98b4-5417f48f9f82",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "40ddd666-9f13-46bd-8a58-45bef952bfa2",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}