mirror of
https://github.com/ION606/COGMOD-HWI.git
synced 2026-05-14 22:16:57 +00:00
229 lines
360 KiB
Plaintext
229 lines
360 KiB
Plaintext
|
|
{
|
||
|
|
"cells": [
|
||
|
|
{
|
||
|
|
"cell_type": "code",
|
||
|
|
"execution_count": null,
|
||
|
|
"metadata": {},
|
||
|
|
"outputs": [
|
||
|
|
{
|
||
|
|
"data": {
|
||
|
|
"image/png": "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
|
||
|
|
"text/plain": [
|
||
|
|
"<Figure size 600x400 with 1 Axes>"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"metadata": {},
|
||
|
|
"output_type": "display_data"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"source": [
|
||
|
|
"import numpy as np\n",
|
||
|
|
"import matplotlib.pyplot as plt\n",
|
||
|
|
"\n",
|
||
|
|
"SENSITIVITY = 0.95\n",
|
||
|
|
"SPECIFICITY = 0.95\n",
|
||
|
|
"\n",
|
||
|
|
"def posterior(prior, sensitivity, specificity):\n",
|
||
|
|
" return (sensitivity * prior) / (sensitivity * prior + (1 - specificity) * (1 - prior))\n",
|
||
|
|
"\n",
|
||
|
|
"priors = np.linspace(0, 1, 100)\n",
|
||
|
|
"posteriors = posterior(priors, SENSITIVITY, SPECIFICITY)\n",
|
||
|
|
"\n",
|
||
|
|
"plt.figure(figsize=(6, 4))\n",
|
||
|
|
"plt.plot(priors, posteriors)\n",
|
||
|
|
"plt.xlim(0, 1) \n",
|
||
|
|
"plt.ylim(0, 1)\n",
|
||
|
|
"plt.xlabel('Prior')\n",
|
||
|
|
"plt.ylabel('Posterior')\n",
|
||
|
|
"plt.show()\n",
|
||
|
|
"\n"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"cell_type": "code",
|
||
|
|
"execution_count": null,
|
||
|
|
"metadata": {},
|
||
|
|
"outputs": [
|
||
|
|
{
|
||
|
|
"data": {
|
||
|
|
"image/png": "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
|
||
|
|
"text/plain": [
|
||
|
|
"<Figure size 600x400 with 1 Axes>"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"metadata": {},
|
||
|
|
"output_type": "display_data"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"source": [
|
||
|
|
"import numpy as np\n",
|
||
|
|
"import matplotlib.pyplot as plt\n",
|
||
|
|
"\n",
|
||
|
|
"prior = 0.01\n",
|
||
|
|
"specificity = 0.90\n",
|
||
|
|
"\n",
|
||
|
|
"def posterior_prob(prior, sensitivity, specificity):\n",
|
||
|
|
" return (sensitivity * prior) / ((sensitivity * prior) + ((1 - specificity) * (1 - prior)))\n",
|
||
|
|
"\n",
|
||
|
|
"sensitivities = np.linspace(0, 1, 100)\n",
|
||
|
|
"posteriors = [posterior_prob(prior, sens, specificity) for sens in sensitivities]\n",
|
||
|
|
"\n",
|
||
|
|
"# Plot\n",
|
||
|
|
"plt.figure(figsize=(6, 4))\n",
|
||
|
|
"plt.plot(sensitivities, posteriors)\n",
|
||
|
|
"plt.title(f'Prior={prior}, Specificity={specificity}') \n",
|
||
|
|
"plt.xlabel('Test Sensitivity')\n",
|
||
|
|
"plt.ylabel('Posterior Probability Given a Positive Test')\n",
|
||
|
|
"plt.show()"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"cell_type": "code",
|
||
|
|
"execution_count": null,
|
||
|
|
"metadata": {},
|
||
|
|
"outputs": [
|
||
|
|
{
|
||
|
|
"data": {
|
||
|
|
"image/png": "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
|
||
|
|
"text/plain": [
|
||
|
|
"<Figure size 600x400 with 1 Axes>"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"metadata": {},
|
||
|
|
"output_type": "display_data"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"source": [
|
||
|
|
"import numpy as np\n",
|
||
|
|
"import matplotlib.pyplot as plt\n",
|
||
|
|
"\n",
|
||
|
|
"prior = 0.01\n",
|
||
|
|
"sensitivity = 0.95\n",
|
||
|
|
"\n",
|
||
|
|
"def posterior_prob(prior, sensitivity, specificity):\n",
|
||
|
|
" return (sensitivity * prior) / ((sensitivity * prior) + ((1 - specificity) * (1 - prior)))\n",
|
||
|
|
"\n",
|
||
|
|
"# Vary specificity from 0 to 1\n",
|
||
|
|
"specificities = np.linspace(0, 1, 100)\n",
|
||
|
|
"posteriors = [posterior_prob(prior, sensitivity, sp) for sp in specificities]\n",
|
||
|
|
"\n",
|
||
|
|
"# Plot\n",
|
||
|
|
"plt.figure(figsize=(6, 4))\n",
|
||
|
|
"plt.plot(specificities, posteriors) \n",
|
||
|
|
"plt.title(f'Posterior vs. Specificity (Prior={prior}, Sensitivity={sensitivity})')\n",
|
||
|
|
"plt.xlabel('Test Specificity')\n",
|
||
|
|
"plt.ylabel('Posterior Probability Given a Positive Test')\n",
|
||
|
|
"plt.show()"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"cell_type": "code",
|
||
|
|
"execution_count": null,
|
||
|
|
"metadata": {},
|
||
|
|
"outputs": [],
|
||
|
|
"source": [
|
||
|
|
"'''\n",
|
||
|
|
"As the disease becomes more common (higher prior), the posterior increases because a positive test is more believable.\n",
|
||
|
|
"\n",
|
||
|
|
"Increasing sensitivity (correctly detecting disease) lowers false negatives, raising the posterior.\n",
|
||
|
|
"\n",
|
||
|
|
"Increasing specificity (correctly identifying healthy individuals) lowers false positives, also raising the posterior.\n",
|
||
|
|
"\n",
|
||
|
|
"'''"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"cell_type": "code",
|
||
|
|
"execution_count": 18,
|
||
|
|
"metadata": {},
|
||
|
|
"outputs": [
|
||
|
|
{
|
||
|
|
"data": {
|
||
|
|
"image/png": "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
|
||
|
|
"text/plain": [
|
||
|
|
"<Figure size 1200x400 with 3 Axes>"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"metadata": {},
|
||
|
|
"output_type": "display_data"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"source": [
|
||
|
|
"import numpy as np\n",
|
||
|
|
"import matplotlib.pyplot as plt\n",
|
||
|
|
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||
|
|
"\n",
|
||
|
|
"def posterior_prob(prior, sens, spec, eps=1e-10):\n",
|
||
|
|
" denom = (sens * prior) + ((1 - spec) * (1 - prior))\n",
|
||
|
|
" return (sens * prior) / (denom + eps)\n",
|
||
|
|
"\n",
|
||
|
|
"# Define ranges\n",
|
||
|
|
"points = 25\n",
|
||
|
|
"priors = np.linspace(0, 1, points)\n",
|
||
|
|
"sens = np.linspace(0, 1, points)\n",
|
||
|
|
"spec = np.linspace(0, 1, points)\n",
|
||
|
|
"\n",
|
||
|
|
"fig = plt.figure(figsize=(12, 4))\n",
|
||
|
|
"\n",
|
||
|
|
"# Posterior vs. (prior, sensitivity), fixed specificity\n",
|
||
|
|
"SPEC_FIXED = 0.90\n",
|
||
|
|
"P, S = np.meshgrid(priors, sens)\n",
|
||
|
|
"Z1 = posterior_prob(P, S, SPEC_FIXED)\n",
|
||
|
|
"ax1 = fig.add_subplot(131, projection='3d')\n",
|
||
|
|
"surf1 = ax1.plot_surface(P, S, Z1)\n",
|
||
|
|
"ax1.set_title(f'Spec = {SPEC_FIXED}')\n",
|
||
|
|
"ax1.set_xlabel('Prior')\n",
|
||
|
|
"ax1.set_ylabel('Sensitivity')\n",
|
||
|
|
"ax1.set_zlabel('Posterior')\n",
|
||
|
|
"\n",
|
||
|
|
"# Posterior vs. (prior, specificity), fixed sensitivity\n",
|
||
|
|
"SENS_FIXED = 0.95\n",
|
||
|
|
"P2, Sp = np.meshgrid(priors, spec)\n",
|
||
|
|
"Z2 = posterior_prob(P2, SENS_FIXED, Sp)\n",
|
||
|
|
"ax2 = fig.add_subplot(132, projection='3d')\n",
|
||
|
|
"surf2 = ax2.plot_surface(P2, Sp, Z2)\n",
|
||
|
|
"ax2.set_title(f'Sens = {SENS_FIXED}')\n",
|
||
|
|
"ax2.set_xlabel('Prior')\n",
|
||
|
|
"ax2.set_ylabel('Specificity')\n",
|
||
|
|
"ax2.set_zlabel('Posterior')\n",
|
||
|
|
"\n",
|
||
|
|
"\n",
|
||
|
|
"# Posterior vs. (sensitivity, specificity), fixed prior\n",
|
||
|
|
"PRIOR_FIXED = 0.01\n",
|
||
|
|
"S3, Sp3 = np.meshgrid(sens, spec)\n",
|
||
|
|
"Z3 = posterior_prob(PRIOR_FIXED, S3, Sp3)\n",
|
||
|
|
"ax3 = fig.add_subplot(133, projection='3d')\n",
|
||
|
|
"surf3 = ax3.plot_surface(S3, Sp3, Z3)\n",
|
||
|
|
"ax3.set_title(f'Prior = {PRIOR_FIXED}')\n",
|
||
|
|
"ax3.set_xlabel('Sensitivity')\n",
|
||
|
|
"ax3.set_ylabel('Specificity')\n",
|
||
|
|
"ax3.set_zlabel('Posterior')\n",
|
||
|
|
"\n",
|
||
|
|
"plt.tight_layout()\n",
|
||
|
|
"plt.show()"
|
||
|
|
]
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"metadata": {
|
||
|
|
"kernelspec": {
|
||
|
|
"display_name": ".venv",
|
||
|
|
"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.12.3"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"nbformat": 4,
|
||
|
|
"nbformat_minor": 2
|
||
|
|
}
|