{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5850a630",
   "metadata": {},
   "source": [
    "# Project Delay Risk Baseline\n",
    "\n",
    "**AIMPACT peer-learning baseline**  \n",
    "**Dataset:** Illustrative synthetic work-package data  \n",
    "**Source:** https://zenodo.org/records/21929174  \n",
    "**Task:** Regression  \n",
    "**Status:** runnable demonstration with synthetic fallback, not a validated plant or project model.\n",
    "\n",
    "Install `numpy pandas scikit-learn openpyxl notebook` first. Set `DATA_FILE` to a local file to run against a compatible dataset where supported. Check source terms and permissions before use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5048285",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pathlib import Path\n",
    "from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier\n",
    "from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, classification_report, confusion_matrix\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.impute import SimpleImputer\n",
    "RANDOM_STATE = 42\n",
    "rng = np.random.default_rng(RANDOM_STATE)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c866a73",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Illustrative synthetic data only. The linked Zenodo record is a research lead,\n",
    "# not loaded by this notebook. Never interpret results as a real pilot finding.\n",
    "n=900\n",
    "df=pd.DataFrame({\n",
    " \"planned_days\":rng.integers(5,85,n),\n",
    " \"crew_size\":rng.integers(5,70,n),\n",
    " \"drawing_lag_days\":rng.integers(0,18,n),\n",
    " \"material_lag_days\":rng.integers(0,24,n),\n",
    " \"rain_days\":rng.integers(0,14,n),\n",
    " \"predecessor_delay_days\":rng.integers(0,25,n)\n",
    "})\n",
    "df[\"delay_days\"]=np.maximum(0,\n",
    "  .65*df[\"drawing_lag_days\"]+.8*df[\"material_lag_days\"]+\n",
    "  .45*df[\"rain_days\"]+.7*df[\"predecessor_delay_days\"]-\n",
    "  .05*df[\"crew_size\"]+rng.normal(0,3,n)).round(1)\n",
    "print(\"SYNTHETIC EXAMPLE — no real project observations\",df.shape)\n",
    "display(df.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "79624f24",
   "metadata": {},
   "outputs": [],
   "source": [
    "X=df.drop(columns=\"delay_days\");y=df[\"delay_days\"]\n",
    "# Random split is for this independent synthetic demonstration only.\n",
    "# For real projects, use chronological / project-held-out validation to avoid leakage.\n",
    "X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=.25,random_state=RANDOM_STATE)\n",
    "model=Pipeline([(\"impute\",SimpleImputer(strategy=\"median\")),(\"rf\",RandomForestRegressor(n_estimators=120,min_samples_leaf=3,random_state=RANDOM_STATE,n_jobs=-1))])\n",
    "model.fit(X_train,y_train)\n",
    "pred=model.predict(X_test)\n",
    "print(\"MAE (days):\",round(mean_absolute_error(y_test,pred),2))\n",
    "print(\"RMSE (days):\",round(np.sqrt(mean_squared_error(y_test,pred)),2))\n",
    "print(\"R²:\",round(r2_score(y_test,pred),3))\n",
    "print(\"Warning: the synthetic labels were constructed from these features; these metrics are not evidence of real-world forecasting accuracy.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a6029a6",
   "metadata": {},
   "source": [
    "## Peer review checklist\n",
    "\n",
    "- Check data provenance, license, missing values and representativeness.\n",
    "- Confirm whether target values would actually be known at prediction time.\n",
    "- Use chronological, site-held-out or project-held-out testing for real deployments.\n",
    "- Compare against a simple baseline and report uncertainty and failure cases.\n",
    "- Do not connect experimental models to plant controls or safety-critical decisions.\n",
    "- Document reviewer comments and proposed next experiments."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
