{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Approach 1a: Basic frame differencing\n",
    "For this most basic approach, we compare each motion image $M$ to the closest lapse image $L$ and take the\n",
    "1. mean absolute pixel-wise difference $ \\frac{1}{xy} \\sum_{x,y} | M_{x,y} - L_{x,y} | $\n",
    "2. mean squared pixel-wise difference $ \\frac{1}{xy} \\sum_{x,y} (M_{x,y} - L_{x,y})^2 $\n",
    "M and L are both grayscale.\n",
    "\n",
    "**Reasoning:** We assume that anomalous images highly differ from the closest lapse image in a significant amount of pixels while normal images only have low pixel differences.\n",
    "\n",
    "### Suspected problems\n",
    "- **Noise** (we scale the images down for performance reasons which also reduces noise a bit)\n",
    "- **Small object movements** that are not of interest (such as leaves, dust particles, etc.)\n",
    "- Very sensitive to **camera movement** (which seems to happen a lot in the dataset)\n",
    "- Since we eliminate the **color information**, a deer might look very much like a forest."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2 sessions\n",
      "Session 'Beaver_01' at folder: ./ResizedSessions_NoBackup/VIELAAS_Spring_Session01-VIELAAS_Beaver_01\n",
      "Loaded scans.\n"
     ]
    }
   ],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "from tqdm.notebook import tqdm\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from skimage.color import rgb2gray\n",
    "from tqdm import tqdm\n",
    "\n",
    "from py.PlotUtils import plot_roc_curve, get_percentiles\n",
    "from py.Dataset import Dataset\n",
    "from py.Session import MotionImage\n",
    "from py.ImageUtils import display_images, is_daytime\n",
    "from py.Labels import LABELS\n",
    "from py.ImageClassifier import AbstractImageClassifier\n",
    "\n",
    "DIR = './ResizedSessions_NoBackup' # dataset directory\n",
    "\n",
    "ds = Dataset(DIR)\n",
    "session = ds.create_session(\"beaver_01\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Experiment 1: Basic classifier\n",
    "The proposed classifier computes the following features\n",
    "- mean of absolute pixel-wise difference _absmean_\n",
    "- variance of absolute pixel-wise difference _absvar_\n",
    "- mean of squared pixel-wise difference _sqmean_\n",
    "- var of squared pixel-wise difference _sqvar_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def normalize(comp_arr, motion_arr):\n",
    "    # normalize comp_arr and transform motion_arr identically\n",
    "    mean, std = np.mean(comp_arr), np.std(comp_arr)\n",
    "    motion_arr = (motion_arr - mean) / std\n",
    "    comp_arr = (comp_arr - mean) / std\n",
    "    return comp_arr, motion_arr\n",
    "\n",
    "def normalize_img(img):\n",
    "    return (img - np.mean(img)) / np.std(img)\n",
    "\n",
    "class FrameDiffClassifier(AbstractImageClassifier):\n",
    "    def evaluate(self, motion_img: MotionImage, display=False):\n",
    "        before_img, after_img, rel = motion_img.get_closest_lapse_images()\n",
    "        comp_img = before_img if rel <= 0.5 else after_img\n",
    "        motion_arr = motion_img.read(gray=False)\n",
    "        comp_arr = comp_img.read(gray=False)\n",
    "        motion_daytime = is_daytime(motion_arr)\n",
    "\n",
    "        # don't compare daytime with nighttime images\n",
    "        if motion_daytime != is_daytime(comp_arr):\n",
    "            # choose the other closest lapse image\n",
    "            comp_img = after_img if rel <= 0.5 else before_img\n",
    "            comp_arr = comp_img.read(gray=False)\n",
    "            assert motion_daytime == is_daytime(comp_arr)\n",
    "            # if this assertion fails, a motion image was captured at daytime between two nighttime lapse images or the other way around\n",
    "\n",
    "        # convert to gray\n",
    "        motion_arr = rgb2gray(motion_arr)\n",
    "        comp_arr = rgb2gray(comp_arr)\n",
    "\n",
    "        # comp_arr, motion_arr = normalize(comp_arr, motion_arr)\n",
    "        comp_arr, motion_arr = normalize_img(comp_arr), normalize_img(motion_arr)\n",
    "\n",
    "        absdiff = abs(motion_arr - comp_arr)\n",
    "        sqdiff = (motion_arr - comp_arr) ** 2\n",
    "        absmean = np.average(absdiff)\n",
    "        absstd = np.std(absdiff)\n",
    "        sqmean = np.average(sqdiff)\n",
    "        sqstd = np.std(sqdiff)\n",
    "\n",
    "        if display:\n",
    "            display_images([motion_arr, comp_arr, absdiff, sqdiff], [\"Motion image\", \"Closest lapse image\", f\"abs mean = {absmean}, std = {absstd}\", f\"sq mean = {sqmean}, std = {sqstd}\"], cmap=\"gray\")\n",
    "\n",
    "        return absmean, absstd, sqmean, sqstd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 1115820 characters]",
      "text/plain": [
       "<Figure size 1152x720 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(0.5830181244945464, 0.555556827887569, 0.6485535225016364, 1.2471391565015033)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = session.get_random_motion_image(day_only=True)\n",
    "classifier = FrameDiffClassifier()\n",
    "classifier.evaluate(img, display=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The anomalous object is usually clearly visible in the difference image but there are still a lot of unwanted artefacts around it (possibly because of small object movement and noise)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 695/695 [00:59<00:00, 11.64it/s]\n"
     ]
    }
   ],
   "source": [
    "def generate_test_scores(classifier):\n",
    "    normal_scores = []\n",
    "    anomalous_scores = []\n",
    "\n",
    "    for img in tqdm(list(session.generate_motion_images())):\n",
    "        img_nr = int(img.filename[10:-4])\n",
    "        if img_nr > LABELS[session.name][\"max\"]:\n",
    "            continue\n",
    "        score = classifier.evaluate(img)\n",
    "        if img_nr in LABELS[session.name][\"normal\"]:\n",
    "            normal_scores.append(score)\n",
    "        else:\n",
    "            anomalous_scores.append(score)\n",
    "    return normal_scores, anomalous_scores\n",
    "\n",
    "\n",
    "classifier = FrameDiffClassifier()\n",
    "normal_scores, anomalous_scores = generate_test_scores(classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45756 characters]",
      "text/plain": [
       "<Figure size 1080x576 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot(i1, i2, normal_scores, anomalous_scores, scale=\"log\"):\n",
    "    titles = [\"abs mean\", \"abs var\", \"sq mean\", \"sq var\"]\n",
    "    plt.scatter([ar[i1] for ar in anomalous_scores], [ar[i2] for ar in anomalous_scores], color=\"red\", label=\"anomalous\", marker=\".\")\n",
    "    plt.scatter([ar[i1] for ar in normal_scores], [ar[i2] for ar in normal_scores], color=\"blue\", label=\"normal\", marker=\".\")\n",
    "    plt.xlabel(titles[i1])\n",
    "    plt.ylabel(titles[i2])\n",
    "    plt.xscale(scale)\n",
    "    plt.yscale(scale)\n",
    "    plt.legend()\n",
    "    \n",
    "plt.figure(figsize=(15, 8))\n",
    "plt.subplot(1, 2, 1)\n",
    "plot(0, 1, normal_scores, anomalous_scores)\n",
    "plt.subplot(1, 2, 2)\n",
    "plot(2, 3, normal_scores, anomalous_scores)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(695, 4)\n",
      "(695,)\n"
     ]
    }
   ],
   "source": [
    "y_anom = np.array(anomalous_scores)\n",
    "assert y_anom.shape[1] == 4\n",
    "\n",
    "y_norm = np.array(normal_scores)\n",
    "assert y_norm.shape[1] == 4\n",
    "\n",
    "X = np.concatenate([y_norm, y_anom])\n",
    "print(X.shape)\n",
    "y = np.concatenate([-np.ones((y_norm.shape[0])), np.ones((y_anom.shape[0]))])\n",
    "print(y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9 percentile : TPR = 0.9227, FPR = 0.5811 <-> TNR = 0.4189 @ thresh 0.11559366582259728\n",
      "0.95 percentile : TPR = 0.9533, FPR = 0.6486 <-> TNR = 0.3514 @ thresh 0.10078405586237728\n",
      "0.98 percentile : TPR = 0.9807, FPR = 0.7838 <-> TNR = 0.2162 @ thresh 0.08912281297293448\n",
      "0.99 percentile : TPR = 0.9968, FPR = 0.8378 <-> TNR = 0.1622 @ thresh 0.08113976314506045\n",
      "absmean auc=0.7307960134047091\n",
      "0.9 percentile : TPR = 0.9195, FPR = 0.5135 <-> TNR = 0.4865 @ thresh 0.1597904067052574\n",
      "0.95 percentile : TPR = 0.9501, FPR = 0.5811 <-> TNR = 0.4189 @ thresh 0.12430776868553675\n",
      "0.98 percentile : TPR = 0.9871, FPR = 0.7432 <-> TNR = 0.2568 @ thresh 0.09134296262895039\n",
      "0.99 percentile : TPR = 0.9903, FPR = 0.7568 <-> TNR = 0.2432 @ thresh 0.08903542053416316\n",
      "absvar auc=0.7414370892631762\n",
      "0.9 percentile : TPR = 0.9452, FPR = 0.5811 <-> TNR = 0.4189 @ thresh 0.02817008267638741\n",
      "0.95 percentile : TPR = 0.9581, FPR = 0.5946 <-> TNR = 0.4054 @ thresh 0.024229766266360083\n",
      "0.98 percentile : TPR = 0.9968, FPR = 0.7838 <-> TNR = 0.2162 @ thresh 0.014011222844325977\n",
      "0.99 percentile : TPR = 0.9968, FPR = 0.7838 <-> TNR = 0.2162 @ thresh 0.014011222844325977\n",
      "sqmean auc=0.7336249292771032\n",
      "0.9 percentile : TPR = 0.9581, FPR = 0.5811 <-> TNR = 0.4189 @ thresh 0.10496299471989833\n",
      "0.95 percentile : TPR = 0.9581, FPR = 0.5811 <-> TNR = 0.4189 @ thresh 0.10496299471989833\n",
      "0.98 percentile : TPR = 0.9984, FPR = 0.7432 <-> TNR = 0.2568 @ thresh 0.04146565095773032\n",
      "0.99 percentile : TPR = 0.9984, FPR = 0.7432 <-> TNR = 0.2568 @ thresh 0.04146565095773032\n",
      "sqvar auc=0.729577403490447\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 23972 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 23892 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 23788 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 23608 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "vals = [\"absmean\", \"absvar\", \"sqmean\", \"sqvar\"]\n",
    "for i in range(4):\n",
    "    fpr, tpr, thresholds, auc_score = plot_roc_curve(y, X[:,i], f\"Basic frame differencing ({vals[i]})\", savefile=f\"plots/approach1a/roc_curves/{session.name}_{vals[i]}\", show=False)\n",
    "    get_percentiles(fpr, tpr, thresholds)\n",
    "    print(f\"{vals[i]} auc={auc_score}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Experiment 2: Add a Gaussian filter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from py.ImageClassifier import AbstractImageClassifier\n",
    "from scipy import ndimage\n",
    "\n",
    "class GaussianFrameDiffClassifier(AbstractImageClassifier):\n",
    "    def __init__(self, sigma: int):\n",
    "        self.sigma = sigma\n",
    "    \n",
    "    def evaluate(self, motion_img: MotionImage, display=False):\n",
    "        before_img, after_img, rel = motion_img.get_closest_lapse_images()\n",
    "        comp_img = before_img if rel <= 0.5 else after_img\n",
    "        motion_arr = motion_img.read(gray=False)\n",
    "        comp_arr = comp_img.read(gray=False)\n",
    "        motion_daytime = is_daytime(motion_arr)\n",
    "\n",
    "        # don't compare daytime with nighttime images\n",
    "        if motion_daytime != is_daytime(comp_arr):\n",
    "            # choose the other closest lapse image\n",
    "            comp_img = after_img if rel <= 0.5 else before_img\n",
    "            comp_arr = comp_img.read(gray=False)\n",
    "            assert motion_daytime == is_daytime(comp_arr)\n",
    "            # if this assertion fails, a motion image was captured at daytime between two nighttime lapse images or the other way around\n",
    "\n",
    "        # convert to gray\n",
    "        motion_arr = rgb2gray(motion_arr)\n",
    "        comp_arr = rgb2gray(comp_arr)\n",
    "\n",
    "        comp_arr, motion_arr = normalize_img(comp_arr), normalize_img(motion_arr)\n",
    "\n",
    "        motion_arrg = ndimage.gaussian_filter(motion_arr, sigma=self.sigma)\n",
    "        comp_arrg = ndimage.gaussian_filter(comp_arr, sigma=self.sigma)\n",
    "\n",
    "        absdiff = abs(motion_arrg - comp_arrg)\n",
    "        sqdiff = (motion_arrg - comp_arrg) ** 2\n",
    "        absmean = np.average(absdiff)\n",
    "        absvar = np.var(absdiff)\n",
    "        sqmean = np.average(sqdiff)\n",
    "        sqvar = np.var(sqdiff)\n",
    "\n",
    "        if display:\n",
    "            display_images([motion_arr, comp_arr, absdiff, sqdiff], [\"Motion image\", \"Closest lapse image\", f\"abs mean = {absmean}, var = {absvar}\", f\"sq mean = {sqmean}, var = {sqvar}\"], cmap=\"gray\")\n",
    "\n",
    "        return absmean, absvar, sqmean, sqvar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 1191348 characters]",
      "text/plain": [
       "<Figure size 1152x720 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 889428 characters]",
      "text/plain": [
       "<Figure size 1152x720 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(0.17548586593139567,\n",
       " 0.06852500246438885,\n",
       " 0.09932029160608065,\n",
       " 0.19114494975722832)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = session.get_random_motion_image(day_only=True)\n",
    "classifier = FrameDiffClassifier()\n",
    "classifier.evaluate(img, display=True)\n",
    "classifier2 = GaussianFrameDiffClassifier(sigma=2)\n",
    "classifier2.evaluate(img, display=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 695/695 [01:25<00:00,  8.09it/s]\n"
     ]
    }
   ],
   "source": [
    "classifier = GaussianFrameDiffClassifier(sigma=2)\n",
    "normal_scores_g, anomalous_scores_g = generate_test_scores(classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 695/695 [01:33<00:00,  7.45it/s]\n"
     ]
    }
   ],
   "source": [
    "classifier = GaussianFrameDiffClassifier(sigma=4)\n",
    "normal_scores_g2, anomalous_scores_g2 = generate_test_scores(classifier)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 155104 characters]",
      "text/plain": [
       "<Figure size 1800x1800 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "scale = \"log\"\n",
    "plt.figure(figsize=(25, 25))\n",
    "plt.subplot(3, 2, 1)\n",
    "plot(0, 1, normal_scores, anomalous_scores, scale=scale)\n",
    "plt.subplot(3, 2, 2)\n",
    "plot(2, 3, normal_scores, anomalous_scores, scale=scale)\n",
    "plt.subplot(3, 2, 3)\n",
    "plot(0, 1, normal_scores_g, anomalous_scores_g, scale=scale)\n",
    "plt.subplot(3, 2, 4)\n",
    "plot(2, 3, normal_scores_g, anomalous_scores_g, scale=scale)\n",
    "plt.subplot(3, 2, 5)\n",
    "plot(0, 1, normal_scores_g2, anomalous_scores_g2, scale=scale)\n",
    "plt.subplot(3, 2, 6)\n",
    "plot(2, 3, normal_scores_g2, anomalous_scores_g2, scale=scale)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(695, 4)\n",
      "(695,)\n"
     ]
    }
   ],
   "source": [
    "y_anom = np.array(anomalous_scores_g2)\n",
    "assert y_anom.shape[1] == 4\n",
    "\n",
    "y_norm = np.array(normal_scores_g2)\n",
    "assert y_norm.shape[1] == 4\n",
    "\n",
    "X = np.concatenate([y_norm, y_anom])\n",
    "print(X.shape)\n",
    "y = np.concatenate([-np.ones((y_norm.shape[0])), np.ones((y_anom.shape[0]))])\n",
    "print(y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "absmean sigma=2 auc=0.8293946120033077\n",
      "0.9 percentile : TPR = 0.9002, FPR = 0.3649 <-> TNR = 0.6351 @ thresh 0.07249433566897984\n",
      "0.95 percentile : TPR = 0.9646, FPR = 0.5541 <-> TNR = 0.4459 @ thresh 0.03261906593919228\n",
      "0.98 percentile : TPR = 0.9887, FPR = 0.6892 <-> TNR = 0.3108 @ thresh 0.021977000274880486\n",
      "0.99 percentile : TPR = 0.9919, FPR = 0.7027 <-> TNR = 0.2973 @ thresh 0.01988756449288908\n",
      "absvar sigma=2 auc=0.9067545806676243\n",
      "0.9 percentile : TPR = 0.9211, FPR = 0.3378 <-> TNR = 0.6622 @ thresh 0.009052023616784883\n",
      "0.95 percentile : TPR = 0.9775, FPR = 0.4189 <-> TNR = 0.5811 @ thresh 0.00428247310101172\n",
      "0.98 percentile : TPR = 0.9871, FPR = 0.4595 <-> TNR = 0.5405 @ thresh 0.00338826930319687\n",
      "0.99 percentile : TPR = 0.9936, FPR = 0.4730 <-> TNR = 0.5270 @ thresh 0.0031191044471881387\n",
      "sqmean sigma=2 auc=0.8777037907472691\n",
      "0.9 percentile : TPR = 0.9179, FPR = 0.3514 <-> TNR = 0.6486 @ thresh 0.013134956441145457\n",
      "0.95 percentile : TPR = 0.9517, FPR = 0.3919 <-> TNR = 0.6081 @ thresh 0.009071263120002648\n",
      "0.98 percentile : TPR = 0.9807, FPR = 0.5541 <-> TNR = 0.4459 @ thresh 0.004837652796850888\n",
      "0.99 percentile : TPR = 0.9952, FPR = 0.5676 <-> TNR = 0.4324 @ thresh 0.0027703968855825266\n",
      "sqvar sigma=2 auc=0.9155677416546982\n",
      "0.9 percentile : TPR = 0.9147, FPR = 0.2027 <-> TNR = 0.7973 @ thresh 0.0047686452078300684\n",
      "0.95 percentile : TPR = 0.9501, FPR = 0.3514 <-> TNR = 0.6486 @ thresh 0.0021427173670522394\n",
      "0.98 percentile : TPR = 0.9968, FPR = 0.4324 <-> TNR = 0.5676 @ thresh 0.0005008172914661139\n",
      "0.99 percentile : TPR = 0.9968, FPR = 0.4324 <-> TNR = 0.5676 @ thresh 0.0005008172914661139\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 24548 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24352 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24220 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24224 characters]",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sigma = 2\n",
    "vals = [\"absmean\", \"absvar\", \"sqmean\", \"sqvar\"]\n",
    "for i in range(4):\n",
    "    fpr, tpr, thresholds, auc_score = plot_roc_curve(y, X[:,i], f\"Basic frame differencing ({vals[i]}, sigma=2)\", savefile=f\"plots/approach1a/roc_curves/{session.name}_{vals[i]}_sigma{sigma}\", show=False)\n",
    "    print(f\"{vals[i]} sigma={sigma} auc={auc_score}\")\n",
    "    get_percentiles(fpr, tpr, thresholds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
  },
  "kernelspec": {
   "display_name": "Python 3.6.9 64-bit",
   "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.6.9"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
