---
format:
  pdf:
    fontsize: 11pt
    number-sections: true
    include-in-header: ../MV_Header_Seminar.tex
lang: de
---


\setcounter{section}{7}
# Prädiktive Modellierung


## Mathematische Grundlagen

Gegeben sei ein *binärer Klassifikationsdatensatz* mit einer Menge von *Trainingsdatenpunkten*

\begin{equation} \label{eq:BKDS}
\mathcal{D} = \left\lbrace (x_1, y_1), \ldots, (x_n, y_n) \right\rbrace \; ,
\end{equation}

wobei $x_i \in \mathbb{R}^m$, $i = 1,\ldots,n$ ein $m$-dimensionaler *Featurevektor* sei und $y_i \in \left\lbrace 0, 1 \right\rbrace$, $i = 1,\ldots,n$ den Wert einer skalaren *Labelvariable* darstelle, wobei der Wert 1 für "positive Fälle" und der Wert 0 für "negative Fälle" stehe.

Die Bezeichnungen "positiv" und "negativ" sind aber lediglich formal zu verstehen. Beispiele für vorherzusagende Labelvariablen (1/0) etwa wären "erkrankt/gesund", "erzielt Therapieerfolg/bleibt erkrankt" oder "ältere/jüngere Person".

Ziel der *prädiktiven Modellierung* ist die Kalibrierung einer Funktion $f(x): \mathbb{R}^m \rightarrow \left\lbrace 0, 1 \right\rbrace$, die prädizierte Labels $f(x_i) = \hat{y}_i$ ergibt, wenn man Featurevektoren einsetzt. Mit der Methode der *leave-one-out cross-validation* (LOO-CV) wird ein prädiktives Modell wiederholt an einem Datensatz trainiert und getestet, wobei in jeder Wiederholung der Trainingsdatensatz aus allen experimentellen Einheiten bis auf eine besteht und die ausgelassene experimentelle Einheit den Testdatensatz bildet.

Liegen für einen Trainingsdatensatz wahre Labels $y_i$ und prädizierte Labels $\hat{y}_i = f(x_i)$ vor, kann die Klassifikationsperformanz des prädiktiven Modells evaluiert werden. Dazu werden die Einträge der binären Konfusionsmatrix bestimmt

\begin{equation} \label{eq:TN-FP-FN-TP}
\begin{split}
\mathrm{TN} &= \left| \left\lbrace (x_i, y_i) \; | \; y_i = 0 \land f(x_i) = 0 \right\rbrace \right| \\
\mathrm{FP} &= \left| \left\lbrace (x_i, y_i) \; | \; y_i = 0 \land f(x_i) = 1 \right\rbrace \right| \\
\mathrm{FN} &= \left| \left\lbrace (x_i, y_i) \; | \; y_i = 1 \land f(x_i) = 0 \right\rbrace \right| \\
\mathrm{TP} &= \left| \left\lbrace (x_i, y_i) \; | \; y_i = 1 \land f(x_i) = 1 \right\rbrace \right| \; ,
\end{split}
\end{equation}

wobei $\left| \left\lbrace \cdot \right\rbrace \right|$ die Anzahl der Elemente der entsprechenden Menge bezeichne (z.B. der Menge der tatsächlich negativen Fälle, $y_i = 0$, die als positiv klassifiziert wurden, $f(x_i) = 1$; false positives, FP).

\pagebreak
Folgende Klassifikationsmetriken, die in der Vorlesung detailliert besprochen wurden, können aus den Einträgen der Konfusionsmatrix berechnet werden:

- true positive rate (TPR), false positive rate (FPR), true negative rate (TNR) und false negative rate (FNR)

- positive predictive value (PPV), false discovery rate (FDR), negative predictive value (NPV) und false omission rate (FOR)

- accuracy (ACC), balanced accuracy (BAC), Precision, Recall, F1-Score (F1)


## Analyse in R

Die Datei `FADE_SAME.csv` enthält den in der ersten Seminarsitzung vorgestellten Datensatz. Erklären Sie die Funktion des folgenden R-Codes:

\footnotesize
```{r, echo = T, eval = T, results = 'hide'}
# Daten einlesen
fname = 'FADE_SAME.csv'                             # Dateiname
D     = read.csv(fname)                             # Dataframe

# Datenmatrix extrahieren
rows  = startsWith(D$subject, 'subA')               # Personen aus Studie A
cols  = c('novelty.SAME', 'memory.SAME')            # Definition Variablen
X     = t(as.matrix(D[rows,cols]))                  # Datenmatrix
y     = t(as.matrix(D$age[rows]))                   # gruppendefinierende Variable
y     = 0*(y <= 35) + 1*(y > 35)                    # Labelvariable
print(dim(X))                                       # Überprüfung Datenmatrix
print(dim(y))                                       # Überprüfung Labelvariable
```
\normalsize


## Erste Programmieraufgabe

Visualisieren Sie die in der Datenmatrix enthaltenen Variablen getrennt nach, d.h. unter Berücksichtigung der Werte der Labelvariable. Gehen Sie dazu wie folgt vor:

- Orientieren Sie sich für diese Aufgabe am Abschnitt 1.4 des Arbeitsblatts (1) *Multiple Regression*, weichen Sie jedoch wie folgt vom dortigen Vorgehen ab:

- Die Variable auf der x-Achse soll die erste Zeile von $X$, die Variable auf der y-Achse soll die zweite Zeile von $X$ sein.

- Die Variablen sollen getrennt für junge Probanden (indiziert durch \verb|y==0|) und ältere Probanden (indiziert durch \verb|y==1|) dargestellt werden.

- Es sollen keine Regressionsgeraden dargestellt werden.

- Beide Achsen sollen jeweils von $-3$ bis $+3$ gehen.

- Achsenbeschriftungen und Legende sollen den dargestellten Variablen angepasst werden.

- Erzeugen und speichern Sie die Abbildung. Mutmaßen Sie auf Grundlage des dargestellten Trainingsdatensatzes, inwieweit die Variable "Altersgruppe" sich aus den Variablen "Novelty-SAME" und "Memory-SAME" klassifizieren lässt. Sie sollten in etwa folgende Abbildung erhalten:

\footnotesize
```{r, echo = F, eval = F}
# Abbildungsparameter
library(latex2exp)
par(
    family     = "sans",
    pty        = "m",
    bty        = "o",
    lwd        = 1,
    las        = 1,
    mgp        = c(2,1,0),
    xaxs       = "i",
    yaxs       = "i",
    cex        = 1.2)

# Punktwolken
plot(X[1,y==0], X[2,y==0],
    pch        = 16,
    col        = "red",
    xlab       = "Novelty-SAME-Score",
    ylab       = "Memory-SAME-Score",
    xlim       = c(-3, +3),
    ylim       = c(-3, +3))
points(X[1,y==1], X[2,y==1],
    pch        = 16,
    col        = "blue")

# Legende
legend("topleft", c("junge Erwachsene (y = 0)", "ältere Erwachsene (y = 1)"),
    lty        = 0,
    pch        = 16,
    col        = c("red", "blue"),
    bty        = "n",
    cex        = 1)

# Speichern
dev.copy2pdf(
    file        = "Abbildungen/Prädiktive_Modellierung_1.pdf",
    width       = 9,
    height      = 9)
```
\normalsize

![Novelty-SAME-Score und Memory-SAME-Score, getrennt nach Altersgruppe.]("Abbildungen/Prädiktive_Modellierung_1.pdf"){#prädiktive-modellierung-1 fig-align="center" width=80%}


\pagebreak
## Analyse in R

Im zweiten Teil wollen wir nun eine prädiktives Modell auf Grundlage der Datenmatrix $X$ und der Labelvariable $y$ schätzen. Erklären Sie dazu zunächst den folgenden R-Code und die Analyse, die er durchführt:

\footnotesize
```{r, echo = T, eval = T, results = 'hide'}
# Vorbereitung Datenanalyse
m       = nrow(X)                                   # Anzahl Features
n       = length(y)                                 # Anzahl Datenpunkte
L       = c(0,1)                                    # Klassenlabels
y_pred  = matrix(rep(NaN,n*2), nrow = n)            # wahre und prädizierte Label

# leave-one-out cross-validation
for (i in 1:n) {                                    # Iteration über Datenpunkte

    # Datensatz partitionieren
    x_train     = as.matrix(X[,-i])                 # i-ter Featurevektor nicht im Trainingsdatendatz
    y_train     = as.matrix(y[,-i])                 # i-tes Label nicht im Trainingsdatendatz
    x_test      = as.matrix(X[, i])                 # i-ter Featurevektor als Testdatenpunkt
    y_test      = as.matrix(y[, i])                 # i-ites Label als Testdatenpunkt
    y_pred[i,1] = y_test                            # wahres Label des i-ten Datenpunkts

    # "Training": klassenspezfische Mahalanobisdistanz berechnen
    D           = matrix(rep(NaN,2), ncol = 2)      # Vektor klassenspezifischer Mahalanobisdistanzen
    for (l in L) {                                  # Iteration über Klassen
        Xl      = x_train[,y_train == l]            # x^{(i)} für Label l
        nl      = ncol(Xl)                          # Anzahl Realisierungen
        I_nl    = diag(nl)                          # Einheitsmatrix I_n
        J_nl    = matrix(rep(1,nl^2), nrow = nl)    # 1_{nn}
        x_bar   = (1/nl)* Xl %*% J_nl[,1]           # Stichprobenmittel
        C       = (1/(nl-1)) *                      # Stichprobenkovarianzmatrix
                  (Xl %*% (I_nl-(1/nl)*J_nl) %*% t(Xl))
        D[l+1]  = t(x_test - x_bar) %*% solve(C) %*%# Mahalanobisdistanz
                   (x_test - x_bar)
    }

    # "Test": Label des Testdatenpunkts prädizieren
    if (D[1] <= D[2]) {y_pred[i,2] = 0}             # prädiziertes Label
    else              {y_pred[i,2] = 1}
}
```
\normalsize


\pagebreak
## Zweite Programmieraufgabe

Evaluieren Sie die Klassifikationsperformanz, indem Sie die sich aus den wahren und prädizierten Labels ergebenden Klassifikationsmetriken berechnen. Gehen Sie dazu wie folgt vor:

- Berechnen Sie die Einträge der $2 \times 2$ Konfusionsmatrix, indem Sie diejenigen Fälle summieren, in denen die prädizierten Labels in der zweiten Spalte von \verb|y_pred| den Wert 0 oder 1 haben, unter der Bedingung, dass die wahren Labels in der ersten Spalte von \verb|y_pred| den Wert 0 oder 1 haben. Die Anzahl der true negatives (TN) beispielsweise ergibt sich als \verb|sum(y_pred[y_pred[,1] == 0, 2] == 0)|. Berechnen Sie auf dieselbe Art und Weise die Anzahl der false positives (FP), false negatives (FN) und true positives (TP).

- Berechnen Sie mithilfe der in der Vorlesung gegebenen Formeln die Klassifikationsmetriken true positive rate (TPR), false positive rate (FPR), true negative rate (TNR) und false negative rate (FNR).

- Berechnen Sie mithilfe der in der Vorlesung gegebenen Formeln die Klassifikationsmetriken positive predictive value (PPV), false discovery rate (FDR), negative predictive value (NPV) und false omission rate (FOR).

- Berechnen Sie mithilfe der in der Vorlesung gegebenen Formeln die Klassifikationsmetriken accuracy (ACC), balanced accuracy (BAC) und F1-Score (F1).

- Geben Sie die Resultate ihrer Analyse aus. Sie sollten folgende Ergebnisse erhalten:

\footnotesize
```{r, echo = F, eval = T}
# Evaluation der Klassifikationsperformanz
TN     = sum(y_pred[y_pred[,1] == 0, 2] == 0)       # true negatives
FP     = sum(y_pred[y_pred[,1] == 0, 2] == 1)       # false positives
FN     = sum(y_pred[y_pred[,1] == 1, 2] == 0)       # false negatives
TP     = sum(y_pred[y_pred[,1] == 1, 2] == 1)       # true positives

TPR    = (TP)/(TP+FN)                               # true positive rate (sensitivity)
FPR    = (FP)/(TN+FP)                               # false positive rate
TNR    = (TN)/(TN+FP)                               # true negative rate (specificity)
FNR    = (FN)/(TP+FN)                               # false negative rate

PPV    = (TP)/(TP+FP)                               # positive predictive value
FDR    = (FP)/(TP+FP)                               # false discovery rate
NPV    = (TN)/(TN+FN)                               # negative predictive value
FOR    = (FN)/(TN+FN)                               # false omission rate

Acc    = (TN+TP)/(TN+FP+FN+TP)                      # accuracy
BAcc   = (TPR+TNR)/2                                # balanced accuracy
Prec   = (TP)/(TP+FP)                               # precision
Rec    = (TP)/(TP+FN)                               # recall
F1     = 2*((Prec*Rec)/(Prec+Rec))                  # F1 Score

# Ausgabe der Ergebnisse
cat(  "true positive rate (sensitivity) : ", round(TPR,  digits = 4), 
    "\nfalse positive rate              : ", round(FPR,  digits = 4), 
    "\ntrue negative rate (specificity) : ", round(TNR,  digits = 4),
    "\nfalse negative rate              : ", round(FNR,  digits = 4),
    "\npositive predictive value        : ", round(PPV,  digits = 4),  
    "\nfalse discovery rate             : ", round(FDR,  digits = 4),
    "\nnegative predictive value        : ", round(NPV,  digits = 4),
    "\nfalse omission rate              : ", round(FOR,  digits = 4),
    "\nAccuracy                         : ", round(Acc,  digits = 4),
    "\nBalanced Accuracy                : ", round(BAcc, digits = 4),
    "\nF1 Score                         : ", round(F1,   digits = 4), "\n")
```
\normalsize


\pagebreak
## Lückentext

Füllen Sie mit den in der Übung gewonnenen Erkenntnissen den folgenden Lückentext aus und präsentieren Sie die Ergebnisse im Seminar:

\vspace{1em}
**Lückentext:** Ein binärer Klassifikationsdatensatz besteht aus einer Menge von Trainingsdatenpunkten, wobei jeder Trainingsdatenpunkt aus einem \underline{ $m$-dimensionalen Featurevektor } $x_i$ und einem \underline{ skalaren Klassenlabel } $y_i$ besteht. Eine beliebte Methode zur Evaluation eines prädiktiven Modells am Trainingsdatensatz ist \underline{ leave-one-out cross-validation }. Vorhergesagte Werte von $y_i$ bezeichnet man als \underline{ prädizierte Labels }. Der vorliegende Trainingsdatensatz besteht aus \underline{ 259 } Datenpunkten, wobei jeder Featurevektor \underline{ 2 } Einträge hat. Nach *Nearest-Neighbor-Klassifikation* der Variable \underline{ Altersgruppe } aus den Variablen \underline{ Novelty-SAME } und \underline{ Memory-SAME } mittels *leave-one-out cross-validation* ergibt sich eine true positive rate (TPR, "Sensitivität") von \underline{ 0.7451 }, eine true negative rate (TNR, "Spezifizität") von \underline{ 0.8208 } und eine accuracy (ACC, "Genauigkeit") von \underline{ 0.7761 }.


## Mögliche Klausurfrage

Präsentieren Sie im Seminar folgende Klausurfrage und erklären Sie die richtige Antwort:

\vspace{1em}
**Frage:** Aus einer binären Klassifikation ergeben sich TN = 57, FP = 25, FN = 43, TP = 75 (TN = true negative, FP = false positive, FN = false negative, TP = true positive). Wie hoch ist der positive predictive value (PPV)?
\begin{enumerate}[a)]
\item 0.57
\item 0.25
\item 0.43
\item 0.75 $\checkmark$
\end{enumerate}


## Kinderwitz

Was mögen Autos am liebsten?

\begin{turn}{180}
Antwort: Parkplätzchen!
\end{turn}