Compare to ANOVA and LMM: ROC curve

import numpy as np

from bayes_window import model_comparison, BayesWindow
from bayes_window.generative_models import generate_fake_lfp

Data plot

  • Intercept varies across mice, but not slope

    • (Same response, different baseline)

  • We vary the number of trials and then test raw or log-transformed data

df, df_monster, index_cols, firing_rates = generate_fake_lfp(n_trials=70, mouse_response_slope=10)

BayesWindow(df, y='Power', treatment='stim', group='mouse', detail='i_trial').chart_data_box_detail.display()
BayesWindow(df, y='Log power', treatment='stim', group='mouse', detail='i_trial').chart_data_box_detail.display()

ROC and CM, original scale

# NBVAL_SKIP
# Note: Only works with single ys and single true_slopes
res = model_comparison.run_conditions(true_slopes=np.hstack([np.zeros(15),
                                                             np.tile(10, 15)]),
                                      #                                                              np.tile(np.linspace(20, 40, 3), 15)]),
                                      n_trials=np.linspace(10, 70, 5).astype(int),
                                      #                                       trial_baseline_randomness=np.linspace(.2, 11, 3),
                                      ys=('Power',),
                                      parallel=True)
  0%|          | 0/450 [00:00<?, ?it/s]
  3%|▎         | 12/450 [00:00<00:09, 46.56it/s]
  3%|▎         | 12/450 [00:19<00:09, 46.56it/s]
  5%|▌         | 24/450 [00:26<09:15,  1.30s/it]
  8%|▊         | 36/450 [00:53<11:56,  1.73s/it]
 11%|█         | 48/450 [01:23<13:38,  2.04s/it]
 13%|█▎        | 60/450 [01:50<13:42,  2.11s/it]
 16%|█▌        | 72/450 [02:25<15:04,  2.39s/it]
 19%|█▊        | 84/450 [02:58<15:16,  2.50s/it]
 21%|██▏       | 96/450 [03:24<14:03,  2.38s/it]
 24%|██▍       | 108/450 [03:57<14:20,  2.51s/it]
 27%|██▋       | 120/450 [04:28<13:51,  2.52s/it]
 29%|██▉       | 132/450 [05:03<13:59,  2.64s/it]
 32%|███▏      | 144/450 [05:38<13:57,  2.74s/it]
 35%|███▍      | 156/450 [06:01<12:13,  2.50s/it]
 37%|███▋      | 168/450 [06:39<12:37,  2.69s/it]
 40%|████      | 180/450 [07:06<11:32,  2.56s/it]
 43%|████▎     | 192/450 [07:42<11:32,  2.68s/it]
 45%|████▌     | 204/450 [08:14<10:57,  2.67s/it]
 48%|████▊     | 216/450 [08:38<09:42,  2.49s/it]
 51%|█████     | 228/450 [09:08<09:13,  2.49s/it]
 53%|█████▎    | 240/450 [09:38<08:40,  2.48s/it]
 56%|█████▌    | 252/450 [10:10<08:21,  2.53s/it]
 59%|█████▊    | 264/450 [10:38<07:43,  2.49s/it]
 61%|██████▏   | 276/450 [11:14<07:36,  2.62s/it]
 64%|██████▍   | 288/450 [11:45<07:03,  2.61s/it]
 67%|██████▋   | 300/450 [12:12<06:15,  2.51s/it]
 69%|██████▉   | 312/450 [12:41<05:42,  2.48s/it]
 72%|███████▏  | 324/450 [13:14<05:23,  2.57s/it]
 75%|███████▍  | 336/450 [13:39<04:35,  2.41s/it]
 77%|███████▋  | 348/450 [14:10<04:13,  2.48s/it]
 80%|████████  | 360/450 [14:37<03:36,  2.40s/it]
 83%|████████▎ | 372/450 [15:12<03:19,  2.56s/it]
 85%|████████▌ | 384/450 [15:43<02:49,  2.57s/it]
 88%|████████▊ | 396/450 [16:10<02:13,  2.47s/it]
 91%|█████████ | 408/450 [16:41<01:45,  2.50s/it]
 93%|█████████▎| 420/450 [17:09<01:13,  2.45s/it]
 96%|█████████▌| 432/450 [17:40<00:44,  2.49s/it]
 99%|█████████▊| 444/450 [18:09<00:14,  2.47s/it]
100%|██████████| 450/450 [18:09<00:00,  2.42s/it]

Confusion matrix

# NBVAL_SKIP
model_comparison.plot_confusion(
    model_comparison.make_confusion_matrix(res[res['y'] == 'Power'], ('method', 'y', 'randomness', 'n_trials')
                                           )).properties(width=140).facet(row='method', column='n_trials')

ROC curve

df = model_comparison.make_roc_auc(res, binary=False, groups=('method', 'y', 'n_trials'))

bars, roc = model_comparison.plot_roc(df)
bars.facet(column='n_trials', row='y').properties().display()
roc.facet(column='n_trials', row='y').properties()
# NBVAL_SKIP

Log-transformed

reslog = model_comparison.run_conditions(true_slopes=np.hstack([np.zeros(15),
                                                                np.tile(10, 15)]),
                                         #                                                              np.tile(np.linspace(20, 40, 3), 15)]),
                                         n_trials=np.linspace(10, 70, 5).astype(int),
                                         #                                       trial_baseline_randomness=np.linspace(.2, 11, 3),
                                         ys=('Log power',),
                                         parallel=True)
# NBVAL_SKIP
  0%|          | 0/450 [00:00<?, ?it/s]
  5%|▌         | 24/450 [00:20<06:04,  1.17it/s]
  8%|▊         | 36/450 [00:50<10:42,  1.55s/it]
 11%|█         | 48/450 [01:32<15:12,  2.27s/it]
 13%|█▎        | 60/450 [02:09<16:34,  2.55s/it]
 16%|█▌        | 72/450 [02:41<16:15,  2.58s/it]
 19%|█▊        | 84/450 [03:24<17:45,  2.91s/it]
 21%|██▏       | 96/450 [03:55<16:36,  2.82s/it]
 24%|██▍       | 108/450 [04:41<17:48,  3.12s/it]
 27%|██▋       | 120/450 [05:13<16:20,  2.97s/it]
 29%|██▉       | 132/450 [05:51<16:08,  3.05s/it]
 32%|███▏      | 144/450 [06:28<15:38,  3.07s/it]
 35%|███▍      | 156/450 [07:03<14:44,  3.01s/it]
 37%|███▋      | 168/450 [07:43<14:34,  3.10s/it]
 40%|████      | 180/450 [08:15<13:24,  2.98s/it]
 43%|████▎     | 192/450 [08:53<12:59,  3.02s/it]
 45%|████▌     | 204/450 [09:33<12:47,  3.12s/it]
 48%|████▊     | 216/450 [10:06<11:48,  3.03s/it]
 51%|█████     | 228/450 [10:44<11:18,  3.06s/it]
 53%|█████▎    | 240/450 [11:20<10:36,  3.03s/it]
 56%|█████▌    | 252/450 [11:59<10:13,  3.10s/it]
 59%|█████▊    | 264/450 [12:44<10:13,  3.30s/it]
 61%|██████▏   | 276/450 [13:12<08:42,  3.00s/it]
 64%|██████▍   | 288/450 [13:52<08:25,  3.12s/it]
 67%|██████▋   | 300/450 [14:27<07:38,  3.06s/it]
 69%|██████▉   | 312/450 [15:10<07:23,  3.21s/it]
 72%|███████▏  | 324/450 [15:46<06:35,  3.14s/it]
 75%|███████▍  | 336/450 [16:20<05:47,  3.04s/it]
 77%|███████▋  | 348/450 [16:59<05:18,  3.12s/it]
 80%|████████  | 360/450 [17:35<04:37,  3.08s/it]
 83%|████████▎ | 372/450 [18:14<04:04,  3.14s/it]
 85%|████████▌ | 384/450 [18:54<03:29,  3.18s/it]
 88%|████████▊ | 396/450 [19:27<02:44,  3.05s/it]
 91%|█████████ | 408/450 [20:07<02:11,  3.13s/it]
 93%|█████████▎| 420/450 [20:44<01:33,  3.11s/it]
 96%|█████████▌| 432/450 [21:22<00:56,  3.15s/it]
 99%|█████████▊| 444/450 [22:05<00:19,  3.28s/it]
100%|██████████| 450/450 [22:05<00:00,  2.95s/it]

Confusion matrix

model_comparison.plot_confusion(
    model_comparison.make_confusion_matrix(reslog, ('method', 'y', 'randomness', 'n_trials')
                                           )).properties(width=140).facet(row='method', column='n_trials')
# NBVAL_SKIP

ROC curve

df = model_comparison.make_roc_auc(reslog, binary=False, groups=('method', 'y', 'n_trials'))

bars, roc = model_comparison.plot_roc(df)
bars.facet(column='n_trials', row='y').properties().display()
roc.facet(column='n_trials', row='y').properties()
# NBVAL_SKIP