{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1baac5d8",
   "metadata": {},
   "source": [
    "# Probabilistic analysis of SUV"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ccab8f6",
   "metadata": {},
   "source": [
    "Author: Martin Horvat, October 2022"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5da46295",
   "metadata": {},
   "source": [
    "## Reading matlab files and getting data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b6bd26cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "  Filenames of matlab files\n",
    "  CWD =  \"Optimisation Group/Retrospective  data/Python\"\n",
    "\"\"\" \n",
    "suv_filename = \"../data/suv_percentilesSLOthenUWM.mat\"\n",
    "flags_filename=\"../data/flags_combined.mat\"\n",
    "normal_range_filename =\"../data/normal_range.mat\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "02eb5b93",
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy import io\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a8a2b1fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "Loading all data\n",
    "\"\"\"\n",
    "suv_dict = io.loadmat(suv_filename)\n",
    "flags_dict = io.loadmat(flags_filename)\n",
    "normal_range_dict = io.loadmat(normal_range_filename)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "767eadff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "suv: dict_keys(['__header__', '__version__', '__globals__', 'bowel_SUVperc_COMBINED', 'lung_SUVperc_COMBINED', 'thyroid_SUVperc_COMBINED'])\n",
      "flags: dict_keys(['__header__', '__version__', '__globals__', 'days', 'flags', 'patients'])\n"
     ]
    }
   ],
   "source": [
    "# tables in data\n",
    "print(\"suv:\", suv_dict.keys())\n",
    "print(\"flags:\",flags_dict.keys())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00c25424",
   "metadata": {},
   "source": [
    "## Short analysis of max SUV at certain percentiles for lungs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "eabead83",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "flags = flags_dict['flags']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b7c8f0ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(71, 17, 100)\n",
      "(71, 7)\n"
     ]
    }
   ],
   "source": [
    "print(lung_suv.shape)\n",
    "print(flags.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "62381e04",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1   0   0   1 187   0   0]\n",
      " [  1   0   0   0   0   1  17]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   1 191   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   1 299   0   0]\n",
      " [  1   1 196   0   0   0   0]\n",
      " [  1   0   0   0   0   1  42]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   1  65   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   1 122   1 122]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1 637]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1 154]\n",
      " [  1   0   0   0   0   1 721]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   1 195   1 273   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1  63]\n",
      " [  1   1  32   0   0   0   0]\n",
      " [  9   1 323   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  2   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1  27]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   1 231   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1  28]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  2   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  2   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  3   0   0   0   0   0   0]\n",
      " [  2   0   0   0   0   0   0]\n",
      " [  5   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   0   0]\n",
      " [  1   0   0   0   0   1   0]\n",
      " [  1   0   0   0   0   1   0]]\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Flags: columns\n",
    "    0 base : line exist  \n",
    "    1 bowel : status, 0 ~ NC, 1 ~ AE\n",
    "    2 bowel : time\n",
    "    3 lung  : status\n",
    "    4 lung  : time \n",
    "    5 thyroid : status\n",
    "    6 thyroid : time \n",
    "\"\"\"\n",
    "print(flags)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4c04d7fa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
      "NC: 66\n",
      "AE: 5\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "  Focus on lungs\n",
    "\"\"\"\n",
    "lung_flags = flags[:,3]\n",
    "print(lung_flags)\n",
    "print(\"NC:\", np.count_nonzero(lung_flags == 0))\n",
    "print(\"AE:\", np.count_nonzero(lung_flags == 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "20d1c213",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 95  # percentile of interest\n",
    "X = np.nanmax(lung_suv[:,:,p], axis=1)  # taking SUV max and ignoring NaNs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8c50b417",
   "metadata": {},
   "outputs": [],
   "source": [
    "# extracting Xs associated to NC and AE\n",
    "X_NC = X[lung_flags == 0]\n",
    "X_AE = X[lung_flags == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "d2df81aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['font.size']=16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "55fb09a9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 5104 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    " Plotting stuff\n",
    "\"\"\"\n",
    "plt.hist(X_NC,density=True,label=\"NC\")\n",
    "plt.hist(X_AE,density=True,label=\"AE\")\n",
    "plt.legend()\n",
    "plt.savefig(\"p_risk.pdf\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecd96505",
   "metadata": {},
   "source": [
    "Conclusion:\n",
    "The statistics of AE is not very good, but for NC is reasonable."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8cbe96f",
   "metadata": {},
   "source": [
    "## Distributions of max SUV in patients"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "5df2cf8e",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "lung_flags = flags_dict['flags'][:,3]  # 0 == NC, 1 == AE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "d88b747a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate percentiles\n",
    "P = np.arange(0,100)/100\n",
    "\n",
    "# calculate max SUV of all visits per patient and percentile (i)\n",
    "X = np.array([np.nanmax(lung_suv[:,:,i], axis=1) for i in range(100)], dtype=float).T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "dc54dff6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(71, 100)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "c9c9e21f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "a2ce731c",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['text.usetex'] = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "497ae324",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.xlim(0.1,20)\n",
    "plt.ylim(0.01,1)\n",
    "\n",
    "plt.xscale('log')\n",
    "plt.yscale('log')\n",
    "plt.xlabel(r\"$x = \\max_\\textrm{over visits}(SUV)$\")\n",
    "plt.ylabel(r\"$1 - P(X < x)$\")\n",
    "\n",
    "plt.title(\"AE cases\")\n",
    "for x in X[lung_flags == 1]: plt.plot(x,1-P)\n",
    "plt.tight_layout()\n",
    "plt.savefig(\"P_risk_AE.pdf\",bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "3f6154fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 71832 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlim(0.1,20)\n",
    "plt.ylim(0.01,1)\n",
    "\n",
    "plt.xscale('log')\n",
    "plt.yscale('log')\n",
    "plt.xlabel(r\"$x = \\max_\\textrm{over visits}(SUV)$\")\n",
    "plt.ylabel(r\"$1 - P(X < x)$\")\n",
    "plt.title(\"NC cases\")\n",
    "\n",
    "for x in X[lung_flags == 0]: plt.plot(x,1-P)\n",
    "plt.tight_layout()\n",
    "plt.savefig(\"P_risk_NC.pdf\",bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "3caf02fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f9496531450>"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 20792 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlim(0.1,30)\n",
    "plt.ylim(0.01,1)\n",
    "\n",
    "plt.xscale('log')\n",
    "plt.yscale('log')\n",
    "plt.xlabel(r\"$x = \\max_\\textrm{over visits}(SUV)$\")\n",
    "plt.ylabel(r\"$1 - P(X < x)$\")\n",
    "plt.title(\"average distributions\")\n",
    "\n",
    "plt.plot(np.average(X[lung_flags == 0],axis=0),1-P,label='NC')\n",
    "plt.plot(np.average(X[lung_flags == 1],axis=0),1-P,label='AE')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "92373a7d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f948f21e380>"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 21848 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlim(0.1,30)\n",
    "plt.ylim(0.01,1)\n",
    "\n",
    "plt.xscale('log')\n",
    "plt.yscale('log')\n",
    "plt.xlabel(r\"$x = \\max_\\textrm{over visits}(SUV)$\")\n",
    "plt.ylabel(r\"$1 - P(X < x)$\")\n",
    "plt.title(\"average distributions +- std. of average\")\n",
    "\n",
    "for i,l in enumerate(['NC','AE']):\n",
    "    T = X[lung_flags == i]\n",
    "    plt.errorbar(np.average(T,axis=0), 1-P, xerr = np.std(T, axis=0), label=l)\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "ac9c21f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 20508 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlim(0.1,30)\n",
    "plt.ylim(0.01,1)\n",
    "\n",
    "plt.xscale('log')\n",
    "plt.yscale('log')\n",
    "plt.xlabel(r\"$x = \\max_\\textrm{over visits}(SUV)$\")\n",
    "plt.ylabel(r\"$1 - ProbX < x)$\")\n",
    "plt.title(\"average distributions +- std. of average\")\n",
    "\n",
    "for i,l in enumerate(['NC','AE']):\n",
    "    T = X[lung_flags == i]\n",
    "    n = np.count_nonzero(lung_flags == 0)\n",
    "    plt.errorbar(np.average(T,axis=0), 1-P, xerr = np.std(T, axis=0)/np.sqrt(n), label=l)\n",
    "    \n",
    "plt.legend()\n",
    "plt.tight_layout()\n",
    "plt.savefig(\"Pave_risk.pdf\",bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4af369ab",
   "metadata": {},
   "source": [
    "## Logistic/logit regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "10fc7388",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32864413",
   "metadata": {},
   "source": [
    "On ubuntu:\n",
    "```\n",
    "apt install python3-sklearn\n",
    "```\n",
    "Ref:\n",
    " * https://en.wikipedia.org/wiki/Logistic_regression\n",
    " * https://www.w3schools.com/python/python_ml_logistic_regression.asp\n",
    " * https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n",
    " * https://stackoverflow.com/questions/36681449/scikit-learn-return-value-of-logisticregression-predict-proba"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "014247a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "lung_flags = flags_dict['flags'][:,3]  # 0 == NC, 1 == AE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "3d813361",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 95  # percentile of interest\n",
    "X = np.nanmax(lung_suv[:,:,p], axis=1).reshape(-1,1)   # taking SUV max and ignoring NaNs, shape [71,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "9751c867",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import linear_model\n",
    "logr = linear_model.LogisticRegression()\n",
    "clf = logr.fit(X, lung_flags)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "1cc45208",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w0: [-5.9605805]\n",
      "w1: [[2.04920735]]\n"
     ]
    }
   ],
   "source": [
    "# underlaying linear model coefficients\n",
    "print(\"w0:\", logr.intercept_)\n",
    "print(\"w1:\", logr.coef_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "19901943",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.linspace(0, 6, 100)\n",
    "y = logr.predict_proba(x.reshape(-1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "845ca499",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f767024db70>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 13592 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"P(AE|X=x)\")\n",
    "\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"AE\")\n",
    "#plt.plot(x, y[:,1], label=\"probability\",color=\"red\")\n",
    "plt.plot(x, 1/(1 + np.exp(-logr.intercept_[0] - logr.coef_[0,0]*x)), label=\"logit model\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "1f7a8948",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Covariance matrix: \n",
      " [[ 3.13832521 -1.68557139]\n",
      " [-1.68557139  0.99280095]]\n",
      "Standard errors:  [1.77153188 0.99639397]\n",
      "Params: [-5.9605805   2.04920735]\n",
      "Wald statistics:  [11.32085346  4.22970058]\n"
     ]
    }
   ],
   "source": [
    "# Ref:\n",
    "#   https://stats.stackexchange.com/questions/89484/how-to-compute-the-standard-errors-of-a-logistic-regressions-coefficients\n",
    "#   https://web.stanford.edu/class/archive/stats/stats200/stats200.1172/Lecture26.pdf\n",
    "\n",
    "# Calculate matrix of predicted class probabilities.\n",
    "predProbs = logr.predict_proba(X)\n",
    "\n",
    "# Design matrix -- add column of 1's at the beginning of your X_train matrix\n",
    "X_design = np.hstack([np.ones((X.shape[0], 1)), X])\n",
    "\n",
    "# Initiate matrix of 0's, fill diagonal with each predicted observation's variance\n",
    "V = np.diagflat(np.product(predProbs, axis=1))\n",
    "\n",
    "# Covariance matrix C_params = (X^T V X)^-1, params = (b0,b1) \n",
    "covLogit = np.linalg.inv(np.dot(np.dot(X_design.T, V), X_design))\n",
    "print(\"Covariance matrix: \\n\", covLogit)\n",
    "\n",
    "# Standard errors\n",
    "print(\"Standard errors: \", np.sqrt(np.diag(covLogit)))\n",
    "\n",
    "# Wald statistic (coefficient / s.e.) ^ 2\n",
    "logitParams = np.insert(logr.coef_, 0, logr.intercept_)\n",
    "print(\"Params:\", logitParams)\n",
    "print(\"Wald statistics: \", (logitParams / np.sqrt(np.diag(covLogit))) ** 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "id": "4b1e2ee4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f76135633a0>"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 12600 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Linear approach to variance in logit regression:\n",
    "#\n",
    "#   f(x|p*) + df(x|p*).dp  dp ~ N(0,C_p)\n",
    "#   V_f = E[(df(x|p*).dp)^2] = df(x|p*)^T C_p df(x|p*)\n",
    "\n",
    "f = lambda x: 1/(1 + np.exp(-logitParams[0] - logitParams[1]*x))\n",
    "\n",
    "def df(x): \n",
    "    t = f(x)\n",
    "    return -t*(1-t)*np.array((1,x))\n",
    "\n",
    "def Vf(x):\n",
    "    t = df(x)\n",
    "    return np.dot(t,np.dot(covLogit,t))\n",
    "\n",
    "x = np.linspace(0, 6, 100)\n",
    "y = f(x)\n",
    "dy = np.sqrt([Vf(t) for t in x])\n",
    "\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"AE\")\n",
    "plt.plot(x, y, label=\"fit logitmodel \",color=\"red\")\n",
    "plt.errorbar(x,y,dy, label=\"linear variance\", fmt=' ')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "f5cd2ccf-6321-4211-ab61-08d68d8c5219",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Direct approach to variance in logit regression:\n",
    "#\n",
    "#   f(x|p*)    p ~ N(p*,C_p)\n",
    "#\n",
    "\n",
    "f = lambda x,p: 1/(1 + np.exp(-p[0] - p[1]*x))\n",
    "fopt = lambda x: 1/(1 + np.exp(-logitParams[0] - logitParams[1]*x))\n",
    "\n",
    "#generate parameters and points in x axis\n",
    "ps = np.random.multivariate_normal(logitParams, covLogit, 1000)\n",
    "xs = np.linspace(0, 6, 100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "id": "290689a3-f3b4-44c8-a5e0-f3b1333ecd95",
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate values in y axis\n",
    "yopts = fopt(xs)\n",
    "ys = np.array([np.fromiter(map(lambda p: f(x,p), ps),float) for x in xs])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "id": "ca4438c7-24c4-4d02-bebc-be3137250652",
   "metadata": {},
   "outputs": [],
   "source": [
    "# doing statistics on values\n",
    "mys = np.median(ys,axis=1)\n",
    "yerr_min = np.quantile(ys, 0.25, axis=1)\n",
    "yerr_max = np.quantile(ys, 0.75, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "id": "03fdb9cc-b0b3-4d50-b59f-1d88efa5cef2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f7612fcb3d0>"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 13028 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"AE\")\n",
    "plt.plot(xs, yopts, label=\"fit logit model\",color=\"red\")\n",
    "plt.errorbar(xs, mys, yerr = [mys-yerr_min, yerr_max-mys], label=\"direct variance\",fmt=' ')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fa88da2",
   "metadata": {},
   "source": [
    "## Bayesian Gaussian modeling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "21058bc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "c3e4dd89",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "lung_flags = flags_dict['flags'][:,3]  # 0 == NC, 1 == AE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f9e6e879",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 95  # percentile of interest\n",
    "X = np.nanmax(lung_suv[:,:,p], axis=1) # taking SUV max and ignoring NaNs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "57558f7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# first central moments of X associated to NC and AE \n",
    "param_NC = [np.mean(X[lung_flags==0]), np.std(X[lung_flags==0])]\n",
    "param_AE = [np.mean(X[lung_flags==1]), np.std(X[lung_flags==1])]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "fc9def49",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.3857508112083783, 0.25838646551499894]\n",
      "[2.662019371986389, 0.9351373779777512]\n"
     ]
    }
   ],
   "source": [
    "print(param_NC)\n",
    "print(param_AE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "559eb809",
   "metadata": {},
   "outputs": [],
   "source": [
    "# define Gaussian distribution\n",
    "g = lambda x, mu, sigma: np.exp(-(x-mu)**2/(2*sigma**2))/(np.sqrt(2*np.pi)*sigma)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "df3ffcfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# probability for NC and AE  \n",
    "P_NC = np.count_nonzero(lung_flags == 0)/len(lung_flags)  # Prob(Y = NC)\n",
    "P_AE = np.count_nonzero(lung_flags == 1)/len(lung_flags)  # Prob(Y = AE)\n",
    "\n",
    "\n",
    "# defined conditional probability densities  for X at a class \n",
    "f_XatNC = lambda x: g(x, param_NC[0], param_NC[1])   # f(x | NC)\n",
    "f_XatAE = lambda x: g(x, param_AE[0], param_AE[1])   # f(x | AE)\n",
    "\n",
    "# probability density for X\n",
    "f_X = lambda x: P_NC*f_XatNC(x) + P_AE*f_XatAE(x)\n",
    "\n",
    "\n",
    "# conditional probability for AE at X\n",
    "P_AEatX = lambda x: P_AE*f_XatAE(x)/f_X(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "dbdf301c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fb8c3ee6aa0>"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 17684 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(0, 6, 100)\n",
    "\n",
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"P(AE|X=x)\")\n",
    "\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"AE\")\n",
    "\n",
    "plt.plot(x, P_AEatX(x), label=\"Bayesian model with Gaussians\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "dabe8878",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fb8c3b6f370>"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 21520 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"f_X(x|case)\")\n",
    "\n",
    "plt.plot(x,f_XatNC(x),label=\"case=NC\")\n",
    "plt.plot(x,f_XatAE(x),label=\"case=AE\")\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"point NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"points AE\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d0f363d",
   "metadata": {},
   "source": [
    "## Bayesian Lognormal modeling\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2a60d334",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "0dea6bca",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "lung_flags = flags_dict['flags'][:,3]  # 0 == NC, 1 == AE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "f69c3512",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 95  # percentile of interest\n",
    "X = np.nanmax(lung_suv[:,:,p], axis=1) # taking SUV max and ignoring NaNs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "3219d4ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# first central moments of X associated to NC and AE \n",
    "param_NC = [np.mean(np.log(X[lung_flags==0])), np.std(np.log(X[lung_flags==0]))]\n",
    "param_AE = [np.mean(np.log(X[lung_flags==1])), np.std(np.log(X[lung_flags==1]))]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "0a62b5e1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.3099913036929419, 0.17899981637999948]\n",
      "[0.927665922391502, 0.3065334767927164]\n"
     ]
    }
   ],
   "source": [
    "print(param_NC)\n",
    "print(param_AE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "92d64787",
   "metadata": {},
   "outputs": [],
   "source": [
    "# define lognormal distribution\n",
    "lg = lambda x, mu, sigma: np.exp(-(np.log(x)-mu)**2/(2*sigma**2))/(np.sqrt(2*np.pi)*sigma*x)\n",
    "# define Gaussian distribution\n",
    "g = lambda x, mu, sigma: np.exp(-(x-mu)**2/(2*sigma**2))/(np.sqrt(2*np.pi)*sigma)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "493344e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# probability for NC and AE  \n",
    "P_NC = np.count_nonzero(lung_flags == 0)/len(lung_flags)  # Prob(Y = NC)\n",
    "P_AE = np.count_nonzero(lung_flags == 1)/len(lung_flags)  # Prob(Y = AE)\n",
    "\n",
    "\n",
    "# defined conditional probability densities  for X at a class \n",
    "f_XatNC = lambda x: lg(x, param_NC[0], param_NC[1])   # f(x | NC)\n",
    "f_XatAE = lambda x: lg(x, param_AE[0], param_AE[1])   # f(x | AE)\n",
    "\n",
    "# probability density for X\n",
    "f_X = lambda x: P_NC*f_XatNC(x) + P_AE*f_XatAE(x)\n",
    "\n",
    "\n",
    "# conditional probability for AE at X\n",
    "P_AEatX = lambda x: P_AE*f_XatAE(x)/f_X(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "b707afde",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fb8c3c6b190>"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 16112 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(0.5, 6, 100)\n",
    "\n",
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"P(AE|X=x)\")\n",
    "\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"AE\")\n",
    "\n",
    "plt.plot(x, P_AEatX(x), label=\"Bayesian model with Lognormals\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "2a6cc81e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fb8c3dfb670>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 21636 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"f_X(x|case)\")\n",
    "\n",
    "plt.plot(x,f_XatNC(x),label=\"case=NC\")\n",
    "plt.plot(x,f_XatAE(x),label=\"case=AE\")\n",
    "plt.scatter(X[lung_flags==0], lung_flags[lung_flags==0],label=\"point NC\")  \n",
    "plt.scatter(X[lung_flags==1], lung_flags[lung_flags==1],label=\"points AE\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c982d82",
   "metadata": {},
   "source": [
    "## Bayesian custom  distribution modeling via Fitter package\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "623911f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "87e42b85",
   "metadata": {},
   "outputs": [],
   "source": [
    "## fitter package provides a simple class to identify the distribution from which a data samples is generated from\n",
    "## pip3 install fitter --user\n",
    "from fitter import Fitter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "3b34915b",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    " Extracting only data associated to lungs\n",
    "\"\"\"\n",
    "lung_suv = suv_dict['lung_SUVperc_COMBINED']\n",
    "lung_flags = flags_dict['flags'][:,3]  # 0 == NC, 1 == AE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "4d08ebd0",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 95  # percentile of interest\n",
    "X = np.nanmax(lung_suv[:,:,p], axis=1) # taking SUV max and ignoring NaNs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "e14a1285",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_NC = X[lung_flags==0]\n",
    "X_AE = X[lung_flags==1]\n",
    "\n",
    "flags_NC = lung_flags[lung_flags==0]\n",
    "flags_AE = lung_flags[lung_flags==1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "ecc1366d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Fitting 106 distributions:  25%|███▊           | 27/106 [00:01<00:06, 12.87it/s]/usr/lib/python3/dist-packages/scipy/stats/_continuous_distns.py:3102: IntegrationWarning: The occurrence of roundoff error is detected, which prevents \n",
      "  the requested tolerance from being achieved.  The error may be \n",
      "  underestimated.\n",
      "  t1 = integrate.quad(llc, -np.inf, x)[0]\n",
      "Fitting 106 distributions:  27%|████           | 29/106 [00:02<00:07, 10.94it/s]/usr/lib/python3/dist-packages/scipy/stats/_continuous_distns.py:3102: IntegrationWarning: The algorithm does not converge.  Roundoff error is detected\n",
      "  in the extrapolation table.  It is assumed that the requested tolerance\n",
      "  cannot be achieved, and that the returned result (if full_output = 1) is \n",
      "  the best which can be obtained.\n",
      "  t1 = integrate.quad(llc, -np.inf, x)[0]\n",
      "/usr/lib/python3/dist-packages/scipy/stats/_continuous_distns.py:3102: IntegrationWarning: The integral is probably divergent, or slowly convergent.\n",
      "  t1 = integrate.quad(llc, -np.inf, x)[0]\n",
      "Fitting 106 distributions:  44%|██████▋        | 47/106 [00:04<00:06,  8.78it/s]WARNING:root:SKIPPED kstwo distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  75%|███████████▏   | 79/106 [00:08<00:04,  6.09it/s]WARNING:root:SKIPPED rv_continuous distribution (taking more than 30 seconds)\n",
      "WARNING:root:SKIPPED rv_histogram distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  98%|█████████████▋| 104/106 [00:22<00:03,  1.92s/it]/usr/lib/python3/dist-packages/scipy/integrate/_quadpack_py.py:879: IntegrationWarning: The maximum number of subdivisions (50) has been achieved.\n",
      "  If increasing the limit yields no improvement it is advised to analyze \n",
      "  the integrand in order to determine the difficulties.  If the position of a \n",
      "  local difficulty can be determined (singularity, discontinuity) one will \n",
      "  probably gain from splitting up the interval and calling the integrator \n",
      "  on the subranges.  Perhaps a special-purpose integrator should be used.\n",
      "  quad_r = quad(f, low, high, args=args, full_output=self.full_output,\n",
      "/usr/lib/python3/dist-packages/scipy/integrate/_quadpack_py.py:879: IntegrationWarning: The integral is probably divergent, or slowly convergent.\n",
      "  quad_r = quad(f, low, high, args=args, full_output=self.full_output,\n",
      "WARNING:root:SKIPPED levy_stable distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  99%|█████████████▊| 105/106 [00:34<00:04,  4.58s/it]WARNING:root:SKIPPED studentized_range distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions: 100%|██████████████| 106/106 [00:38<00:00,  2.74it/s]\n"
     ]
    }
   ],
   "source": [
    "f_NC = Fitter(X_NC)\n",
    "f_NC.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "1f426be8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sumsquare_error</th>\n",
       "      <th>aic</th>\n",
       "      <th>bic</th>\n",
       "      <th>kl_div</th>\n",
       "      <th>ks_statistic</th>\n",
       "      <th>ks_pvalue</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>dgamma</th>\n",
       "      <td>50.441287</td>\n",
       "      <td>420.953150</td>\n",
       "      <td>-5.174787</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.110320</td>\n",
       "      <td>0.370769</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>dweibull</th>\n",
       "      <td>53.350977</td>\n",
       "      <td>416.219346</td>\n",
       "      <td>-1.473358</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.114425</td>\n",
       "      <td>0.327907</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>burr</th>\n",
       "      <td>57.746991</td>\n",
       "      <td>378.503984</td>\n",
       "      <td>7.942108</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.086732</td>\n",
       "      <td>0.671072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mielke</th>\n",
       "      <td>57.747002</td>\n",
       "      <td>378.502837</td>\n",
       "      <td>7.942121</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.086731</td>\n",
       "      <td>0.671079</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>logistic</th>\n",
       "      <td>58.086717</td>\n",
       "      <td>405.057087</td>\n",
       "      <td>-0.050060</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.087842</td>\n",
       "      <td>0.655816</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          sumsquare_error         aic       bic  kl_div  ks_statistic  \\\n",
       "dgamma          50.441287  420.953150 -5.174787     inf      0.110320   \n",
       "dweibull        53.350977  416.219346 -1.473358     inf      0.114425   \n",
       "burr            57.746991  378.503984  7.942108     inf      0.086732   \n",
       "mielke          57.747002  378.502837  7.942121     inf      0.086731   \n",
       "logistic        58.086717  405.057087 -0.050060     inf      0.087842   \n",
       "\n",
       "          ks_pvalue  \n",
       "dgamma     0.370769  \n",
       "dweibull   0.327907  \n",
       "burr       0.671072  \n",
       "mielke     0.671079  \n",
       "logistic   0.655816  "
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 25180 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f_NC.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "f66ffca5",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Fitting 106 distributions:  43%|██████▌        | 46/106 [00:07<00:04, 12.11it/s]WARNING:root:SKIPPED kstwo distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  74%|███████████    | 78/106 [00:14<00:11,  2.37it/s]WARNING:root:SKIPPED rv_continuous distribution (taking more than 30 seconds)\n",
      "WARNING:root:SKIPPED rv_histogram distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  96%|█████████████▍| 102/106 [00:31<00:09,  2.36s/it]WARNING:root:SKIPPED levy_stable distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions:  99%|█████████████▊| 105/106 [00:43<00:03,  3.44s/it]WARNING:root:SKIPPED studentized_range distribution (taking more than 30 seconds)\n",
      "Fitting 106 distributions: 100%|██████████████| 106/106 [00:45<00:00,  2.31it/s]\n"
     ]
    }
   ],
   "source": [
    "f_AE = Fitter(X_AE)\n",
    "f_AE.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "fd5c81fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sumsquare_error</th>\n",
       "      <th>aic</th>\n",
       "      <th>bic</th>\n",
       "      <th>kl_div</th>\n",
       "      <th>ks_statistic</th>\n",
       "      <th>ks_pvalue</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>exponweib</th>\n",
       "      <td>228.925939</td>\n",
       "      <td>440.014005</td>\n",
       "      <td>25.557555</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.403842</td>\n",
       "      <td>0.298813</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>exponpow</th>\n",
       "      <td>229.805636</td>\n",
       "      <td>394.721026</td>\n",
       "      <td>23.967294</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.388485</td>\n",
       "      <td>0.340837</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>fisk</th>\n",
       "      <td>231.478144</td>\n",
       "      <td>503.287303</td>\n",
       "      <td>24.003551</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.367344</td>\n",
       "      <td>0.408087</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>gamma</th>\n",
       "      <td>234.918930</td>\n",
       "      <td>449.229349</td>\n",
       "      <td>24.077327</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.530632</td>\n",
       "      <td>0.076795</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>powerlognorm</th>\n",
       "      <td>235.582727</td>\n",
       "      <td>876.615438</td>\n",
       "      <td>25.700873</td>\n",
       "      <td>inf</td>\n",
       "      <td>0.761559</td>\n",
       "      <td>0.001558</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              sumsquare_error         aic        bic  kl_div  ks_statistic  \\\n",
       "exponweib          228.925939  440.014005  25.557555     inf      0.403842   \n",
       "exponpow           229.805636  394.721026  23.967294     inf      0.388485   \n",
       "fisk               231.478144  503.287303  24.003551     inf      0.367344   \n",
       "gamma              234.918930  449.229349  24.077327     inf      0.530632   \n",
       "powerlognorm       235.582727  876.615438  25.700873     inf      0.761559   \n",
       "\n",
       "              ks_pvalue  \n",
       "exponweib      0.298813  \n",
       "exponpow       0.340837  \n",
       "fisk           0.408087  \n",
       "gamma          0.076795  \n",
       "powerlognorm   0.001558  "
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 20312 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f_AE.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "5ec7ddad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'dgamma': {'a': 1.7679446613668826, 'loc': 1.3985560931689764, 'scale': 0.10908557770910016}}\n",
      "{'exponweib': {'a': 0.6969758080792576, 'c': 0.40664217557825433, 'loc': 1.7872766256332395, 'scale': 1.132668555489615}}\n"
     ]
    }
   ],
   "source": [
    "print(f_NC.get_best())\n",
    "print(f_AE.get_best())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "cd262429",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1.3766861489939175, 0.134050348144684)\n",
      "(2.4707774407516867, 0.48732718406256026)\n"
     ]
    }
   ],
   "source": [
    "# see tutorial: https://fitter.readthedocs.io/en/latest/tuto.html\n",
    "print(f_NC.fitted_param['logistic'])\n",
    "print(f_AE.fitted_param['logistic'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "id": "d14d775f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.stats as ss\n",
    "\n",
    "# choose distributions\n",
    "dist_name_NC = 'logistic'\n",
    "dist_name_AE = 'logistic'\n",
    "\n",
    "par_NC = f_NC.fitted_param[dist_name_NC]\n",
    "par_AE = f_AE.fitted_param[dist_name_AE]\n",
    "\n",
    "dist_NC = ss.logistic.pdf\n",
    "dist_AE = ss.logistic.pdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "91b734ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# probability for NC and AE  \n",
    "P_NC = np.count_nonzero(lung_flags == 0)/len(lung_flags)  # Prob(Y = NC)\n",
    "P_AE = np.count_nonzero(lung_flags == 1)/len(lung_flags)  # Prob(Y = AE)\n",
    "\n",
    "# defined conditional probability densities  for X at a class \n",
    "f_XatNC = lambda x: dist_NC(x, *par_NC)   # f(x | NC)\n",
    "f_XatAE = lambda x: dist_AE(x, *par_AE)   # f(x | AE)\n",
    "\n",
    "# probability density for X\n",
    "f_X = lambda x: P_NC*f_XatNC(x) + P_AE*f_XatAE(x)\n",
    "\n",
    "# conditional probability for AE at X\n",
    "P_AEatX = lambda x: P_AE*f_XatAE(x)/f_X(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "c3de7e50",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f35fdb5ab60>"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 17300 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.linspace(0.5, 6, 100)\n",
    "\n",
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"P(AE|X=x)\")\n",
    "\n",
    "plt.scatter(X_NC, lung_flags_NC,label=\"NC\")  \n",
    "plt.scatter(X_AE, lung_flags_AE,label=\"AE\")\n",
    "\n",
    "plt.plot(x, P_AEatX(x), label = f\"Bayesian model with ({dist_name_NC}, {dist_name_AE})\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "b0f3b623",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f35fd7578b0>"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 21388 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.xlabel(\"x = maxSUV\")\n",
    "plt.ylabel(\"f_X(x|case)\")\n",
    "\n",
    "plt.plot(x,f_XatNC(x),label=\"case=NC\")\n",
    "plt.plot(x,f_XatAE(x),label=\"case=AE\")\n",
    "\n",
    "plt.scatter(X_NC, lung_flags_NC,label=\"point NC\")  \n",
    "plt.scatter(X_AE, lung_flags_AE,label=\"points AE\")\n",
    "\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67f408e7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "hide_input": false,
  "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.10.12"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
