AIC and likelihood ratio model comparison

There are many approaches to comparing models and evaluating relative goodness-of-fit. The FitGrid[time, channe] query mechanism is designed to streamline the computations for whatever approach is deemed appropriate for the research question at hand..

The AIC example demonstrates the fitgrid.utils.summarize function, a convenience wrapper that fits a list of models and returns key summary information for each as an indexed data frame. The summary may be passed to a function for visualizing the AIC \(\mathsf{\Delta_{min}}\) model comparison ([BurAnd2004]) as shown, or processed by custom user routines as needed.

For cases where the summary information is insufficient, the likelihood ratio example illustrates how to compute and visualize a model comparison measure derived from the original fitted grids. Other measures may be computed in a similar manner.

Prepare sample data

import pandas as pd
from matplotlib import pyplot as plt
import fitgrid as fg
from fitgrid import DATA_DIR, sample_data

sample_data.get_file("sub000p3.ms1500.epochs.feather")
p3_epochs_df = pd.read_feather(DATA_DIR / "sub000p3.ms1500.epochs.feather")

# drop calibration pulses for these examples
p3_epochs_df = p3_epochs_df.query("stim != 'cal'")

# look up the data QC flags and select the good epochs
good_epochs = p3_epochs_df.query("match_time == 0 and log_flags == 0")[
    "epoch_id"
]
p3_epochs_df = p3_epochs_df.query("epoch_id in @good_epochs")

# rename the time stamp column
p3_epochs_df.rename(columns={"match_time": "time_ms"}, inplace=True)

# select columns of interest for modeling
indices = ["epoch_id", "time_ms"]
predictors = ["stim", "tone"]  # categorical with 2 levels: standard, target
channels = ["MiPf", "MiCe", "MiPa", "MiOc"]  # midline electrodes
p3_epochs_df = p3_epochs_df[indices + predictors + channels]

# set the epoch and time column index for fg.Epochs
p3_epochs_df.set_index(["epoch_id", "time_ms"], inplace=True)

# "baseline", i.e., center each epoch on the 200 ms pre-stimulus interval
centered = []
for epoch_id, vals in p3_epochs_df.groupby("epoch_id"):
    centered.append(
        vals[channels]
        - vals[channels].query("time_ms >= -200 and time_ms < 0").mean()
    )
p3_epochs_df[channels] = pd.concat(centered)

# slice epochs down to a shorter interval
p3_epochs_df.query("time_ms >= -200 and time_ms <= 600", inplace=True)
p3_epochs_df
stim tone MiPf MiCe MiPa MiOc
epoch_id time_ms
0 -200 target hi -0.380001 20.450624 29.704453 21.073549
-196 target hi 0.119999 19.700624 28.266953 17.432924
-192 target hi -3.880001 11.106874 18.485703 11.112612
-188 target hi -1.380001 11.106874 14.891953 6.261050
-184 target hi 3.119999 9.075624 9.641953 3.343081
... ... ... ... ... ... ... ...
391 584 standard hi -27.759998 -19.758007 -14.340283 -3.182412
588 standard hi -27.759998 -24.312695 -23.644970 -8.283975
592 standard hi -19.259998 -13.181836 -14.102002 2.649619
596 standard hi -19.259998 -13.687696 -15.293408 -0.510537
600 standard hi -22.259998 -12.423047 -12.670362 -1.239053

67134 rows × 6 columns



Ingest as fitgrid.Epochs

p3_epochs_fg = fg.epochs_from_dataframe(
    p3_epochs_df, epoch_id="epoch_id", time="time_ms", channels=channels
)

Model summaries

The fitgrid.utils.summarize function is a convenience wrapper that fits a list of models and collects a few key summary measures into a single dataframe indexed by model, beta estimate, and the measure. It supports OLS and LME model fitting and the summaries are returned are in the same format.

This experimental design is a fully crossed 2 (stim: standard, target) \(\times\) 2 (tone: hi, lo). The predictors are treatment coded (patsy default).

Here is a stack of 5 models to summarize and compare:

rhss_T = [
    "1 + stim + tone + stim:tone",  # long form of "stim * tone"
    "1 + stim + tone",
    "1 + stim",
    "1 + tone",
    "1",
]
from fitgrid.utils.summary import summarize

lm_summary_T = summarize(
    p3_epochs_fg, modeler="lm", RHS=rhss_T, LHS=channels, parallel=False
)
lm_summary_T

Out:

  0%|          | 0/201 [00:00<?, ?it/s]
  2%|2         | 5/201 [00:00<00:04, 40.87it/s]
  5%|4         | 10/201 [00:00<00:04, 42.29it/s]
  7%|7         | 15/201 [00:00<00:04, 41.51it/s]
 10%|9         | 20/201 [00:00<00:04, 42.35it/s]
 12%|#2        | 25/201 [00:00<00:04, 42.80it/s]
 15%|#4        | 30/201 [00:00<00:03, 43.05it/s]
 17%|#7        | 35/201 [00:00<00:03, 43.38it/s]
 20%|#9        | 40/201 [00:00<00:03, 43.44it/s]
 22%|##2       | 45/201 [00:01<00:03, 43.49it/s]
 25%|##4       | 50/201 [00:01<00:03, 43.47it/s]
 27%|##7       | 55/201 [00:01<00:03, 43.51it/s]
 30%|##9       | 60/201 [00:01<00:03, 43.54it/s]
 32%|###2      | 65/201 [00:01<00:03, 43.68it/s]
 35%|###4      | 70/201 [00:01<00:02, 43.72it/s]
 37%|###7      | 75/201 [00:01<00:02, 43.78it/s]
 40%|###9      | 80/201 [00:01<00:02, 43.72it/s]
 42%|####2     | 85/201 [00:01<00:02, 43.83it/s]
 45%|####4     | 90/201 [00:02<00:02, 43.82it/s]
 47%|####7     | 95/201 [00:02<00:02, 43.89it/s]
 50%|####9     | 100/201 [00:02<00:02, 43.82it/s]
 52%|#####2    | 105/201 [00:02<00:02, 43.82it/s]
 55%|#####4    | 110/201 [00:02<00:02, 43.56it/s]
 57%|#####7    | 115/201 [00:02<00:01, 43.65it/s]
 60%|#####9    | 120/201 [00:02<00:01, 43.59it/s]
 62%|######2   | 125/201 [00:02<00:01, 43.71it/s]
 65%|######4   | 130/201 [00:02<00:01, 43.70it/s]
 67%|######7   | 135/201 [00:03<00:01, 43.74it/s]
 70%|######9   | 140/201 [00:03<00:01, 43.70it/s]
 72%|#######2  | 145/201 [00:03<00:01, 43.71it/s]
 75%|#######4  | 150/201 [00:03<00:01, 43.64it/s]
 77%|#######7  | 155/201 [00:03<00:01, 43.71it/s]
 80%|#######9  | 160/201 [00:03<00:00, 43.68it/s]
 82%|########2 | 165/201 [00:03<00:00, 43.74it/s]
 85%|########4 | 170/201 [00:03<00:00, 43.69it/s]
 87%|########7 | 175/201 [00:04<00:00, 43.76it/s]
 90%|########9 | 180/201 [00:04<00:00, 43.72it/s]
 92%|#########2| 185/201 [00:04<00:00, 43.82it/s]
 95%|#########4| 190/201 [00:04<00:00, 43.67it/s]
 97%|#########7| 195/201 [00:04<00:00, 43.67it/s]
100%|#########9| 200/201 [00:04<00:00, 43.60it/s]
100%|##########| 201/201 [00:04<00:00, 43.53it/s]

  0%|          | 0/201 [00:00<?, ?it/s]
  2%|2         | 5/201 [00:00<00:04, 42.79it/s]
  5%|4         | 10/201 [00:00<00:04, 44.52it/s]
  7%|7         | 15/201 [00:00<00:04, 45.03it/s]
 10%|9         | 20/201 [00:00<00:04, 45.21it/s]
 12%|#2        | 25/201 [00:00<00:03, 45.64it/s]
 15%|#4        | 30/201 [00:00<00:03, 45.72it/s]
 17%|#7        | 35/201 [00:00<00:03, 45.94it/s]
 20%|#9        | 40/201 [00:00<00:03, 45.79it/s]
 22%|##2       | 45/201 [00:00<00:03, 45.91it/s]
 25%|##4       | 50/201 [00:01<00:03, 45.98it/s]
 27%|##7       | 55/201 [00:01<00:03, 45.99it/s]
 30%|##9       | 60/201 [00:01<00:03, 46.08it/s]
 32%|###2      | 65/201 [00:01<00:02, 46.12it/s]
 35%|###4      | 70/201 [00:01<00:02, 46.20it/s]
 37%|###7      | 75/201 [00:01<00:02, 46.15it/s]
 40%|###9      | 80/201 [00:01<00:02, 46.19it/s]
 42%|####2     | 85/201 [00:01<00:02, 46.10it/s]
 45%|####4     | 90/201 [00:01<00:02, 46.12it/s]
 47%|####7     | 95/201 [00:02<00:02, 46.15it/s]
 50%|####9     | 100/201 [00:02<00:02, 46.09it/s]
 52%|#####2    | 105/201 [00:02<00:02, 46.08it/s]
 55%|#####4    | 110/201 [00:02<00:01, 46.07it/s]
 57%|#####7    | 115/201 [00:02<00:01, 46.15it/s]
 60%|#####9    | 120/201 [00:02<00:01, 46.10it/s]
 62%|######2   | 125/201 [00:02<00:01, 46.13it/s]
 65%|######4   | 130/201 [00:02<00:01, 45.99it/s]
 67%|######7   | 135/201 [00:02<00:01, 46.05it/s]
 70%|######9   | 140/201 [00:03<00:01, 46.13it/s]
 72%|#######2  | 145/201 [00:03<00:01, 46.07it/s]
 75%|#######4  | 150/201 [00:03<00:01, 46.17it/s]
 77%|#######7  | 155/201 [00:03<00:00, 46.07it/s]
 80%|#######9  | 160/201 [00:03<00:00, 46.18it/s]
 82%|########2 | 165/201 [00:03<00:00, 46.16it/s]
 85%|########4 | 170/201 [00:03<00:00, 46.15it/s]
 87%|########7 | 175/201 [00:03<00:00, 46.04it/s]
 90%|########9 | 180/201 [00:03<00:00, 46.05it/s]
 92%|#########2| 185/201 [00:04<00:00, 45.99it/s]
 95%|#########4| 190/201 [00:04<00:00, 46.11it/s]
 97%|#########7| 195/201 [00:04<00:00, 46.23it/s]
100%|#########9| 200/201 [00:04<00:00, 46.07it/s]
100%|##########| 201/201 [00:04<00:00, 45.98it/s]

  0%|          | 0/201 [00:00<?, ?it/s]
  3%|2         | 6/201 [00:00<00:03, 58.51it/s]
  6%|6         | 13/201 [00:00<00:03, 60.53it/s]
 10%|9         | 20/201 [00:00<00:02, 61.03it/s]
 13%|#3        | 27/201 [00:00<00:02, 61.56it/s]
 17%|#6        | 34/201 [00:00<00:02, 61.80it/s]
 20%|##        | 41/201 [00:00<00:02, 61.97it/s]
 24%|##3       | 48/201 [00:00<00:02, 62.03it/s]
 27%|##7       | 55/201 [00:00<00:02, 62.12it/s]
 31%|###       | 62/201 [00:01<00:02, 62.00it/s]
 34%|###4      | 69/201 [00:01<00:02, 62.14it/s]
 38%|###7      | 76/201 [00:01<00:02, 62.15it/s]
 41%|####1     | 83/201 [00:01<00:01, 62.25it/s]
 45%|####4     | 90/201 [00:01<00:01, 62.11it/s]
 48%|####8     | 97/201 [00:01<00:01, 62.19it/s]
 52%|#####1    | 104/201 [00:01<00:01, 62.21it/s]
 55%|#####5    | 111/201 [00:01<00:01, 62.24it/s]
 59%|#####8    | 118/201 [00:01<00:01, 62.17it/s]
 62%|######2   | 125/201 [00:02<00:01, 62.07it/s]
 66%|######5   | 132/201 [00:02<00:01, 61.56it/s]
 69%|######9   | 139/201 [00:02<00:01, 61.30it/s]
 73%|#######2  | 146/201 [00:02<00:00, 61.46it/s]
 76%|#######6  | 153/201 [00:02<00:00, 61.51it/s]
 80%|#######9  | 160/201 [00:02<00:00, 61.56it/s]
 83%|########3 | 167/201 [00:02<00:00, 61.56it/s]
 87%|########6 | 174/201 [00:02<00:00, 61.66it/s]
 90%|######### | 181/201 [00:02<00:00, 61.86it/s]
 94%|#########3| 188/201 [00:03<00:00, 62.07it/s]
 97%|#########7| 195/201 [00:03<00:00, 62.04it/s]
100%|##########| 201/201 [00:03<00:00, 61.85it/s]

  0%|          | 0/201 [00:00<?, ?it/s]
  3%|2         | 6/201 [00:00<00:03, 55.51it/s]
  6%|6         | 13/201 [00:00<00:03, 59.47it/s]
 10%|9         | 20/201 [00:00<00:02, 60.68it/s]
 13%|#3        | 27/201 [00:00<00:02, 61.51it/s]
 17%|#6        | 34/201 [00:00<00:02, 61.68it/s]
 20%|##        | 41/201 [00:00<00:02, 62.04it/s]
 24%|##3       | 48/201 [00:00<00:02, 62.09it/s]
 27%|##7       | 55/201 [00:00<00:02, 62.21it/s]
 31%|###       | 62/201 [00:01<00:02, 62.27it/s]
 34%|###4      | 69/201 [00:01<00:02, 62.33it/s]
 38%|###7      | 76/201 [00:01<00:02, 62.30it/s]
 41%|####1     | 83/201 [00:01<00:01, 62.42it/s]
 45%|####4     | 90/201 [00:01<00:01, 62.30it/s]
 48%|####8     | 97/201 [00:01<00:01, 62.40it/s]
 52%|#####1    | 104/201 [00:02<00:05, 16.21it/s]
 55%|#####5    | 111/201 [00:02<00:04, 20.86it/s]
 59%|#####8    | 118/201 [00:02<00:03, 26.06it/s]
 62%|######2   | 125/201 [00:03<00:02, 31.57it/s]
 66%|######5   | 132/201 [00:03<00:01, 37.09it/s]
 69%|######9   | 139/201 [00:03<00:01, 42.20it/s]
 72%|#######2  | 145/201 [00:03<00:01, 45.52it/s]
 76%|#######5  | 152/201 [00:03<00:00, 49.69it/s]
 79%|#######9  | 159/201 [00:03<00:00, 52.15it/s]
 83%|########2 | 166/201 [00:03<00:00, 54.93it/s]
 86%|########6 | 173/201 [00:03<00:00, 57.10it/s]
 90%|########9 | 180/201 [00:03<00:00, 58.64it/s]
 93%|#########3| 187/201 [00:04<00:00, 59.85it/s]
 97%|#########6| 194/201 [00:04<00:00, 60.47it/s]
100%|##########| 201/201 [00:04<00:00, 61.18it/s]
100%|##########| 201/201 [00:04<00:00, 46.66it/s]

  0%|          | 0/201 [00:00<?, ?it/s]
  5%|4         | 10/201 [00:00<00:01, 96.63it/s]
 10%|#         | 21/201 [00:00<00:01, 100.47it/s]
 16%|#5        | 32/201 [00:00<00:01, 102.09it/s]
 21%|##1       | 43/201 [00:00<00:01, 102.14it/s]
 27%|##6       | 54/201 [00:00<00:01, 102.48it/s]
 32%|###2      | 65/201 [00:00<00:01, 103.04it/s]
 38%|###7      | 76/201 [00:00<00:01, 103.15it/s]
 43%|####3     | 87/201 [00:00<00:01, 102.94it/s]
 49%|####8     | 98/201 [00:00<00:00, 103.23it/s]
 54%|#####4    | 109/201 [00:01<00:00, 103.05it/s]
 60%|#####9    | 120/201 [00:01<00:00, 102.91it/s]
 65%|######5   | 131/201 [00:01<00:00, 103.23it/s]
 71%|#######   | 142/201 [00:01<00:00, 103.21it/s]
 76%|#######6  | 153/201 [00:01<00:00, 103.24it/s]
 82%|########1 | 164/201 [00:01<00:00, 103.25it/s]
 87%|########7 | 175/201 [00:01<00:00, 103.45it/s]
 93%|#########2| 186/201 [00:01<00:00, 103.22it/s]
 98%|#########8| 197/201 [00:01<00:00, 103.20it/s]
100%|##########| 201/201 [00:01<00:00, 102.88it/s]
MiPf MiCe MiPa MiOc
time_ms model beta key
-200 1 + stim + tone + stim:tone Intercept 2.5_ci -0.966986 -3.307879 -3.085487 -1.960382
97.5_ci 2.157268 0.814112 1.422942 2.082798
AIC 2453.064268 2638.194268 2698.055391 2625.298684
DF 330.000000 330.000000 330.000000 330.000000
Estimate 0.595141 -1.246884 -0.831273 0.061208
... ... ... ... ... ... ... ...
600 1 Intercept SSresid 54705.731756 74415.041098 84421.740834 62445.342261
T-stat -3.650176 -1.388632 1.231622 1.594855
has_warning 0.000000 0.000000 0.000000 0.000000
logLike -1325.388794 -1376.772956 -1397.842824 -1347.486761
sigma2 164.281477 223.468592 253.518741 187.523550

28944 rows × 4 columns



AIC model comparison: \(\Delta_{i} = \mathsf{AIC}_{i} - \mathsf{AIC_{min}}\)

Akiakie’s information criterion (AIC) increases with residual error and the number of model parameters so comparison on AIC favors the better fitting, more parsimonious models with lower AIC values.

This example visualizes the channel-wise time course of \(\Delta_{i} = \mathsf{AIC}_{i} - \mathsf{AIC_{min}}\), a measure of the AIC of model i vs. the lowest AIC of any model in the set. Burnham and Anderson propose heuristics where models with \(\Delta_{i}\) around 4 are less well supported by the data than the alternative(s) and models with \(\Delta_{i}\) > 7 substantially less so.

In the next figure, the line plots (left column) and raster plots (right column) show the same data in different ways. Higher amplitude line plots and corresponding darker shades of blue in the raster plot indicate that the model’s AIC is higher than the best candidate in the set.

Prestimulus. Prior to stimulus onset at time = 0, the more parsimonious models (bottom three rows) have systematically lower AIC values (broad regions of lighest blue) than the more complex models (top two rows). This indicates that during this interval, the predictor variables alone and in combination do not soak up enough variability to offset the penalty for increasing the model complexity. In terms of this AIC measure, none of the models appear systematically better supported by the data than the null model (bottom row) in the prestimulus interval.

Post-stimulus. In the interval between around 300 - 375 ms poststimulus, the full model that includes stim and tone predictors and their interaction has the minimum AIC among the models compared at all channels except the prefrontal MiPf. The sharp transients in the magntiude of the AIC differences (> 7) at these channels in this interval indicates substantially less support for the alternative models.

from fitgrid.utils.summary import plot_AICmin_deltas

fig, axs = plot_AICmin_deltas(lm_summary_T, figsize=(12, 12))
fig.tight_layout()
for ax_row in range(len(axs)):
    axs[ax_row, 0].set(ylim=(0, 50))
aic min delta: 1 + stim + tone + stim:tone, aic min delta: 1 + stim + tone, aic min delta: 1 + stim, aic min delta: 1 + tone, aic min delta: 1

Likelihood Ratio

This example fits a full and reduced model, computes and then visualizes the time course of likelihood ratios with a few lines of code.

Fit the full model. The log likelihood dataframe is returned by querying the FitGrid.

lmg_full = fg.lm(p3_epochs_fg, RHS="1 + stim + tone + stim:tone", LHS=channels)
lmg_full.llf

Out:

  0%|          | 0/201 [00:00<?, ?it/s]
  2%|2         | 5/201 [00:00<00:04, 41.46it/s]
  5%|4         | 10/201 [00:00<00:04, 43.06it/s]
  7%|7         | 15/201 [00:00<00:04, 43.32it/s]
 10%|9         | 20/201 [00:00<00:04, 43.61it/s]
 12%|#2        | 25/201 [00:00<00:04, 43.71it/s]
 15%|#4        | 30/201 [00:00<00:03, 43.90it/s]
 17%|#7        | 35/201 [00:00<00:03, 43.79it/s]
 20%|#9        | 40/201 [00:00<00:03, 43.93it/s]
 22%|##2       | 45/201 [00:01<00:03, 43.91it/s]
 25%|##4       | 50/201 [00:01<00:03, 44.02it/s]
 27%|##7       | 55/201 [00:01<00:03, 44.06it/s]
 30%|##9       | 60/201 [00:01<00:03, 44.09it/s]
 32%|###2      | 65/201 [00:01<00:03, 43.89it/s]
 35%|###4      | 70/201 [00:01<00:02, 43.98it/s]
 37%|###7      | 75/201 [00:01<00:02, 43.90it/s]
 40%|###9      | 80/201 [00:01<00:02, 43.87it/s]
 42%|####2     | 85/201 [00:01<00:02, 43.88it/s]
 45%|####4     | 90/201 [00:02<00:02, 43.78it/s]
 47%|####7     | 95/201 [00:02<00:02, 43.81it/s]
 50%|####9     | 100/201 [00:02<00:02, 43.84it/s]
 52%|#####2    | 105/201 [00:02<00:02, 43.92it/s]
 55%|#####4    | 110/201 [00:02<00:02, 43.87it/s]
 57%|#####7    | 115/201 [00:02<00:01, 43.60it/s]
 60%|#####9    | 120/201 [00:02<00:01, 43.51it/s]
 62%|######2   | 125/201 [00:02<00:01, 43.64it/s]
 65%|######4   | 130/201 [00:02<00:01, 43.62it/s]
 67%|######7   | 135/201 [00:03<00:01, 43.68it/s]
 70%|######9   | 140/201 [00:03<00:01, 43.55it/s]
 72%|#######2  | 145/201 [00:03<00:01, 43.62it/s]
 75%|#######4  | 150/201 [00:03<00:01, 43.54it/s]
 77%|#######7  | 155/201 [00:03<00:01, 43.66it/s]
 80%|#######9  | 160/201 [00:03<00:00, 43.59it/s]
 82%|########2 | 165/201 [00:03<00:00, 43.76it/s]
 85%|########4 | 170/201 [00:03<00:00, 43.69it/s]
 87%|########7 | 175/201 [00:04<00:00, 43.81it/s]
 90%|########9 | 180/201 [00:04<00:00, 43.81it/s]
 92%|#########2| 185/201 [00:04<00:00, 43.89it/s]
 95%|#########4| 190/201 [00:04<00:00, 43.71it/s]
 97%|#########7| 195/201 [00:04<00:00, 43.76it/s]
100%|#########9| 200/201 [00:04<00:00, 43.48it/s]
100%|##########| 201/201 [00:04<00:00, 43.72it/s]
MiPf MiCe MiPa MiOc
time_ms
-200 -1222.532134 -1315.097134 -1345.027696 -1308.649342
-196 -1219.015289 -1309.332110 -1343.317795 -1307.756720
-192 -1217.569942 -1299.470975 -1337.332536 -1313.580720
-188 -1203.189206 -1284.976803 -1330.065186 -1304.068471
-184 -1176.462814 -1277.721413 -1331.545780 -1303.852666
... ... ... ... ...
584 -1311.148454 -1361.863041 -1387.438445 -1340.639807
588 -1307.528658 -1365.721171 -1386.531566 -1332.786442
592 -1313.377251 -1370.874212 -1389.435160 -1333.903770
596 -1318.216984 -1373.834763 -1393.517831 -1343.739941
600 -1323.657999 -1373.309777 -1388.665581 -1337.706494

201 rows × 4 columns



Fit the reduced model likewise.

lmg_reduced = fg.lm(p3_epochs_fg, RHS="1 + stim + tone", LHS=channels)
lmg_reduced.llf

Out:

  0%|          | 0/201 [00:00<?, ?it/s]
  2%|2         | 5/201 [00:00<00:04, 42.52it/s]
  5%|4         | 10/201 [00:00<00:04, 44.53it/s]
  7%|7         | 15/201 [00:00<00:04, 44.94it/s]
 10%|9         | 20/201 [00:00<00:03, 45.51it/s]
 12%|#2        | 25/201 [00:00<00:03, 45.54it/s]
 15%|#4        | 30/201 [00:00<00:03, 45.72it/s]
 17%|#7        | 35/201 [00:00<00:03, 45.80it/s]
 20%|#9        | 40/201 [00:00<00:03, 45.96it/s]
 22%|##2       | 45/201 [00:00<00:03, 46.03it/s]
 25%|##4       | 50/201 [00:01<00:03, 46.16it/s]
 27%|##7       | 55/201 [00:01<00:03, 46.12it/s]
 30%|##9       | 60/201 [00:01<00:03, 46.12it/s]
 32%|###2      | 65/201 [00:01<00:02, 46.17it/s]
 35%|###4      | 70/201 [00:01<00:02, 46.18it/s]
 37%|###7      | 75/201 [00:01<00:02, 46.30it/s]
 40%|###9      | 80/201 [00:01<00:02, 46.21it/s]
 42%|####2     | 85/201 [00:01<00:02, 46.23it/s]
 45%|####4     | 90/201 [00:01<00:02, 46.15it/s]
 47%|####7     | 95/201 [00:02<00:02, 46.25it/s]
 50%|####9     | 100/201 [00:02<00:02, 46.32it/s]
 52%|#####2    | 105/201 [00:02<00:02, 46.25it/s]
 55%|#####4    | 110/201 [00:02<00:01, 46.38it/s]
 57%|#####7    | 115/201 [00:02<00:01, 46.33it/s]
 60%|#####9    | 120/201 [00:02<00:01, 46.44it/s]
 62%|######2   | 125/201 [00:02<00:01, 46.36it/s]
 65%|######4   | 130/201 [00:02<00:01, 46.35it/s]
 67%|######7   | 135/201 [00:02<00:01, 46.26it/s]
 70%|######9   | 140/201 [00:03<00:01, 46.13it/s]
 72%|#######2  | 145/201 [00:03<00:01, 45.86it/s]
 75%|#######4  | 150/201 [00:03<00:01, 46.01it/s]
 77%|#######7  | 155/201 [00:03<00:00, 46.12it/s]
 80%|#######9  | 160/201 [00:03<00:00, 45.85it/s]
 82%|########2 | 165/201 [00:03<00:00, 44.43it/s]
 85%|########4 | 170/201 [00:03<00:00, 43.56it/s]
 87%|########7 | 175/201 [00:03<00:00, 41.82it/s]
 90%|########9 | 180/201 [00:03<00:00, 42.95it/s]
 92%|#########2| 185/201 [00:04<00:00, 41.41it/s]
 95%|#########4| 190/201 [00:04<00:00, 42.60it/s]
 97%|#########7| 195/201 [00:04<00:00, 43.64it/s]
100%|#########9| 200/201 [00:04<00:00, 44.14it/s]
100%|##########| 201/201 [00:04<00:00, 45.13it/s]
MiPf MiCe MiPa MiOc
time_ms
-200 -1222.598161 -1315.857038 -1345.655697 -1310.202354
-196 -1219.035644 -1309.862783 -1344.004489 -1309.552813
-192 -1217.708926 -1300.291720 -1338.389544 -1315.676625
-188 -1203.608227 -1286.117888 -1331.449561 -1305.668078
-184 -1176.544845 -1278.648741 -1332.709155 -1304.580230
... ... ... ... ...
584 -1311.224343 -1361.863881 -1387.594031 -1341.033271
588 -1307.935020 -1365.731574 -1386.761340 -1333.356553
592 -1313.604190 -1370.888442 -1389.681551 -1334.510610
596 -1318.389052 -1373.835473 -1393.602722 -1344.138936
600 -1324.154922 -1373.313601 -1388.716013 -1338.103694

201 rows × 4 columns



Calculate. The likelihood ratio is the difference of the log likelihoods.

likelihood_ratio = lmg_full.llf - lmg_reduced.llf
likelihood_ratio
MiPf MiCe MiPa MiOc
time_ms
-200 0.066027 0.759904 0.628001 1.553012
-196 0.020355 0.530672 0.686694 1.796092
-192 0.138984 0.820745 1.057008 2.095905
-188 0.419021 1.141085 1.384376 1.599607
-184 0.082031 0.927328 1.163375 0.727564
... ... ... ... ...
584 0.075889 0.000840 0.155586 0.393464
588 0.406362 0.010402 0.229774 0.570111
592 0.226939 0.014231 0.246391 0.606841
596 0.172068 0.000710 0.084891 0.398995
600 0.496923 0.003825 0.050432 0.397200

201 rows × 4 columns



Visualize. This comparison shows that stimulus x tone interaction term in the model has little systematic impact on the goodness-of-fit as given by the likelihood except around 300 - 375 ms poststimulus, largest over central scalp (MiCe).

fig, ax = plt.subplots(figsize=(12, 3))

# render
im = ax.imshow(likelihood_ratio.T, interpolation="none", aspect=16)
cb = fig.colorbar(im, ax=ax)

# label
ax.set_title("Likelihood ratio")
ax.set(xlabel="Time (ms)", ylabel="Channel")

xtick_labels = range(-200, 600, 100)
ax.set_xticks([likelihood_ratio.index.get_loc(tick) for tick in xtick_labels])
ax.set_xticklabels(xtick_labels)

ax.set_yticks(range(len(likelihood_ratio.columns)))
ax.set_yticklabels(likelihood_ratio.columns)
fig.tight_layout()
Likelihood ratio
fig, ax = plt.subplots(figsize=(8, 3))
ax.set_title("Likelihood Ratio")
_ = (lmg_full.llf - lmg_reduced.llf).plot(ax=ax)
Likelihood Ratio

Total running time of the script: ( 0 minutes 38.955 seconds)

Gallery generated by Sphinx-Gallery