{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "view-in-github"
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uiVM4lOtpJVt"
},
"source": [
"# Logistic regression in pytorch\n",
"This is an extension of using pytorch to perform linear regression to using it to perform logistic regression."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 195
},
"id": "6nKZWgTDvTTK",
"outputId": "264fb349-cfa2-42cd-ddb4-1efc49f2d883"
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" FLAIR | \n",
" PD | \n",
" T1 | \n",
" T2 | \n",
" FLAIR_10 | \n",
" PD_10 | \n",
" T1_10 | \n",
" T2_10 | \n",
" FLAIR_20 | \n",
" PD_20 | \n",
" T1_20 | \n",
" T2_20 | \n",
" GOLD_Lesions | \n",
" y | \n",
" x | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 1.143692 | \n",
" 1.586219 | \n",
" -0.799859 | \n",
" 1.634467 | \n",
" 0.437568 | \n",
" 0.823800 | \n",
" -0.002059 | \n",
" 0.573663 | \n",
" 0.279832 | \n",
" 0.548341 | \n",
" 0.219136 | \n",
" 0.298662 | \n",
" 0 | \n",
" 1 | \n",
" 1.181648 | \n",
"
\n",
" \n",
" 1 | \n",
" 1.652552 | \n",
" 1.766672 | \n",
" -1.250992 | \n",
" 0.921230 | \n",
" 0.663037 | \n",
" 0.880250 | \n",
" -0.422060 | \n",
" 0.542597 | \n",
" 0.422182 | \n",
" 0.549711 | \n",
" 0.061573 | \n",
" 0.280972 | \n",
" 0 | \n",
" 1 | \n",
" 1.426453 | \n",
"
\n",
" \n",
" 2 | \n",
" 1.036099 | \n",
" 0.262042 | \n",
" -0.858565 | \n",
" -0.058211 | \n",
" -0.044280 | \n",
" -0.308569 | \n",
" 0.014766 | \n",
" -0.256075 | \n",
" -0.136532 | \n",
" -0.350905 | \n",
" 0.020673 | \n",
" -0.259914 | \n",
" 0 | \n",
" 0 | \n",
" -0.614749 | \n",
"
\n",
" \n",
" 3 | \n",
" 1.037692 | \n",
" 0.011104 | \n",
" -1.228796 | \n",
" -0.470222 | \n",
" -0.013971 | \n",
" -0.000498 | \n",
" -0.395575 | \n",
" -0.221900 | \n",
" 0.000807 | \n",
" -0.003085 | \n",
" -0.193249 | \n",
" -0.139284 | \n",
" 0 | \n",
" 0 | \n",
" -0.955175 | \n",
"
\n",
" \n",
" 4 | \n",
" 1.580589 | \n",
" 1.730152 | \n",
" -0.860949 | \n",
" 1.245609 | \n",
" 0.617957 | \n",
" 0.866352 | \n",
" -0.099919 | \n",
" 0.384261 | \n",
" 0.391133 | \n",
" 0.608826 | \n",
" 0.071648 | \n",
" 0.340601 | \n",
" 0 | \n",
" 1 | \n",
" 1.376909 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" FLAIR PD T1 T2 FLAIR_10 PD_10 T1_10 \\\n",
"0 1.143692 1.586219 -0.799859 1.634467 0.437568 0.823800 -0.002059 \n",
"1 1.652552 1.766672 -1.250992 0.921230 0.663037 0.880250 -0.422060 \n",
"2 1.036099 0.262042 -0.858565 -0.058211 -0.044280 -0.308569 0.014766 \n",
"3 1.037692 0.011104 -1.228796 -0.470222 -0.013971 -0.000498 -0.395575 \n",
"4 1.580589 1.730152 -0.860949 1.245609 0.617957 0.866352 -0.099919 \n",
"\n",
" T2_10 FLAIR_20 PD_20 T1_20 T2_20 GOLD_Lesions y x \n",
"0 0.573663 0.279832 0.548341 0.219136 0.298662 0 1 1.181648 \n",
"1 0.542597 0.422182 0.549711 0.061573 0.280972 0 1 1.426453 \n",
"2 -0.256075 -0.136532 -0.350905 0.020673 -0.259914 0 0 -0.614749 \n",
"3 -0.221900 0.000807 -0.003085 -0.193249 -0.139284 0 0 -0.955175 \n",
"4 0.384261 0.391133 0.608826 0.071648 0.340601 0 1 1.376909 "
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import torch\n",
"import statsmodels.formula.api as smf\n",
"import statsmodels as sm\n",
"import seaborn as sns\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"## Read in the data and display a few rows\n",
"dat = pd.read_csv(\"https://raw.githubusercontent.com/bcaffo/ds4bme_intro/master/data/oasis.csv\")\n",
"dat.head(4)\n",
"\n",
"## Create a binary outcome variable (people will use gold lesions in HW)\n",
"m = np.median(dat.T2)\n",
"dat = dat.assign(y = (dat.T2 > m) * 1 )\n",
"## Create a normalized regression variable\n",
"dat = dat.assign(x = (dat.PD - np.mean(dat.PD)) / np.std(dat.PD))\n",
"dat.head()\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 290
},
"id": "ehiVfmYHJ4EL",
"outputId": "eb701a2c-88e2-46ee-b2cf-3d5b6cc8eaa8"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimization terminated successfully.\n",
" Current function value: 0.427855\n",
" Iterations 7\n"
]
},
{
"data": {
"text/html": [
"\n",
"Logit Regression Results\n",
"\n",
" Dep. Variable: | y | No. Observations: | 100 | \n",
"
\n",
"\n",
" Model: | Logit | Df Residuals: | 98 | \n",
"
\n",
"\n",
" Method: | MLE | Df Model: | 1 | \n",
"
\n",
"\n",
" Date: | Mon, 29 Jan 2024 | Pseudo R-squ.: | 0.3827 | \n",
"
\n",
"\n",
" Time: | 07:03:46 | Log-Likelihood: | -42.785 | \n",
"
\n",
"\n",
" converged: | True | LL-Null: | -69.315 | \n",
"
\n",
"\n",
" Covariance Type: | nonrobust | LLR p-value: | 3.238e-13 | \n",
"
\n",
"
\n",
"\n",
"\n",
" | coef | std err | z | P>|z| | [0.025 | 0.975] | \n",
"
\n",
"\n",
" Intercept | 0.0367 | 0.269 | 0.136 | 0.892 | -0.491 | 0.565 | \n",
"
\n",
"\n",
" x | 2.2226 | 0.436 | 5.095 | 0.000 | 1.368 | 3.078 | \n",
"
\n",
"
"
],
"text/latex": [
"\\begin{center}\n",
"\\begin{tabular}{lclc}\n",
"\\toprule\n",
"\\textbf{Dep. Variable:} & y & \\textbf{ No. Observations: } & 100 \\\\\n",
"\\textbf{Model:} & Logit & \\textbf{ Df Residuals: } & 98 \\\\\n",
"\\textbf{Method:} & MLE & \\textbf{ Df Model: } & 1 \\\\\n",
"\\textbf{Date:} & Mon, 29 Jan 2024 & \\textbf{ Pseudo R-squ.: } & 0.3827 \\\\\n",
"\\textbf{Time:} & 07:03:46 & \\textbf{ Log-Likelihood: } & -42.785 \\\\\n",
"\\textbf{converged:} & True & \\textbf{ LL-Null: } & -69.315 \\\\\n",
"\\textbf{Covariance Type:} & nonrobust & \\textbf{ LLR p-value: } & 3.238e-13 \\\\\n",
"\\bottomrule\n",
"\\end{tabular}\n",
"\\begin{tabular}{lcccccc}\n",
" & \\textbf{coef} & \\textbf{std err} & \\textbf{z} & \\textbf{P$> |$z$|$} & \\textbf{[0.025} & \\textbf{0.975]} \\\\\n",
"\\midrule\n",
"\\textbf{Intercept} & 0.0367 & 0.269 & 0.136 & 0.892 & -0.491 & 0.565 \\\\\n",
"\\textbf{x} & 2.2226 & 0.436 & 5.095 & 0.000 & 1.368 & 3.078 \\\\\n",
"\\bottomrule\n",
"\\end{tabular}\n",
"%\\caption{Logit Regression Results}\n",
"\\end{center}"
],
"text/plain": [
"\n",
"\"\"\"\n",
" Logit Regression Results \n",
"==============================================================================\n",
"Dep. Variable: y No. Observations: 100\n",
"Model: Logit Df Residuals: 98\n",
"Method: MLE Df Model: 1\n",
"Date: Mon, 29 Jan 2024 Pseudo R-squ.: 0.3827\n",
"Time: 07:03:46 Log-Likelihood: -42.785\n",
"converged: True LL-Null: -69.315\n",
"Covariance Type: nonrobust LLR p-value: 3.238e-13\n",
"==============================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"------------------------------------------------------------------------------\n",
"Intercept 0.0367 0.269 0.136 0.892 -0.491 0.565\n",
"x 2.2226 0.436 5.095 0.000 1.368 3.078\n",
"==============================================================================\n",
"\"\"\""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fit = smf.logit('y ~ x', data = dat).fit()\n",
"fit.summary()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "F6gUNlf6LbJc"
},
"outputs": [],
"source": [
"# The in sample predictions\n",
"yhat = 1 / (1 + np.exp(-fit.fittedvalues))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"id": "9LZ4MgGEPxEN",
"outputId": "6fe594a1-85f9-4644-f41c-6991e120e91c"
},
"outputs": [
{
"data": {
"text/plain": [
"[torch.Size([100, 1]), torch.Size([100, 1]), [100, 1]]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"n = dat.shape[0]\n",
"\n",
"## Get the y and x from \n",
"xtraining = torch.from_numpy(dat['x'].values)\n",
"ytraining = torch.from_numpy(dat['y'].values)\n",
"\n",
"## PT wants floats\n",
"xtraining = xtraining.float()\n",
"ytraining = ytraining.float()\n",
"\n",
"## Dimension is 1xn not nx1\n",
"## squeeze the second dimension\n",
"xtraining = xtraining.unsqueeze(1)\n",
"ytraining = ytraining.unsqueeze(1)\n",
"\n",
"## Show that everything is the right size\n",
"[xtraining.shape, \n",
" ytraining.shape,\n",
" [n, 1]\n",
" ]\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "OZKrXwTjPdrB"
},
"outputs": [],
"source": [
"## Doing it more now the pytorch docs recommend\n",
"## Example taken from \n",
"## https://medium.com/biaslyai/pytorch-linear-and-logistic-regression-models-5c5f0da2cb9\n",
"\n",
"## They recommend creating a class that defines\n",
"## the model\n",
"class LogisticRegression(torch.nn.Module):\n",
" def __init__(self):\n",
" super(LogisticRegression, self).__init__()\n",
" self.linear = torch.nn.Linear(1, 1, bias = True)\n",
" def forward(self, x):\n",
" y_pred = torch.sigmoid(self.linear(x))\n",
" return y_pred\n",
"\n",
"## Then the model is simply \n",
"model = LogisticRegression()\n",
"\n",
"## MSE is the loss function\n",
"loss_fn = torch.nn.BCELoss() \n",
"\n",
"## Set the optimizer\n",
"optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)\n",
"\n",
"## Loop over iterations\n",
"for t in range(100000):\n",
"\n",
" ## Forward propagation\n",
" y_pred = model(xtraining)\n",
"\n",
" ## the loss for this interation\n",
" loss = loss_fn(y_pred, ytraining)\n",
"\n",
" #print(t, loss.item() / n)\n",
"\n",
" ## Zero out the gradients before adding them up \n",
" optimizer.zero_grad()\n",
" \n",
" ## Backprop\n",
" loss.backward()\n",
" \n",
" ## Optimization step\n",
" optimizer.step()\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 282
},
"id": "fd1wjXgukgqs",
"outputId": "91f22597-1686-4b25-ee01-67dcba4753ca"
},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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fvz4omi51LDiu7DEjoz8zjCMM96bpnlW7c+OP1ddzhTqdf7d7Nmzef7550lOTqZKlSqF1V6JcqHX2u/3061bN8aMGUP9+vWLqr0SI5S/04FAAMMwmDVrFtdddx3t2rXjrbfeYubMmRod+ROhXOetW7cycOBARo0axYYNG/jss8/YtWsXffr0KYpWS5Wi/i4ssf+rFBcXh91uPythHzx48KzE97tLL730nMc7HA4qV65caL2Gs/xc598lJyfzyCOPMGfOHG6//fbCbLNECPVaHz9+nPXr17Nx40b69+8P5H5pmqaJw+Fg2bJl3HrrrUXSezjJz9/phIQEqlWrdsaj0hs2bIhpmuzdu5fLL7+8UHsOR/m5zklJSdxwww089dRTADRp0oSyZcvSunVrXnrpJY1eFxArvgtL7MhIREQEiYmJpKamnlFPTU2lVatW5zynZcuWZx2/bNkymjdvjtPpLLRew1l+rjPkjoj07NmTjz76SPO9FyjUax0TE8OWLVvYtGlT8NWnTx+uuOIKNm3aRIsWLYqq9bCSn7/TN9xwA/v37+fEiRPB2vbt27HZbFSvXr1Q+w1X+bnOp06dwmY782vLbrcDef/nLhfPku/CQrs1thj4fdnYtGnTzK1bt5qDBw82y5Yta+7evds0TdMcPny4+dBDDwWP/30505AhQ8ytW7ea06ZN09LeCxDqdf7oo49Mh8NhTpw40XS5XMHXsWPHrPoVwkao1/p/aTXNhQn1Oh8/ftysXr26ed9995k//vijuWLFCvPyyy83e/fubdWvEBZCvc4zZswwHQ6HOWnSJHPHjh3m6tWrzebNm5vXXXedVb9CWDh+/Li5ceNGc+PGjSZgvvXWW+bGjRuDS6iLw3dhiQ4jpmmaEydONGvVqmVGRESYzZo1M1esWBH8rEePHuZNN910xvFff/21ec0115gRERFm7dq1zcmTJxdxx+EplOt80003mcBZrx49ehR942Eo1L/T/01h5MKFep23bdtm3n777WaZMmXM6tWrm0OHDjVPnTpVxF2Hn1Cv87hx48wrr7zSLFOmjJmQkGA++OCD5t69e4u46/Dy1Vdf/eF/c4vDd6FhmhrbEhEREeuU2HtGREREJDwojIiIiIilFEZERETEUgojIiIiYimFEREREbGUwoiIiIhYSmFERERELKUwIiIiIpZSGBERERFLKYyIiIiIpRRGRERExFIKIyIiImKp/w9tbJzpUf4nAgAAAABJRU5ErkJggg==",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ytest = model(xtraining)\n",
"ytest = ytest.detach().numpy().reshape(-1)\n",
"plt.plot(yhat, ytest, \".\")\n",
"plt.plot([0, 1], [0, 1], linewidth=2)"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 52
},
"id": "hZpPdBPYy53z",
"outputId": "8ee26a76-37fd-4dc4-ea84-9a7f17cd5c3a"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([[1.4062]])\n",
"tensor([-0.0502])\n"
]
}
],
"source": [
"for param in model.parameters(): \n",
" print(param.data)\n"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"include_colab_link": true,
"machine_shape": "hm",
"name": "logisticRegression in pytorch",
"provenance": []
},
"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.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 4
}