{
  "cells": [
    {
      "attachments": {
        "logo.png": {
          "image/png": "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"
        }
      },
      "cell_type": "markdown",
      "id": "4ed0a233",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "![NVIDIA Structured Data Models logo](attachment:logo.png)\n\n# Kumo Tabular on Breast Mass Classification (Kaggle)\n\n**Kumo Tabular** is a structured-data foundation model for predictive AI on a single table. It uses labelled context rows to predict outcomes for new rows without training a task-specific model.\n\nThis notebook runs a **binary classification** task with the Mammographic Mass dataset from **Kaggle**, using `structured-data-models-client` to call a deployed **Kumo Tabular NVIDIA NIM**. It demonstrates both a direct `Request` and a Predictive Query Language (PQL) workflow.\n\n**A GPU is not required on the notebook machine.** The model runs on the NIM server. This notebook reads the dataset from an existing Snowflake stage using an active Snowpark session.\n\nThe client identifies the model as `KumoTabular()`; its size is determined by the server's deployed checkpoint. Local PyTorch `size`, `device`, and ensemble settings do not configure the NIM.\n\nSee the [Kumo Tabular overview](https://docs.nvidia.com/sdgm/kumo-tabular/about-kumo-tabular/overview), [quickstart](https://docs.nvidia.com/sdgm/kumo-tabular/get-started/quickstart), and [client repository](https://github.com/NVIDIA/structured-data-models-client).\n\nEach user is responsible for checking the content of datasets and the applicable licenses and determining if suitable for the intended use."
    },
    {
      "cell_type": "markdown",
      "id": "561d19ec",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 1. Install and connect\n\nUse a Python 3.10 or newer kernel with network access to the NIM endpoint and an active Snowflake session for the dataset. The notebook also uses pandas, NumPy, and scikit-learn.\n\nInstall the base client; the relational extra is not needed. See [Install and Connect](https://docs.nvidia.com/sdgm/kumo-tabular/get-started/sdk-getting-started)."
    },
    {
      "id": "39f1ec88-eee7-40e9-9c9b-4b2d36e0031c",
      "cell_type": "code",
      "metadata": {
        "language": "python"
      },
      "source": "%pip install structured-data-models-client",
      "outputs": [],
      "execution_count": null
    },
    {
      "id": "80909c75-dfb5-4051-b037-4a6b92e92049",
      "cell_type": "code",
      "metadata": {
        "language": "python"
      },
      "source": "import os\nfrom sdm_client import SDMClient, KumoTabular, Request, Schema, PredictiveQuery\n\n# Override the endpoint through environment configuration when needed.\nnim_endpoint = os.environ.get(\n    \"KUMO_TABULAR_API_ENDPOINT\",\n    \"http://<dns_name>:8000\",\n)\n\nnim_api_key = os.environ.get(\"KUMO_TABULAR_API_KEY\")",
      "outputs": [],
      "execution_count": null
    },
    {
      "id": "1ef18d21-c18a-44e6-b8f3-078ac5a2cc30",
      "cell_type": "code",
      "metadata": {
        "language": "python"
      },
      "source": "# Check the models served by the configured NIM endpoint.\nwith SDMClient(url=nim_endpoint, api_key=nim_api_key) as client:\n    print(client.models())",
      "outputs": [],
      "execution_count": null
    },
    {
      "cell_type": "markdown",
      "id": "e94f92c0",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 2. Load the dataset\n\n**Dataset:** [Mammographic Mass Data Set (Kaggle)](https://www.kaggle.com/datasets/overratedgman/mammographic-mass-data-set), version 3\n\n**Task:** Binary classification of breast masses: benign (0) or malignant (1)\n\nHere we will primarily use four predictors: `age`, `mass` `shape`, `margin`, and `density`"
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "bfdc049a",
      "metadata": {
        "language": "python"
      },
      "outputs": [],
      "source": "import numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom snowflake.snowpark.context import get_active_session\n\n# Read the Kaggle CSV uploaded to the stage\nsession = get_active_session()\nwith session.file.get_stream(\"@<database>.<schema>.<stage>/Cleaned_data.csv\") as f:\n    data = pd.read_csv(f)\n\n# Select predictors and readable class labels\nX = data[[\"Age\", \"Shape\", \"Margin\", \"Density\"]]\ny = data[\"Severity\"].map({0: \"benign\", 1: \"malignant\"})\nclasses = sorted(y.unique())\ndf = X.assign(target=pd.Categorical(y, categories=classes))\n\n# Split ICL examples (\"train\") and test sets \ntrain, test = train_test_split(\n    data.index, test_size=0.2, stratify=y, random_state=0,\n)"
    },
    {
      "cell_type": "markdown",
      "id": "9b2d96a3",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 3. Prepare rows and run Kumo Tabular through the NIM\n\nUse the training split as labelled `context` and the held-out test split as `predict`. The target column must be present only in the context. A row ID lets PQL identify entities and keeps the held-out rows distinct from the context.\n\nThe explicit schema preserves the original numerical and categorical feature types. The NIM accepts `task=\"classification\"` for both binary and multiclass tasks. Direct requests support up to 10,000 context rows; this dataset fits within that limit.\n\nSee [Make Predictions](https://docs.nvidia.com/sdgm/kumo-tabular/user-guide/make-predictions/make-predictions)."
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "91fccd58",
      "metadata": {
        "language": "python"
      },
      "outputs": [],
      "source": "context = df.iloc[train].copy()\nto_score = df.iloc[test].drop(columns=\"target\").copy()\ncontext.insert(0, \"row_id\", train)\nto_score.insert(0, \"row_id\", test)\n\nschema = Schema.from_data(\n    {\"masses\": context},\n    primary_keys={\"masses\": \"row_id\"},\n    relationships=[],\n)\nfor column, stype in {\n    \"Age\": \"numerical\",\n    \"Density\": \"numerical\",\n    \"Shape\": \"categorical\",\n    \"Margin\": \"categorical\",\n    \"target\": \"categorical\",\n}.items():\n    schema[\"masses\"][column].stype = stype\nschema.check_consistent()\n\nrequest = Request(\n    context=context,\n    predict=to_score,\n    target=\"target\",\n    task=\"classification\",\n    schema=schema,\n    entity_table=\"masses\",\n)\n\nwith SDMClient(url=nim_endpoint, api_key=nim_api_key) as client:\n    result = client.predict(\n        request,\n        model=KumoTabular(),\n        outputs=[\"prediction\", \"probabilities\"],\n    )"
    },
    {
      "cell_type": "markdown",
      "id": "9e64dc5a",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 4. Read the predictions\n\n`PredictionResult.to_pandas()` returns `row_index`, `prediction`, and `probability_<class>` columns. `row_index` refers to the zero-based position within `to_score`, not its pandas index. Align on it before evaluating against the test labels.\n\nSee [Understand Prediction Results](https://docs.nvidia.com/sdgm/kumo-tabular/user-guide/work-with-prediction-results/prediction-results)."
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c46ac604",
      "metadata": {
        "language": "python"
      },
      "outputs": [],
      "source": "answers = result.to_pandas().set_index(\"row_index\").reindex(range(len(to_score)))\npredictions = answers[\"prediction\"].to_numpy()\nprobabilities = answers[[f\"probability_{label}\" for label in classes]].to_numpy()\nanswers.head()"
    },
    {
      "cell_type": "markdown",
      "id": "6dc8e858",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 5. Evaluate predictions"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "039b95c2",
      "metadata": {
        "language": "python"
      },
      "outputs": [],
      "source": "from sklearn.dummy import DummyClassifier\nfrom sklearn.metrics import accuracy_score, roc_auc_score\n\nbaseline = DummyClassifier(strategy=\"most_frequent\").fit(X.iloc[train], y.iloc[train])\npd.DataFrame({\n    \"Model\": [\"Kumo Tabular (NIM)\", \"Majority class\"],\n    \"Accuracy\": [\n        accuracy_score(y.iloc[test], predictions),\n        accuracy_score(y.iloc[test], baseline.predict(X.iloc[test])),\n    ],\n    \"ROC AUC\": [\n        roc_auc_score(y.iloc[test], probabilities[:, classes.index(\"malignant\")]),\n        roc_auc_score(y.iloc[test], baseline.predict_proba(X.iloc[test])[:,\n                      list(baseline.classes_).index(\"malignant\")]),\n    ],\n}).set_index(\"Model\").round(4)"
    },
    {
      "cell_type": "markdown",
      "id": "f1d2284c",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## 6. Run the same task with a predictive query (PQL)\n\nPQL names the prediction target and entity. Here `PREDICT masses.target FOR EACH masses.row_id` asks for each mass's benign/malignant label. `materialize()` builds the request, and `client.predict()` sends it to the NIM.\n\nReuse the schema built from **training rows only** and supply the held-out feature rows with `predict=to_score`. This keeps test labels out of the prediction context. Pass `task=\"classification\"` explicitly. Both workflows use the same context, test split, and semantic types; predictions can vary between calls.\n\nFor rows already in a schema's table, `materialize(indices=[...], task=\"classification\")` selects rows by primary-key value and excludes them from context. The `predict=` form below scores rows supplied separately.\n\nSee [Make Predictions with PQL](https://docs.nvidia.com/sdgm/kumo-tabular/user-guide/make-predictions/make-predictions#ask-in-pql)."
    },
    {
      "cell_type": "code",
      "id": "c7d38349",
      "metadata": {
        "language": "python"
      },
      "source": "query = PredictiveQuery(\n    \"PREDICT masses.target FOR EACH masses.row_id\",\n    schema,\n)\npql_request = query.materialize(\n    predict=to_score,\n    task=\"classification\",\n    model=KumoTabular(),\n)\n\nwith SDMClient(url=nim_endpoint, api_key=nim_api_key) as client:\n    pql_result = client.predict(\n        pql_request,\n        model=KumoTabular(),\n        outputs=[\"prediction\", \"probabilities\"],\n    )\n\npql_answers = (\n    pql_result.to_pandas()\n    .set_index(\"row_index\")\n    .reindex(range(len(to_score)))\n)\npql_answers.head()",
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "id": "21562091",
      "metadata": {
        "language": "python"
      },
      "source": "pd.DataFrame({\n    \"Model\": [\"Kumo Tabular (NIM, PQL)\"],\n    \"Accuracy\": [accuracy_score(y.iloc[test], pql_answers[\"prediction\"])],\n    \"ROC AUC\": [roc_auc_score(y.iloc[test], pql_answers[\"probability_malignant\"])],\n}).set_index(\"Model\").round(4)",
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "id": "425c9d32",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "## Next Steps"
    },
    {
      "cell_type": "markdown",
      "id": "053b0106",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "### Check out other available Structured Data Foundation Models:\n- [Kumo-Relational](https://huggingface.co/nvidia/Kumo-Relational)\n- [Kumo-Anomaly](https://huggingface.co/nvidia/Kumo-Anomaly)\n- [Kumo-Forecast](https://huggingface.co/nvidia/Kumo-Forecast)"
    },
    {
      "cell_type": "markdown",
      "id": "27aae15a",
      "metadata": {
        "codeCollapsed": true
      },
      "source": "### Check out Kumo Engine\nTo run foundation models for structured data in production at scale, check out Kumo Engine\n- [Github](https://github.com/NVIDIA/kumo-engine)\n- [Documentation](https://docs.nvidia.com/sdgm/kumo-engine/get-started-with-kumo-engine/overview)"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}