CSAI2026 labs: Lab-2..Lab-6 (Practical + Solution, data), Module-2..Module-6 notebooks and datasets

This commit is contained in:
mikrotik
2026-10-12 19:16:14 +07:00
commit 2fefa615cc
184 changed files with 1016761 additions and 0 deletions
@@ -0,0 +1,216 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2eb3034b",
"metadata": {},
"source": [
"# Module 3 — Lab 3: A Random Forest Security Pipeline\n",
"\n",
"**Topics:** Scikit-learn Pipeline, imputation, Random Forest, fit, predict\n",
"\n",
"> **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.\n"
]
},
{
"cell_type": "markdown",
"id": "7bf6c5fd",
"metadata": {},
"source": [
"## Learning objectives\n",
"\n",
"After completing this lab, you will be able to:\n",
"\n",
"- create one reusable preprocessing-and-model pipeline;\n",
"- train a Random Forest binary classifier;\n",
"- generate predictions for unseen data;\n",
"- explain why tree models do not require feature standardization.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c98b721f",
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"DATA_PATH = Path(\"data/cicids2017_binary_sample.csv\")\n",
"RANDOM_STATE = 42\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.pipeline import Pipeline\n",
"from sklearn.impute import SimpleImputer\n",
"from sklearn.ensemble import RandomForestClassifier\n"
]
},
{
"cell_type": "markdown",
"id": "3888c4bb",
"metadata": {},
"source": [
"## 1. Prepare the binary classification data\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4c28e44",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv(DATA_PATH)\n",
"df.columns = df.columns.str.strip()\n",
"df = df.drop_duplicates().replace([np.inf, -np.inf], np.nan)\n",
"\n",
"# TODO 1: create numeric X and binary y\n",
"X = None\n",
"y = None\n",
"\n",
"# TODO 2: create a stratified 80/20 split\n",
"X_train, X_test, y_train, y_test = None, None, None, None\n"
]
},
{
"cell_type": "markdown",
"id": "6aad53d0",
"metadata": {},
"source": [
"## 2. Build one pipeline\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6c00af0",
"metadata": {},
"outputs": [],
"source": [
"# TODO 3: create a Pipeline with:\n",
"# - SimpleImputer(strategy=\"median\")\n",
"# - RandomForestClassifier with n_estimators=100, max_depth=12,\n",
"# random_state=42, and n_jobs=-1\n",
"pipeline = None\n",
"\n",
"print(pipeline)\n"
]
},
{
"cell_type": "markdown",
"id": "c2111199",
"metadata": {},
"source": [
"## Why there is no `StandardScaler`\n",
"\n",
"Random Forest makes decisions by comparing feature values with thresholds. Scaling a column does not change the ordering of its values, so standardization is not required for this model family. The imputer remains inside the pipeline because the model needs finite values.\n"
]
},
{
"cell_type": "markdown",
"id": "16aa1030",
"metadata": {},
"source": [
"## 3. Train and predict\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59b48b8d",
"metadata": {},
"outputs": [],
"source": [
"# TODO 4: fit the complete pipeline on X_train and y_train\n",
"\n",
"# TODO 5: predict labels for X_test and store them in y_pred\n",
"y_pred = None\n",
"\n",
"print(\"Predictions:\", None)\n",
"print(\"Number of test samples:\", None)\n"
]
},
{
"cell_type": "markdown",
"id": "c0c83354",
"metadata": {},
"source": [
"## 4. Predict one flow\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e1910ac4",
"metadata": {},
"outputs": [],
"source": [
"one_flow = X_test.iloc[[0]]\n",
"\n",
"# TODO 6: predict one_flow and convert the result to int\n",
"one_prediction = None\n",
"\n",
"print(\"Prediction:\", one_prediction)\n",
"print(\"Meaning:\", \"ATTACK\" if one_prediction == 1 else \"BENIGN\")\n"
]
},
{
"cell_type": "markdown",
"id": "a7cdf396",
"metadata": {},
"source": [
"## Self-check\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "926ba101",
"metadata": {},
"outputs": [],
"source": [
"assert list(pipeline.named_steps) == [\"imputer\", \"model\"]\n",
"assert pipeline.named_steps[\"model\"].n_estimators == 100\n",
"assert len(y_pred) == len(y_test)\n",
"assert set(np.unique(y_pred)).issubset({0, 1})\n",
"assert one_prediction in {0, 1}\n",
"print(\"✓ Lab 3 completed\")\n"
]
},
{
"cell_type": "markdown",
"id": "7beedd77",
"metadata": {},
"source": [
"## Reflection questions\n",
"\n",
"1. What problem does the imputer solve inside the pipeline?\n",
"2. Why is a pipeline safer than manually transforming train and test data in separate cells?\n",
"3. What does `random_state=42` contribute to the experiment?\n"
]
}
],
"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
}