{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "concise-titanic-intro",
      "metadata": {},
      "source": "# Aner: Titanic survival classifier, step by step\n\nUse a current native Aner executable that includes the bundled Titanic and Pima Diabetes loaders, and the compatible Aner VS Code extension supplied for that executable. An older binary does not gain new datasets by opening this file. Open the project folder and this `.anernb` file in **Aner Notebook**. If needed, set **Aner › Notebook: Executable** (`aner.notebook.executable`) to the full executable path. If asked for a kernel, choose **`Aner — notebook`**.\n\nRun code cells from top to bottom, or choose **Run All**. This notebook saves **Shared variables** and **Dev** mode: later cells reuse the same native dataset, split, network, fitted model, and results. If you change data, splitting, topology, or training settings, choose **Aner: Restart Notebook Session**, then **Run All** for a fresh experiment. Saving the notebook preserves source and outputs, not live variables or a model checkpoint.\n\nAfter a cell completes, choose **Inspector** (or the cell's **Dev · Inspector** action) to inspect typed variables and recorded loss. After the training cell, use **Aner: Open Development Training Report** for captured computation topology and available gradients. To include bounded raw tensor values in inspection, enable `aner.notebook.developmentValues` before rerunning. These are completed cell observations; edits can make them stale, and a later cell may retain the training report as historical. The preprocessing cell also prints every learned center and scale explicitly.\n\nSource: Harrell Jr., F. E., and Cason, T., Vanderbilt `titanic3`, courtesy of the Vanderbilt University Department of Biostatistics. The bundled teaching representation preserves **all 1,309 passengers** and uses four numeric predictors: `pclass`, `sex` (`female = 0`, `male = 1`), `sibsp`, and `parch`. The two survival classes are `not_survived = 0` and `survived = 1`. This is the Vanderbilt data, rather than the Kaggle training file variant. Age and fare are omitted because of missing values; outcome revealing boat/body fields are excluded. No rows are dropped or values imputed during loading.\n\nSee [Vanderbilt data and permission](https://hbiostat.org/data/) and the [original source notes](https://hbiostat.org/data/repo/titanic.html). Exact transformation and retained attribution are documented in `datasets/titanic/README.md` in the Aner project.\n\n## 1. Load the dataset\n\nLoad the bundled numeric teaching representation. No CSV preparation or network download is needed. The loader does not fit preprocessing.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-load",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "import aner.dataset\n",
        "import aner.nn\n",
        "import aner.ml\n",
        "\n",
        "let passengers = dataset.load(\"titanic\")\n",
        "print(\"Loaded rows, predictors, classes\")\n",
        "print(dataset.rows(passengers))\n",
        "print(dataset.cols(passengers))\n",
        "print(dataset.classes(passengers))\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-split-note",
      "metadata": {},
      "source": "## 2. Split before fitting\n\nCreate a seeded, stratified 80/20 **row split before fitting anything**. The test partition is reserved for the final evaluation. Related passengers may span both partitions because this variant provides no family group keys; use an explicit group partition if that matters to your experiment.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-split",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "let split = passengers.split(test: 0.2, seed: 2026)\n",
        "let training = split.train()\n",
        "let testing = split.test()\n",
        "print(\"Training rows\")\n",
        "print(training.rows())\n",
        "print(\"Held-out test rows\")\n",
        "print(testing.rows())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-topology-note",
      "metadata": {},
      "source": "## 3. Declare the classifier and preprocessing\n\n4 inputs → 8 dense units → tanh → two raw class logits. Seed `42` fixes initialization, independently of split seed `2026`. The plan uses cross entropy, Adam, and CPU Float64 with the preserve policy. `standardize: true` declares preprocessing; it learns no statistics until `fit` receives the training partition.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-topology",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "let network = nn.sequential(seed: 42)\n",
        "    .dense(inputs: 4, outputs: 8, initialization: \"xavier\")\n",
        "    .tanh()\n",
        "    .dense(inputs: 8, outputs: 2, initialization: \"xavier\")\n",
        "let pipeline = ml.classifier(network, standardize: true,\n",
        "    loss: \"cross_entropy\", optimizer: \"adam\")\n",
        "    .on(device: \"cpu\", precision: \"Float64\", policy: \"preserve\")\n",
        "print(network.summary())\n",
        "print(pipeline.summary())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-fit-note",
      "metadata": {},
      "source": "## 4. Fit on training rows only\n\nFit column centers, population scales, and model parameters from `training` only. Keep the fixed teaching configuration of **400 epochs** at learning rate **0.01**; held out results do not choose these settings. `fit` returns a fitted snapshot containing the learned scaler and trained classifier. After this cell completes, Inspector shows the fitted model and recorded training loss; the Development Training Report shows captured topology and available gradients.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-fit",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "let fitted = pipeline.fit(training, epochs: 400, rate: 0.01)\n",
        "print(\"Final training loss\")\n",
        "print(fitted.training_loss())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-preprocessing-note",
      "metadata": {},
      "source": "## 5. Inspect the preprocessing fitted on training data\n\n`training_center` and `training_scale` are detached tensors with one value per input feature, in the source feature order above. The printed values are the statistics actually learned from training rows. Keep these variables visible in Inspector; enable `aner.notebook.developmentValues` and rerun if you want bounded raw tensor previews. Held out rows never contribute to these centers or scales.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-preprocessing",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "let training_center = ml.center(fitted)\n",
        "let training_scale = ml.scale(fitted)\n",
        "print(\"pclass: training center, population scale\")\n",
        "print(nn.value(training_center, 0, 0))\n",
        "print(nn.value(training_scale, 0, 0))\n",
        "print(\"sex: training center, population scale\")\n",
        "print(nn.value(training_center, 0, 1))\n",
        "print(nn.value(training_scale, 0, 1))\n",
        "print(\"sibsp: training center, population scale\")\n",
        "print(nn.value(training_center, 0, 2))\n",
        "print(nn.value(training_scale, 0, 2))\n",
        "print(\"parch: training center, population scale\")\n",
        "print(nn.value(training_center, 0, 3))\n",
        "print(nn.value(training_scale, 0, 3))\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-evaluation-note",
      "metadata": {},
      "source": "## 6. Evaluate held out rows\n\nEvaluate once on `testing`, reusing the fitted training scaler without refitting preprocessing or updating model parameters. The summary includes held out results and workflow provenance; the retained `evaluation` variable is available in Inspector after this cell completes. This is a demonstration, not an accuracy target.\n"
    },
    {
      "cell_type": "code",
      "id": "concise-titanic-evaluation",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "let evaluation = fitted.evaluate(testing)\n",
        "print(evaluation.summary())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "concise-titanic-rerun-note",
      "metadata": {},
      "source": "## Repeat a clean experiment\n\nTo edit and rerun the workflow, choose **Aner: Restart Notebook Session** and **Run All**. Then inspect the new completed cell values and training report. The matching plain source example is `examples/neural_titanic_concise.aner`; both versions use the same dataset, split seed, initialization, preprocessing, loss, optimizer, precision, and fixed training settings. This downloaded notebook contains no saved results.\n"
    }
  ],
  "metadata": {
    "kernelspec": {
      "name": "aner",
      "display_name": "Aner",
      "language": "aner"
    },
    "language_info": {
      "name": "aner",
      "file_extension": ".aner"
    },
    "aner": {
      "execution_mode": "persistent-session",
      "runtime_mode": "development"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
