{ "cells": [ { "cell_type": "markdown", "id": "3844ce21", "metadata": {}, "source": [ "# Monotone least squares \n", "The objective of this example is to show how to build a transport map to solve monotone regression problems using MParT." ] }, { "cell_type": "markdown", "id": "b79a3293", "metadata": {}, "source": [ "## Problem formulation\n", "One direct use of the monotonicity property given by the transport map approximation to model monotone functions from noisy data. This is called isotonic regression and can be solved in our setting by minimizing the least squares objective function\n", "\n", "$$\n", "J(\\mathbf{w})= \\frac{1}{2} \\sum_{i=1}^N \\left(S(x^i;\\mathbf{w}) - y^i \\right)^2,\n", "$$\n", "\n", "where $S$ is a monotone 1D map with parameters (polynomial coefficients) $\\mathbf{w}$ and $y^i$ are noisy observations. To solve for the map parameters that minimize this objective we will use a gradient-based optimizer. We therefore need the gradient of the objective with respect to the map paramters. This is given by\n", "\n", "$$\n", "\\nabla_\\mathbf{w} J(\\mathbf{w})= \\sum_{i=1}^N \\left(S(x^i;\\mathbf{w}) - y^i \\right)^T\\left[\\nabla_\\mathbf{w}S(x^i;\\mathbf{w})\\right]\n", "$$\n", "\n", "The implementation of S(x) we're using from MParT, provides tools for both evaluating the map to compute $S(x^i;\\mathbf{w})$ but also evaluating computing the action of $\\left[\\nabla_\\mathbf{w}S(x^i;\\mathbf{w})\\right]^T$ on a vector, which is useful for computing the gradient. Below, these features are leveraged when defining an objective function that we then minimize with the BFGS optimizer implemented in scipy.minimize." ] }, { "cell_type": "markdown", "id": "e38bedbd", "metadata": {}, "source": [ "## Imports\n", "First, import MParT and other packages used in this notebook. Note that it is possible to specify the number of threads used by MParT by setting the KOKKOS_NUM_THREADS environment variable **before** importing MParT." ] }, { "cell_type": "code", "execution_count": 1, "id": "8c9e07d2", "metadata": { "execution": { "iopub.execute_input": "2024-03-21T17:44:44.562465Z", "iopub.status.busy": "2024-03-21T17:44:44.562065Z", "iopub.status.idle": "2024-03-21T17:44:46.230254Z", "shell.execute_reply": "2024-03-21T17:44:46.229718Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kokkos::OpenMP::initialize WARNING: You are likely oversubscribing your CPU cores.\n", " process threads available : 4, requested thread : 8\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Kokkos::OpenMP::initialize WARNING: You are likely oversubscribing your CPU cores.\n", " Detected: 4 cores per node.\n", " Detected: 1 MPI_ranks per node.\n", " Requested: 8 threads per process.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Kokkos is using 8 threads\n" ] } ], "source": [ "import numpy as np\n", "from scipy.optimize import minimize\n", "import matplotlib.pyplot as plt\n", "import os\n", "os.environ['KOKKOS_NUM_THREADS'] = '8'\n", "\n", "import mpart as mt\n", "print('Kokkos is using', mt.Concurrency(), 'threads')\n", "plt.rcParams['figure.dpi'] = 110" ] }, { "cell_type": "markdown", "id": "c2f9ade7", "metadata": {}, "source": [ "## Generate training data\n", "\n", "### True model\n", "\n", "Here we choose to use the step function $H(x)=\\text{sgn}(x-2)+1$ as the reference monotone function. It is worth noting that this function is not strictly monotone and is only piecewise continuous." ] }, { "cell_type": "code", "execution_count": 2, "id": "de75209a", "metadata": { "execution": { "iopub.execute_input": "2024-03-21T17:44:46.232452Z", "iopub.status.busy": "2024-03-21T17:44:46.232214Z", "iopub.status.idle": "2024-03-21T17:44:46.358457Z", "shell.execute_reply": "2024-03-21T17:44:46.357960Z" } }, "outputs": [ { "data": { "image/png": "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n9uplP77Up4w34Q8E0VHR5e5Bq2wsFCHDh0qs2Z/aTtJZdru27dPNptN7dq1q/vO1qHajrsipf8VZEUNfa7rWkOb6wsXLujXv/61fv75Z23cuNF5QXpFrDLfNR13RRrafF+qc+fOatSokQ4ePFju51aZ70tVNe6KNJT5Pnz4sP79739r0KBBstvtstvtSkhIkCT16dNH/fv3L7edJ8w3Ic9E8fHx2rJli06fPu0s27BhgwoLCxUfH19huzZt2qhdu3ZavXq1S/lbb72lmJgYl12rnqi24y7PuXPnlJKSoq5du9Z1Nz1CQ5/rutTQ5rq4uFh33323du/erY0bN1Z5EbpkjfmuzbjL09Dmuzyff/65HA6HrrvuunI/t8J8l6eqcZenIc13586dlZaW5vL605/+JElasmSJXn311XLbecR8m3KjFhiGYRg5OTlGq1atjJ49exobN240Xn/9daN58+bGmDFjXOqNHz/eaNSokUvZmjVrDJvNZvzxj3800tLSjGnTphk2m83YtGmTmUOoldqO+9NPPzV+/etfG8uXLze2bt1qrFy50rjpppuMxo0bG19++aXZw6ixc+fOGWvXrjXWrl1r9O7d2wgPD3e+L723mNXm2jBqN+6GPteGYRi//e1vDUnGc889Z3z++ecurzNnzhiGYc35rs24rTDfQ4cONZ5++mnj/fffNz766CNj0aJFRkhIiNGxY0ejsLDQMAxrzndtxm2F+b5UWlpamfvkeeJ8E/JM9t133xlxcXGGv7+/0bx5c2PKlClGQUGBS52xY8ca5eXvFStWGNdff73RuHFjo3379saaNWvM6vZlq824v//+e+P22283WrZsafj4+BhBQUFGfHx8g/mjcPjwYUNSua+0tDTDMKw517UZd0Ofa8MwjIiIiCtyvmszbivM97PPPmt07tzZaNq0qREQEGDccMMNxuzZs53B1jCsOd+1GbcV5vtS5YU8T5xvm2E0kEVxAAAAVBvX5AEAAFgQIQ8AAMCCCHkAAAAWRMgDAACwIEIeAACABRHyAAAALIiQBwAAYEGEPAAAAAsi5AEAAFgQIQ8AAMCCCHkAAAAWRMgDAACwIEIeANSzvLw8RUREaMSIES7lv//972W323Xs2DE39QyAlRHyAKCeBQYGasWKFVq/fr3eeOMNSdKmTZv06quv6tVXX1VYWJibewjAimyGYRju7gQAXAkSExP117/+VR9//LEGDRqkW2+9VW+//ba7uwXAogh5AGCSCxcu6Oabb9ahQ4d09dVXa8+ePbLb7e7uFgCLYrkWAEzi5+enYcOGqbCwUGPGjCHgAahXnMkDAJPs2bNHv/rVr9S+fXulp6dr586dat++vbu7BcCiCHkAYIJ///vf6tatmwICArR161b16tVLDodDX3zxhXx8fNzdPQAWxHItAJjgySef1Pfff6/k5GQ1btxYb7zxhtLT0zVv3jx3dw2ARRHyAKCeffbZZ3ruuee0aNEiRUZGSpKioqL03HPP6dlnn9WXX37p5h4CsCKWawEAACyIM3kAAAAWRMgDAACwIEIeAACABRHyAAAALIiQBwAAYEGEPAAAAAsi5AEAAFgQIQ8AAMCCCHkAAAAWRMgDAACwIEIeAACABRHyAAAALOj/A91HCmaXQlNiAAAAAElFTkSuQmCC", "text/plain": [ "