CSAI2026 labs: Lab-2..Lab-6 (Practical + Solution, data), Module-2..Module-6 notebooks and datasets
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-001",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Module 6 — Lab 1: Auditing NSL-KDD Flow Records\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"**Topics:** network flows, fixed split, labels, attack groups, leakage\n",
|
||||
"\n",
|
||||
"> **Lab version:** Complete every `TODO`, run the cells in order, and use the self-check before opening the Solution."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-002",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Learning objectives\n",
|
||||
"\n",
|
||||
"After completing this lab, you will be able to:\n",
|
||||
"\n",
|
||||
"- distinguish network-flow features from targets and audit fields;\n",
|
||||
"- preserve the predefined NSL-KDD train/test split;\n",
|
||||
"- describe binary labels and the DoS, Probe, R2L, and U2R groups;\n",
|
||||
"- identify attack labels that appear only in the test set;\n",
|
||||
"- document imbalance, duplicates, and benchmark limitations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cell-003",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pathlib import Path\n",
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"TRAIN_PATH = Path(\"data/nsl_kdd_train.csv\")\n",
|
||||
"TEST_PATH = Path(\"data/nsl_kdd_test.csv\")\n",
|
||||
"\n",
|
||||
"missing_files = [str(path) for path in (TRAIN_PATH, TEST_PATH) if not path.exists()]\n",
|
||||
"if missing_files:\n",
|
||||
" raise FileNotFoundError(\n",
|
||||
" \"Missing prepared NSL-KDD files: \" + \", \".join(missing_files) +\n",
|
||||
" \". Follow data/README.md and run: python data/prepare_dataset.py\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"TARGET_COLUMNS = [\"attack_label\", \"attack_group\", \"binary_label\", \"difficulty\"]\n",
|
||||
"CATEGORICAL_FEATURES = [\"protocol_type\", \"service\", \"flag\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-004",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Load and validate the fixed split"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cell-005",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# TODO 1: load the prepared train and test tables.\n",
|
||||
"train_df = None\n",
|
||||
"test_df = None\n",
|
||||
"\n",
|
||||
"# TODO 2: create feature_cols and numeric_features without target/audit columns.\n",
|
||||
"feature_cols = None\n",
|
||||
"numeric_features = None\n",
|
||||
"\n",
|
||||
"print(\"Train shape:\", None)\n",
|
||||
"print(\"Test shape:\", None)\n",
|
||||
"print(\"Model features:\", None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-006",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Audit classes, groups, and unseen attack labels"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cell-007",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# TODO 3: calculate binary-label and attack-group counts for both splits.\n",
|
||||
"train_binary = None\n",
|
||||
"test_binary = None\n",
|
||||
"train_groups = None\n",
|
||||
"test_groups = None\n",
|
||||
"\n",
|
||||
"# TODO 4: find attack labels present in test but absent from training.\n",
|
||||
"train_attack_labels = None\n",
|
||||
"test_attack_labels = None\n",
|
||||
"unseen_test_attacks = None\n",
|
||||
"\n",
|
||||
"display(pd.DataFrame({\"train\": train_binary, \"test\": test_binary}))\n",
|
||||
"print(\"Attack labels seen only in test:\", unseen_test_attacks)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-008",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 3. Audit quality and leakage risks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cell-009",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# TODO 5: build a per-feature table of missing counts and unique counts.\n",
|
||||
"quality_summary = None\n",
|
||||
"\n",
|
||||
"# TODO 6: count exact duplicate rows separately in train and test.\n",
|
||||
"duplicate_counts = None\n",
|
||||
"\n",
|
||||
"# TODO 7: list target/audit columns that must never enter the model.\n",
|
||||
"forbidden_model_columns = None\n",
|
||||
"print(duplicate_counts)\n",
|
||||
"print(\"Columns excluded from modeling:\", forbidden_model_columns)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-010",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Benchmark note\n",
|
||||
"\n",
|
||||
"NSL-KDD is useful for learning a reproducible IDS workflow. Its fixed test set includes attacks that are absent from training, but it remains a legacy benchmark and does not represent modern production traffic."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-011",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Self-check"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cell-012",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert len(feature_cols) == 41\n",
|
||||
"assert set(CATEGORICAL_FEATURES).issubset(feature_cols)\n",
|
||||
"assert set(train_df[\"binary_label\"].unique()) == {0, 1}\n",
|
||||
"assert set(test_df[\"attack_group\"].unique()).issubset({\"Normal\", \"DoS\", \"Probe\", \"R2L\", \"U2R\"})\n",
|
||||
"assert len(unseen_test_attacks) > 0\n",
|
||||
"assert set(feature_cols).isdisjoint(TARGET_COLUMNS)\n",
|
||||
"assert quality_summary.shape[0] == 41\n",
|
||||
"print(\"✓ Lab 1 completed\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cell-013",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Reflection questions\n",
|
||||
"\n",
|
||||
"1. Why should the predefined train/test split be preserved?\n",
|
||||
"2. Why must `difficulty` and derived label columns be excluded from X?\n",
|
||||
"3. Why can binary accuracy hide failure on rare attack groups?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
Reference in New Issue
Block a user