Parameterschätzung, Posterior zusammenfassen, und lineare Modelle.
Bemerkungen
library()
geladen.In der ersten Aufgabe untersuchen Sie einen Datensatz einer Studie, bei der die Arbeitsgedächtnisleitung mittels eines N-Back Tasks bei \(21\) Kindern mit einer ADHS Diagnose untersucht wurde. Gleichzeitig wurde derselbe Task mit einer Kontrollgruppe (\(n=30\)) durchgeführt. Die behavioralen Resultate wurde parallel zu einer fMRI Untersuchung erhoben, damit im Antwortverhalten der Kinder ein Unterschied zur Kontrollgruppe gezeigt werden konnte.
Bei einem N-Back Test wird den Versuchspersonen eine Serie von Stimuli dargeboten (z.B. Buchstaben), und man muss mit einem Tastendruck reagieren, wenn der aktuelle Stimulus gleich dem N-letzten Stimulus war.
Hier sehen Sie ein Beispiel für einen 3-Back Test. Bei den gelb markierten Buchstaben muss die Versuchsperson reagieren.
T A A F A G H R Y Z R V D …
Bei diesem Task untersuchen wir die Reaktionszeiten der Versuchspersonen bei korrekten Antworten. Im Datensatz sind die gemittelten Reaktionszeiten in Sekunden der Kinder in der ADHD
und der Control
Gruppe.
Wir laden die Daten:
Bevor man anfängt, ist es immer eine gute Idee, einen Blick auf die Daten zu werfen.
glimpse(nback1)
Rows: 51
Columns: 2
$ rt <dbl> 1.0267571, 2.0671470, 1.6728257, 1.0355146, 1.0310874,…
$ group <chr> "adhd", "adhd", "adhd", "adhd", "adhd", "adhd", "adhd"…
Die Gruppierungsvariable group
ist ein character Vektor, sollte aber ein Faktor sein.
nback1 <- nback1 %>%
mutate(group = as_factor(group))
Nun macht es Sinn, als Referenzkategorie die control group
zu bestimmen. Mit fct_relevel()
verändern wir die Reihenfolgen der Faktorstufen:
levels(nback1$group)
[1] "adhd" "control"
nback1 <- nback1 %>%
mutate(group = fct_relevel(group, "control"))
control
ist nun die erste Stufe, und wir automatisch zur Referenzkategorie, wenn wir die Variable dummy-kodieren.
levels(nback1$group)
[1] "control" "adhd"
Aufgabe 1.1
Berechnen Sie Mittelwerte und SD pro Gruppe.
Zusätzlich berechnen wir gleich noch die Standardfehler, damit wir die Gruppenmittelwerte grafisch darstellen können. Diese Funktion definiere ich hier selber, da sie in base R nicht exisitiert.
nback1_summary <- nback1 %>%
group_by(group) %>%
summarise(mean = mean(rt),
sd = sd(rt),
se = se(rt))
nback1_summary
# A tibble: 2 x 4
group mean sd se
<fct> <dbl> <dbl> <dbl>
1 control 1.15 0.235 0.0430
2 adhd 1.31 0.426 0.0929
Aufgabe 1.2
Stellen Sie die Daten mit grafisch dar, zum Beispiel mit Histogrammen, Boxplots oder Violin Plots.
library(patchwork)
p1 <- nback1 %>%
ggplot(aes(rt)) +
geom_histogram(fill = "steelblue", bins = 15) +
facet_wrap(~group) +
theme_bw(base_size = 14)
p2 <- nback1 %>%
ggplot(aes(group, rt, fill = group)) +
geom_violin(alpha = 0.4) +
geom_boxplot(alpha = 0.6) +
geom_jitter() +
scale_fill_viridis_d(end = 0.8) +
theme_bw()
p1 + p2
Zusätzlich erstellen wir einen Plot mit eingezeichneten Standardfehlern.
nback1_summary %>%
ggplot(aes(group, mean)) +
geom_errorbar(aes(ymin = mean-se, ymax = mean+se),
width = 0.2, size=1, color="blue") +
geom_point(size = 4) +
theme_bw(base_size = 14)
oder
nback1_summary %>%
ggplot(aes(group, mean)) +
geom_linerange(aes(ymin = mean-se, ymax = mean+se)) +
geom_point(size = 4) +
theme_bw(base_size = 14)
Aufgabe 1.3
Mit welcher Methode würden Sie diese Daten analysieren? Beschreiben Sie Ihre Wahl in 1-2 Sätzen und führen Sie einen Test durch. Was können Sie damit aussagen?
Wir können hier annehmen, dass die Kinder in der adhd
Gruppe länger brauchen. Dies bedeutet, dass wir eine gerichtete Hypothese testen. Es ist in den meisten Fällen sinnvoll, einen Welch Test durchzuführen. Dies ist auch der Default in R (wenn wir einen t-Test wünschen, müssen wir dies explizit angeben, mit var.eq = TRUE
).
t.test(rt ~ group,
data = nback1,
alternative = "less")
Welch Two Sample t-test
data: rt by group
t = -1.5282, df = 28.57, p-value = 0.06873
alternative hypothesis: true difference in means between group control and group adhd is less than 0
95 percent confidence interval:
-Inf 0.01757687
sample estimates:
mean in group control mean in group adhd
1.153130 1.309528
Selbst wenn wir einen gerichteten t-Test durchführen, erhalten wir einen p-Wert von 0.0687. Dies bedeutet, dass wir unter Verwendung von \(\alpha = 0.05\) die Nullhypothese nicht ablehnen dürfen. Falls Sie hier ungerichtet getestet haben, haben Sie einen p-Wert von \(0.1375\) erhalten (entspricht dem doppeltem einseitigen p-Wert).
t.test(rt ~ group,
data = nback1)
Welch Two Sample t-test
data: rt by group
t = -1.5282, df = 28.57, p-value = 0.1375
alternative hypothesis: true difference in means between group control and group adhd is not equal to 0
95 percent confidence interval:
-0.36584395 0.05304754
sample estimates:
mean in group control mean in group adhd
1.153130 1.309528
In beiden Fällen können wir also die Nullhypothese nicht ablehnen. Diese sagt aus, dass die beiden Gruppen in Bezug auf die Teststatistik nicht unterscheiden, d.h. in Bezug auf dem Gruppenmittelwert. Mehr können wir mit diesem t-Test nicht aussagen. Dies ist etwas unglücklich, da unser Ziel wahrscheinlich war, einen Unterschied mit funktioneller Bildgebung zu untersuchen.
Selbstverständlich hätten wir grössere Stichproben nehmen sollen; dies ist aber in fMRI Studien nicht immer möglich, und führt dazu, dass viele Studien under-powered sind.
Wir wollen nun die beiden Gruppenmittelwerte Bayesianisch schätzen. Sie haben zwei Möglichkeiten kennengelernt, die Formel zu spezifieren.
Aufgabe 1.4
Entscheiden Sie sich für eine der beiden, und schätzen sie die Mittelwerte mit brms. Schauen Sie sich vorher mit der Funktion get_prior
die Default Prior Verteilungen an. Wenn sie wollen, können Sie anstelle der Defaults eigene Priors spezifieren. Falls Sie das tun, begründen Sie kurz Ihre Wahl.
Mit den zwei Möglichkeiten sind die folgenden gemeint:
~ 1 + group rt
und
~ 0 + group rt
Die beiden Formeln können wir so verstehen:
~ 1 + group rt
wird zu
~ b0 * 1 + b_group * group rt
Wir haben also einen Achsenabschnitt (Intercept) b0
und einen Regressionskoeffizienten b_group
. Wenn die Variable group
dummy kodiert ist, dann ist b_group
der Unterschied zwischen den Gruppen.
Die Formel
~ 0 + group rt
wird zu
~ b0 * 0 + b_groupcontrol * groupcontrol + b_groupadhd * groupadhd rt
Hier haben wir keinen Achsenabschnitt, so dass wir beide Indikatorvariablen verwenden können. Die beiden Koeffizienten repräsentieren deshalb die beiden Gruppenmittelwerte.
Etwas, das oft falsch gemacht wurde: Mit der Formel rt ~ 1
wird ein Achsenabschnitt geschätzt. Dies wäre das Nullmodell, denn hier wird die Gruppierungsvariable weggelassen, und wir schätzen den Gesamtmittelwert.
Nun schauen wir uns für beide Möglichkeiten die Priors an. Wenn wir rt ~ 1 + group
oder einfach rt ~ group
verwenden, dann erhalten wir einen student_t(3, 1.2, 2.5)
Prior für den Intercept, und einen flachen Prior für den Unterschied.
prior class coef group resp dpar nlpar
(flat) b
(flat) b groupadhd
student_t(3, 1.2, 2.5) Intercept
student_t(3, 0, 2.5) sigma
bound source
default
(vectorized)
default
default
Wenn wir den Intercept weglassen, erhalten wir für beide Gruppen flache Priors:
get_prior(rt ~ 0 + group,
data = nback1)
prior class coef group resp dpar nlpar bound
(flat) b
(flat) b groupadhd
(flat) b groupcontrol
student_t(3, 0, 2.5) sigma
source
default
(vectorized)
(vectorized)
default
Wenn wir uns hier für die ersten Variante entscheiden, können wir eine besseren Prior spezifieren. Z.B. könnten wir a priori 95% sicher sein, dass der Gruppenunterschied zwischen -10 und +10 liegt. Dies können wir mit dem Prior normal(0, 5)
ausdrücken.
priors <- prior(normal(0, 5), class = b)
Aufgabe 1.5
Schätzen Sie nun die Parameter Ihres Modells.
summary
den Output an.Rhat
Werte in Ordnung sind.m1 <- brm(rt ~ group,
prior = priors,
data = nback1,
file = "nback1")
summary(m1)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: rt ~ group
Data: nback1 (Number of observations: 51)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 1.15 0.06 1.03 1.28 1.00 3165 2552
groupadhd 0.16 0.10 -0.03 0.34 1.00 3484 2506
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 0.34 0.04 0.28 0.41 1.00 2763 2124
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Es werden hier 3 Parameter geschätzt: Intercept
, groupadhd
und sigma
. Letzter ist die Standardabweichung der Residuuen. Alle 3 Parameter haben ein Rhat von 1.00
. Wir sollten darauf achten, dass Rhat nicht >1.05 ist. Dies würde bedeuten, dass die 4 Chains, welche unabhängig voneinander sind, nicht dieselbe Posterior Verteilung geschätzt haben, was natürlich nicht das ist, was wir wollen.
Wir haben hier nur ein sigma
geschätzt, was bedeutet, dass wir für beide Gruppen dieselbe Standardabweichung annehmen. Diese Annahme ist nicht nötig, wir könnten genausogut auch 2 Standardabweichungen schätzen. Dies würde so aussehen:
In diesem Modell sagen wir sowohl den Mittelwert als auch die Standardabweichung anhand der Gruppenzugehörigkeit vorher. Das heisst, dass wir hier relitiv flexibel unser Modell spezifizieren können, und zwar so dass wir die interessierenden Parameter besser schätzen können. Dies soll an dieser Stelle einfach mal die Flexibilität von Bayesianischer Inferenz illustrieren — dieses Vorgehen wäre mit frequentistischer Statistik nicht möglich. Wir bräuchten ein eigens dafür entwickeltes Verfahren, und müssten hoffen, dass jemand ein R Package dafür schreibt.
Alle Parameter, welche wir in unserem Modell spezifiziert haben, erscheinen nun auch im Ouput.
Die beiden Parameter Intercept
, groupadhd
interessieren uns hier besonders. Der Intercept ist der erwartete Wert der Kontrollgruppe, während groupadhd
der Unterschied zwischen den Gruppen ist.
Optionale Aufgabe: fassen Sie die Posterior Verteilung des/der relevanten Parameter(s) mit Hilfe der Funtion mean_qi()
im tidybayes
Packages zusammen.
library(tidybayes)
samples1 <- m1 %>%
posterior_samples() %>%
transmute(Differenz = b_groupadhd)
samples1 %>%
mean_qi()
Differenz .lower .upper .width .point .interval
1 0.1579944 -0.03237111 0.3435227 0.95 mean qi
Anstatt sich nur eine Tabelle anzuschauen, ist es hilfreich, die Verteilungen grafisch darzustellen.
Aufgabe 1.6
Stellen Sie die Posterior Verteilung(en) grafisch dar. Sie können dies entweder mit der Funktion mcmc_plots()
im brms
Package, oder (optional) mit dem tidybayes
Package machen. Eine Anleitung für das tidybayes
Package finden Sie im 3. Kapitel des Skripts.
Mit der Funktion mcmc_plot()
können wir eigentlich alles darstellen. Entweder alle Koeffizienten, die beiden Regressionkoeffizienten, oder nur den Unterschiedskoeffizienten.
m1 %>%
mcmc_plot()
m1 %>%
mcmc_plot("b")
Wir können auch die Breite des Credible Intervals ändern, so dass wir die 50% und 95% Credible Intervals erhalten.
m1 %>%
mcmc_plot("b_group", prob = 0.5, prob_outer = 0.95)
Aufgabe 1.7
Diese Frage ist nicht ganz einfach. Mit der Frage “Welche Aussagen dürfen Sie nicht machen?” ist natürlich gemeint, dass wir hier bisher noch keine Hypothese getestet haben, oder zumindest nicht explizit. Implizit haben wir hier zwar die Hypothese, dass es einen Unterschied gibt, den wir schätzen können (mehr dazu später). In diesem einen Modell können wir nun aussagen, in welchen Bereich sich die wahrscheinlichen Werte des Unterschieds befinden. Laut dem Output sind wir 95% sicher, dass der Gruppenunterschied zwischen \(-0.02\) und \(0.34\) liegt. Der Unterschied ist am ehesten > 0. Wir können sogar genau quantifizieren, wie sicher wir uns dessen sind.
Wir berechnen einfach den Anteil der Samples, für welche die Differenz > 0 ist.
samples1 %>%
count(Differenz > 0) %>%
mutate(probability = n / sum(n))
Differenz > 0 n probability
1 FALSE 204 0.051
2 TRUE 3796 0.949
Dies bedeutet, dass wir uns uns 95.5% sicher, dass die Differenz positiv ist. Da wir aber das Nullmodell nicht geschätzt haben, können wir an dieser Stelle keinen Modellvergleich machen. Das Nullmodell ist nämlich dasjenige Modell, in dem die Differenz auf den Wert 0 fixiert wird, d.h. nicht geschätzt wird. Nur wenn wir die beiden Modelle in Bezug auf ihre prädiktiven Fähigkeiten vergleichen, können wir eine Hypothese testen. Etwas, das wir aber hier nicht tun müssen, ist eine binäre Entscheidung zu treffen (Nullhypothese ablehen oder nicht). Diese Entscheidung braucht nämlich eine sogenannte Nutzenfunktion, und diese ist in der frequentistischen Statistik die 5% Fehlerwahrscheinlichkeit. Dies bedeutet, dass Sie bei einem NHST bereit sind, im Schnitt bei jeder 20. Entscheidung einen Fehler zu machen. Dies ist aber nicht zwingend notwendig, da wir auch einfach Evidenz für oder gegen Hypothesen quantifizieren können. Dafür brauchen wir aber z.B. Bayes Factors.
Ganz entscheidend ist hier: wir schätzen hier bedingt auf die Daten die wahrscheinlichen Werte für die Differenz der beiden Gruppen, welche diese Daten generiert haben könnten. In einem NHST wird mehr gemacht. Dort nehmen wir eine Stichprobe, fassen diese anhand von “summary statistics” zusammmen, und schauen uns dann die theoretische Verteilung der summary statistics (in diesem Fall die Mittelwertsdifferenz) unter der Nullhypothese an. Diese Prozedur erlaubt uns auszusagen, wie wahrscheinlich es ist, eine solch grosse Differenz zu erhalten (p-Wert). Anhand dieses p-Wertes kann eine Entscheidung getroffen werden—ob dies eine gute Idee ist, sei dahingestellt. Auf jeden Fall ist die Grenze \(\alpha = 0.05\) willkürlich gewählt, und bedeutet einfach, dass wir bei jeder 20. Entscheidung einen Fehler in Kauf nehmen.
Es gibt einen Trick, wie wir einfach zu dem Anteil der Posterior Samples kommen, welcher über einem Schwellenwert liegt. Wir können einfach die Funktion hypothesis()
benutzen!
Diese verwenden wir so: wir spezifieren unsere “Hypothese” (in Anführungszeichen, weil der Begriff hier nicht ganz richtig verwendet wird) so: "groupadhd > 0"
, und erhalten im Oouput ein Evidence Ratio (Evid.Ratio
). In diesem Fall beträgt dieses 21.22, was genau der Wahrscheinlichkeit von "groupadhd > 0"
geteilt durch die Gegenwahrscheinlichkeit "groupadhd <= 0"
entspricht. Sie erhalten auch die Post.Prob
; dies ist P("groupadhd > 0")
.
m1 %>%
hypothesis("groupadhd > 0")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper Evid.Ratio
1 (groupadhd) > 0 0.16 0.1 0 0.32 18.61
Post.Prob Star
1 0.95
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
In der zweiten Aufgabe untersuchen wir einen Datensatz einer Studie, bei der die Arbeitsgedächtnisleitung mittels eines N-Back Tasks bei 20 gesunden Erwachsenen unter verschiedenen Cognitive Loads untersucht wurde. Ziel dieser Studie war es, die Auswirkung von Cognitive Load auf den Präfrontalen Cortex mittels fMRI zu untersuchen. Wir erwarten, dass bei höherem Cognitive Load die Versuchspersonen länger brauchen, um beim N-Back Task eine korrekte Antwort zu geben.
Der letzte Satz lässt darauf schliessen, dass wir eine gerichtete Hypothese haben.
Wir laden die Daten:
library(tidyverse)
library(rmarkdown)
nback2 <- read_csv("https://raw.githubusercontent.com/kogpsy/neuroscicomplab/main/data/cognitive-load-nback.csv") %>%
mutate(across(-rt, as_factor))
nback2 %>% paged_table()
Wir haben 20 Personen
nback2 %>%
summarize(n_subjects = n_distinct(id))
# A tibble: 1 x 1
n_subjects
<int>
1 20
mit 60 Trials pro Person pro Bedingung. Für jeden Trial haben wir die Reaktionszeit in Millisekunden.
nback2 %>%
group_by(id, load) %>%
count() %>%
rmarkdown::paged_table()
Da die Standardfehler Funktion in R nicht existiert, schreiben wir selber eine (haben wir weiter oben schon gemacht):
Aufgabe 2.1
Fassen Sie die Daten mit Mittelwert, Standardabweichung und Standardfehler pro Person pro Bedingung zusammen.
Mit diesem Code kann ich gleichzeitig 3 Funktionen anwenden (ist effizienter):
# A tibble: 40 x 5
# Groups: id [20]
id load mean sd se
<fct> <fct> <dbl> <dbl> <dbl>
1 1 hi 933. 28.0 3.62
2 1 lo 877. 26.8 3.46
3 2 hi 842. 25.7 3.31
4 2 lo 789. 24.3 3.14
5 3 hi 936. 30.8 3.97
6 3 lo 887. 27.0 3.48
7 4 hi 1030. 20.9 2.70
8 4 lo 976. 26.8 3.46
9 5 hi 834. 23.1 2.99
10 5 lo 796. 24.7 3.19
# … with 30 more rows
Wir erhalten so die mittlere Reaktionszeit für jede Person in jeder Bedingung, plus die SD und die Standardfehler.
Aufgabe 2.2
Sie haben die Kennzahlen für jede Person berechnet. Meistens wollen wir aber nicht nur die Effekte der experimentellen Manipulationen für Individuen, sondern für die ganze Gruppe.
Berechnen Sie die mittlere RT für die beiden Bedingungen, aggregiert über Personen. Wie würden Sie vorgehen? Überlegen Sie sich, was die Vor- und Nachteile eines solches Vorgehens sind, und beschreiben Sie sie kurz.
Meistens wollen wir eine generalisierte Aussage machen können—eine Manipulation soll nicht nur bei einzelnen Individuen einen Effekt haben, sondern in einer Population von gleichen Individuen. Wir haben hier nur den mittlere RT aggregiert über Personen berechnet. Für die Berechnung der Standardfehler müssen wir berücksichtigen, dass die Manipulation des cognitive loads eine “within” Manipulation ist. Dies können wir mit der Funktion summarySEwithin()
aus dem Rmisc
Package machen.
agg <- Rmisc::summarySEwithin(nback2,
measurevar = "rt",
withinvars = "load",
idvar = "id",
na.rm = FALSE,
conf.interval = 0.95)
agg
load N rt sd se ci
1 hi 1200 846.7592 34.56937 0.9979319 1.957887
2 lo 1200 798.0375 35.67373 1.0298120 2.020434
Selbst wenn wir berücksichtigen, dass die load
Bedingung within manipuliert wurde, so haben wir trotzdem noch foglendes Problem: die unsicherheit, die wir bei der Aggregation der RTs der einzelnen Personen haben, wrd einfach ignoriert—wir ersetzen ja die einzelnen Messwerte einfach durch den personenspezifischen Mittelwert für die beiden Bedingungen. Das heisst, anstelle der Verteilung von RTs, welche ziemlich variieren können, nehmen wir einfach den Mittelwert, und hoffen, dass dieser die RTs ausreichend gut zusammenfasst. Dies ist bei RTs leider oft nicht der Fall, da sie eine ausgeprägt Rechtsschiefe aufweisen können.
Diese Aggregation führt dazu, dass wir uns viel zu sicher sind, und die über die Personen aggregegierten Mittelwerte uns ein falsches Gefühl von Sicherheit vermitteln, in dem Sinne, dass sie viel weniger präzise sind, als wir glauben.
Eine sehr gute Methode, um damit umzugehen, ist die Verwendung von Multilevel Modellen—wir bevorzugen hier den Ansatz, die beide Ebenen (Level 1 und Level 2) gleichzeitig zu schätzen, so dass die Unsichersheit nicht einfach weggeworfen wird.
Auch hier ist es sinnvoll, die Daten zuerst grafisch darzustellen.
Aufgabe 2.3
Stellen Sie die mittleren RTs für jede Bedingung aggregiert über Personen grafisch dar.
aggregated %>%
ggplot(aes(load, mean)) +
geom_line(aes(group = 1), linetype = 3) +
geom_point(size = 4) +
theme_bw()
agg %>%
ggplot(aes(x = load, y = rt, group = 1)) +
geom_line() +
geom_errorbar(width =.05, aes(ymin = rt-ci, ymax = rt+ci)) +
geom_point(shape = 21, size = 3, fill = "white") +
theme_bw()
Aufgabe 2.4
Überlegen Sie sich, wie Sie diesen Datensatz frequentistisch analysieren könnten. Beschreiben Sie in 1-2 Sätzen, was Sie tun würden, und welche Aussagen Sie damit machen könnten.
Die einfachste Möglichkeit ist ein paired-samples t-Test.
t.test(rt ~ load,
data = nback2,
alternative = "greater",
paired = TRUE)
Paired t-test
data: rt by load
t = 47.772, df = 1199, p-value < 2.2e-16
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
47.04283 Inf
sample estimates:
mean of the differences
48.72167
Dieser zeigt uns an, dass wir eine Mittelwertsdifferenz zwischen den cognitive load Bedingungen von 48.72 haben, und dass diese Differenz signifikant ist. Das bedeutet genau, dass die Wahrscheinlichkeit, einen t-Wert von 47.772 unter Nullhypotheses zu erhalten klein genug ist, um mit einem Fehlerrisiko von \(\alpha = 0.05\) die Nullhypothese abzulehnen.
Wir könnten hier aber auch ein Multilevel-Modell benutzen:
Es ist sinnvoll, die low cognitive load Bedingung als Referenz zu wählen.
nback2 <- nback2 %>%
mutate(load = fct_relevel(load, "lo"))
Nun erhalten wir den Parameter loadhi
, welcher die Differenz zwischen den Bedingungen repräsentiert, nachdem wir die Messwiederholung innerhalb der Personen berücksichtigt haben.
summary(m_mle_1)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: rt ~ load + (1 | id)
Data: nback2
REML criterion at convergence: 22382.8
Scaled residuals:
Min 1Q Median 3Q Max
-3.5379 -0.6827 0.0229 0.6697 3.9772
Random effects:
Groups Name Variance Std.Dev.
id (Intercept) 7305.3 85.47
Residual 621.8 24.94
Number of obs: 2400, groups: id, 20
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 798.037 19.125 19.027 41.73 <2e-16 ***
loadhi 48.722 1.018 2379.000 47.86 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Correlation of Fixed Effects:
(Intr)
loadhi -0.027
Wir könnten hier auch annehmen, dass die Personen sich auch im Effekt der Bedinungung unterscheiden (random intercept und random slope Modell):
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: rt ~ load + (1 + load | id)
Data: nback2
REML criterion at convergence: 22382.1
Scaled residuals:
Min 1Q Median 3Q Max
-3.5627 -0.6749 0.0220 0.6601 3.9909
Random effects:
Groups Name Variance Std.Dev. Corr
id (Intercept) 7354.849 85.760
loadhi 4.717 2.172 -0.27
Residual 620.711 24.914
Number of obs: 2400, groups: id, 20
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 798.037 19.190 18.999 41.59 <2e-16 ***
loadhi 48.722 1.127 19.001 43.23 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Correlation of Fixed Effects:
(Intr)
loadhi -0.141
Wir wollen nun die population-level Effects mit brms
schätzen, und zwar die Mittelwerte der beiden Cognitive Load Bedingungen. Dafür benutzen wir die Formel ~ 0 + load
. Die population-level Effects entsprechen den Fixed effects im Output von lme4
.
Wir erhalten folgende Default Priors:
get_prior(rt ~ 0 + load + (1 | id),
data = nback2)
prior class coef group resp dpar nlpar bound
(flat) b
(flat) b loadhi
(flat) b loadlo
student_t(3, 0, 94.1) sd
student_t(3, 0, 94.1) sd id
student_t(3, 0, 94.1) sd Intercept id
student_t(3, 0, 94.1) sigma
source
default
(vectorized)
(vectorized)
default
(vectorized)
(vectorized)
default
Die beiden flachen Priors der Parameter loadhi
und loadlo
wollen wir nun durch eigene Priors ersetzen. Wir nehmen hier einfach Normalverteilungen, mit einem Mittelwert, der dem Gesamtmittelwert entspricht, und einer etwas arbiträr gewählten Standardabweichung von \(10\).
Priors können mit set_prior()
oder einfach nur prior()
definiert werden.
Wir schätzen das Model nun mit unseren Prior Verteilungen.
m2 <- brm(rt ~ 0 + load + (1 | id),
prior = priors,
data = nback2,
file = "nback2")
Aufgabe 2.5
Überprüfen Sie, ob die Rhat
Werte in Ordnung sind. Falls ja, fassen Sie die Posterior Verteilung der wichtigen Parameter zusammen. Stellen Sie die Posterior Verteilungen der beiden Bedingungsparameter grafisch dar, z.B. mit mcmc_plot()
.
summary(m2)
Family: gaussian
Links: mu = identity; sigma = identity
Formula: rt ~ 0 + load + (1 | id)
Data: nback2 (Number of observations: 2400)
Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
total post-warmup samples = 4000
Group-Level Effects:
~id (Number of levels: 20)
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
sd(Intercept) 86.88 13.89 63.37 118.19 1.01 306
Tail_ESS
sd(Intercept) 601
Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
loadhi 846.40 6.58 833.08 859.34 1.01 527 697
loadlo 797.94 6.58 784.84 810.94 1.01 522 697
Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 24.96 0.36 24.29 25.70 1.00 1562 1440
Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
Die Rhat Werte sind in Ordnung. Wir erhalten die Parameter loadhi
, loadlo
, sigma
und sd(Intercept)
. sd(Intercept)
ist die Standardabweichung der personenspezifischen Abweichungen von Achsenabschnitt. Das ist vielleicht etwas verwirrend, denn wir haben hier keinen Achsenabschnitt. Eigentlich sind das aber einfach die Abweichungen von den beiden Population-Level Effects. sigma
ist die Standardabweichung der Residuen. loadhi
und loadlo
sind die Mittelwerte der beiden Bedingungen.
m2 %>%
mcmc_plot("b")
Falls Sie die Verteilung der Differenz wollen, können Sie entweder das Modell so parametrisieren: ~ 1 + load + (1 | id)
, oder die Differenz nachträglich für jede Iteration berechnen. Dies können Sie so machen.
samples_m2 <- posterior_samples(m2) %>%
transmute(hi = b_loadhi,
lo = b_loadlo,
Differenz = hi - lo)
Diese Differenz können Sie jetzt auch zusammenfassen
Differenz .lower .upper .width .point .interval
1 48.46462 46.51335 50.4016 0.95 median qi
und grafisch darstellen.
samples_m2 %>%
select(Differenz) %>%
ggplot(aes(x = Differenz)) +
stat_halfeye(point_interval = median_qi) +
theme_tidybayes()
Aufgabe 2.6
Auch hier dient dieser behaviorale Task dazu, die fMRI Analyse zu unterstützen. Wenn wir Unterschiedliche Aktivierung im präfrontalen Cortex in abhängigkeit des congitve load demonstrieren wollen, dann ist es vorteilhaft, auch behavioral einen Effekt zu zeigen.
Wir können wieder Angaben zur Posterior Verteilung der Parameter machen. Wir sind uns 95% sicher, dass die Differenz zwischen 46.54 und 50.39 liegt (das sind diejenigen Werte, welche am ehesten einen solchen Datensatz generienen). Weiter können wir sagen, welcher Anteil der Verteilung der Differenz positiv ist:
samples_m2 %>%
count(Differenz > 0) %>%
mutate(probability = n / sum(n))
Differenz > 0 n probability
1 TRUE 4000 1
Oder wieder mit der hypothesis()
Funktion:
m2 %>%
hypothesis("loadhi > loadlo")
Hypothesis Tests for class b:
Hypothesis Estimate Est.Error CI.Lower CI.Upper
1 (loadhi)-(loadlo) > 0 48.46 1 46.86 50.06
Evid.Ratio Post.Prob Star
1 Inf 1 *
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
Die Wahrscheinlichkeit, dass in der high
Bedingung die RTs grösser sind, ist also 1.
Auch hier müssen wir aber festhalten, dass wir noch keine Hypothese getestet haben. Dafür brauchen wir ein Nullmodell, in welchem wir die Load Bedingung weglassen (aud 0 fixieren).
Der grosse Unterschied zwischen Bayesianischer und frequentistischer Statistik ist (etwas vereinfacht) ausgedrückt:
Bei der frequentistischen Statistik erhalten wir nur eine Punktschätzung der Parameter, ohne etwas über deren Vereilung aussagen zu können (sie haben gar keine Verteilung). Wir würde evtl. gerne etwas darüber aussagen, aber wir dürfen nicht.
Bei der Bayesianischen Statistik erhalten wir eine Verteilung über alle möglichen Werte. Dies alleine erlaubt es uns schon, sehr informative Aussagen zu machen, bevor wir überhaupt daran denken, eine Hypothese mittels Modellvergleich zu testen.
If you see mistakes or want to suggest changes, please create an issue on the source repository.
Text and figures are licensed under Creative Commons Attribution CC BY 4.0. Source code is available at https://github.com/kogpsy/neuroscicomplab, unless otherwise noted. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".
For attribution, please cite this work as
Ellis (2021, June 22). neuroscicomplab: Übung 2: Lösung. Retrieved from https://kogpsy.github.io/neuroscicomplab/solution-2.html
BibTeX citation
@misc{ellis2021übung, author = {Ellis, Andrew}, title = {neuroscicomplab: Übung 2: Lösung}, url = {https://kogpsy.github.io/neuroscicomplab/solution-2.html}, year = {2021} }