---
title: "Tutorium 3"
format: pdf
editor: visual
---

## a , b, c: Setup

Pakete installieren und Daten laden.

```{r}
library(data.table)
library(ggplot2)
library(MASS)
football_data <- fread("../input/bundesliga_vorhersage.csv")
```

## d: Verteilung der Tore

```{r}
# Wir schauen uns die Daten an
print(head(football_data))

# Wir plotten die Daten, wie aus der Vorlesung bekannt
ggplot(football_data, aes(x = Marktwert_Differenz, y = Tore)) +
  geom_point() +
  geom_smooth(method = "glm", method.args = list(family = "poisson"), se = FALSE, color = "blue") +
  theme_minimal() +
  labs(title = "Verteilung der geschossenen Tore nach Marktwertdifferenz", subtitle = "Aus Sicht der Heimmannschaft", x = "Differenz zwischen den Marktwerten der Teams", y = "Tore")
```

## e: Schätzen eines einfachen linearen Modells

```{r}
# Schätzen eines einfachen linearen Modells
football_lm <- lm(Tore ~ Marktwert_Differenz + Heimspiel, data = football_data)
summary(football_lm)
prediction <- predict(football_lm, newdata = football_data)
print(prediction)

# Werden negative Werte vorhergesagt?
sorted_indices <- order(prediction)
lowest_predictions <- prediction[sorted_indices]
print(lowest_predictions[1:10])
```
Das ist vielleicht keine schöne Übersicht, aber wir sehen alle 612 simulierten Tore. Zudem sehen wir, dass einige wenige Werte negativ ausfallen können, was keinen Sinn ergibt, da 0 die Untergrenze für Tore ist (in einem Spiel).


## f: Poisson-Regression

```{r}
# Wir fitten ein Poisson-Modell mit Hilfe der GLM-Funktion
poisson_model <- glm(Tore ~ Marktwert_Differenz + Heimspiel, data = football_data, family = poisson())
summary(poisson_model)
```

## g: Interpretation der Koeffizienten

```{r}
# Wir betrachten die Koeffizienten des Poisson-Modells
coef(poisson_model)
```
Die Intercept Variable beschreibt einen allgemeinen Startwert, von dem wir unsere Schätzung aus starten.
Die Marktwertdifferenz beschreibt den Einfluss des Marktwertunterschieds auf die Anzahl der Tore.
Die Heimspielvariable beschreibt den Einfluss des Heimvorteils auf die Anzahl der Tore.


## h: Modellvalidierung

```{r}
# Wir entfernen die leeren Datenpunkte, der noch nicht ausgespielten Spieltage
football_data_complete <- football_data[!is.na(football_data$Tore), ]

# Wir berechnen die jeweiligen Residuen
football_data_complete$residuals <- residuals(poisson_model, type = "response")

# Wir plotten die Residuen für eine bessere Übersicht
ggplot(football_data_complete, aes(x = fitted(poisson_model), y = residuals)) +
  geom_point() +
  geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
  labs(title = "Residuenplot des Poisson-Modells")
```


## i: Negatives Binomialmodell

```{r}
# Erstellen des negativen Binomialmodells
neg_binom_model <- glm.nb(Tore ~ Marktwert_Differenz + Heimspiel, data = football_data)
summary(neg_binom_model)

# Wir vergleichen die Koeffizienten beider Modelle
coef(poisson_model)
coef(neg_binom_model)
```
Die Ergebnisse sind sehr nah beieinander. Die Abweichungen sind minimal.

## j: Monte Carlo

```{r}
# Fester Seed, um immer das gleiche Ergebnis zu erhalten
set.seed(12345)

# Tabellen data.table
Tabellen <- data.table()

# Monte Carlo Loop
for (i in 1:1000) {
  
# Wir starten jedes Mal mit den gleichen "sauberen" Daten
data_copy <- copy(football_data)

# Simulieren der Tore
simulierte_tore <- rpois(nrow(data_copy), lambda = predict(poisson_model, type = "response"))
data_copy$simulierte_tore <- simulierte_tore
data_copy[is.na(Tore), Tore := simulierte_tore]

# Extrahieren der Team-Namen
Teams <- unique(football_data$Team)

# Gegentore werden aufgenommen
for (i in 1:nrow(data_copy)) {
    # Find the index of the matching row
    matching_index <- which(data_copy$Spieltag == data_copy$Spieltag[i] & 
                              data_copy$Team == data_copy$Gegner[i] & 
                              data_copy$Gegner == data_copy$Team[i])
    data_copy$Gegentore[i] <- data_copy$Tore[matching_index]
}

# Punkte werden, basierend auf den Toren, zugewiesen
data_copy[, Punkte := ifelse(Tore > Gegentore, 3, ifelse(Tore == Gegentore, 1, 0))]

# Die Tabelle wird zusammengesetzt
Tabelle <- data_copy[, .(Punkte = sum(Punkte),
                         Tore = sum(Tore),
                         Gegentore = sum(Gegentore)), 
                     by = Team]
Tabelle[, Tordifferenz := Tore - Gegentore]

# Tabelle wird in aufsteigender Reihenfolge sortiert
setorder(Tabelle, -Punkte, -Tordifferenz, -Tore)

# Hinzufügen der "Platz"-Variable um diese am Ende zu mitteln
Tabelle[, Platz := .I]
Tabellen <- rbindlist(list(Tabellen, Tabelle))
}

# Zusammenfassen der Tabellen
Tabelle <- Tabellen[, .(Platz = mean(Platz), Punkte = mean(Punkte), Tore = mean(Tore), Gegentore = mean(Gegentore), Tordifferenz = mean(Tordifferenz)), by = Team]

# Sortierte Enttabelle
Endtabelle <- Tabelle[order(Tabelle$Platz), ]
Endtabelle
```

Unsere Monte-Carlo Simulation prognostiziert uns einen Abstieg des 1. FC Köln, und eine Relegationsteilnahme des VfL Bochum, zumindest dieser zweite Teil sieht in der Realität allerdings bereits unwahrscheinlich aus.

