{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7ba05a39",
   "metadata": {},
   "source": [
    "# Simulationsstudie: Diebstahlerkennung eines Autos in Echtzeit\n",
    "\n",
    "**Name:** Yann Ahlgrim  \n",
    "\n",
    "In dieser Simulationsstudie wird ein Modell entwickelt, das anhand von Fahrverhaltensdaten erkennt, ob ein anderer Fahrer als üblich am Steuer sitzt. Ziel ist es, eine Wahrscheinlichkeit für einen Fahrerwechsel zu schätzen und bei hoher Wahrscheinlichkeit eine Diebstahlwarnung auszugeben. Die Studie umfasst die Generierung einer synthetischen Grundgesamtheit, die Simulation der Data Scientist Perspektive und die Analyse der Modellgüte."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f04292ef",
   "metadata": {},
   "source": [
    "## Erzeugung der Grundgesamtheit"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5fe9381",
   "metadata": {},
   "source": [
    "### Datengrundlage\n",
    "\n",
    "#### Erklärende Variablen:\n",
    "1. **Durchschnittsgeschwindigkeit (metrisch):** Durchschnittliche Fahrgeschwindigkeit (z.B. über eine Fahrt oder ein Zeitfenster). Natürliche Verteilung z. B. etwa normal um ungefähr 47 km/h (29 mph) mit breiter Streuung. Aggressive Fahrer neigen tendenziell zu höheren Mittelwerten. Diese Variable ist voraussichtlich prädiktiv, da ein anderer Fahrer oft abweichende Geschwindigkeitsprofile hat\n",
    "    \n",
    "    → Die Verteilung der Variable wurde basierend auf dieser Studie in USA erstellt: https://www.nhtsa.gov/sites/nhtsa.gov/files/100carmain.pdf (100 Autos, 241 Fahrer)\n",
    "    \n",
    "2. **Längsbeschleunigung (metrisch):** Maß für das Beschleunigungsverhalten (z.B. Wurzel aus mittlerem Quadrat der Längsbeschleunigung über die Fahrt). Naturalistisch gesammelte Daten zeigen, dass Beschleunigungsprofile relevant für Fahrstil sind. Bei älteren Fahrern wurden insbesondere Längsbeschleunigungsmuster als informativer befunden. Wir simulieren etwa eine Verteilung um Null mit positiver Spitze (Fahrerspezifikationen). Moderate Abhängigkeit zu Bremsereignissen durch aggressives Fahrverhalten.\n",
    "→ Die Erkenntnisse basieren auf diesem Report vom Louisiana Transportation Research Center: https://www.ltrc.lsu.edu/pdf/2017/FR_580.pdf\n",
    "3. **Harte Bremsmanöver (metrisch):** Harte Bremsmanöver sind Fahrmanöver mit hoher negativer Beschleunigung (oft >0,3g). Tesla definiert beispielsweise „Hard Braking“ ab etwa 0,3g Bremsverzögerung (https://www.findmyelectric.com/blog/tesla-safety-score-beta-explained). Wir modellieren diese Zahl z.B. Poisson-verteilt mit kleinem Mittelwert (einige Ereignisse pro 100 km zb). Harte Bremsungen korrelieren moderat mit aggressiven Kurvenfahren. Diese Variable ist prädiktiv (abweichender Fahrer bremst anders).\n",
    "4. **Aggressive Kurvenfahrten (metrisch):** Anzahl oder Rate von extremen Kurvenmanövern (z.B. seitliche Beschleunigung >0,4g). Tesla definiert so „aggressives Kurvenfahren“ (https://www.findmyelectric.com/blog/tesla-safety-score-beta-explained/). Wir simulieren z.B. eine Poisson-Verteilung mit sehr kleinem Mittelwert (im Schnitt wenig Kurven mit >0,4g). Diese Variable ist prädiktiv, da ein fremder Fahrer oft anders (bzw aggressiver) durch Kurven fährt.\n",
    "\n",
    "#### Nicht Erklärende Variablen:\n",
    "5. **Straßentyp (nominal, 3 Kategorien):**\n",
    "    1. auf den deutschen Autobahnen wird ungefähr 30-33% der gesamten Kraftfahrzeugleistung abgewickelt (https://www.udv.de/resource/blob/130998/103ded9eaf113e61851a464843e306d2/79-vs-auf-bab-data.pdf)\n",
    "    2.  43 % der Pkw-Kilometer werden außerorts zurückgelegt (https://openumwelt.de/server/api/core/bitstreams/07bd23f9-ff0a-41e5-b89b-8d7baf0a5c36/content)\n",
    "    3. demnach bleiben ungefähr 24-27% als innerorts zurückgelegte Strecke\n",
    "    \n",
    "    Wir modellieren dies als nominale Zufallsvariable (z.B. multinomial mit diesen Anteilen). Straßentyp beeinflusst zwar Tempo und Beschleunigung, ist aber selbst nur eine Kontextinformation, **kein direkter Prädiktor** für einen Fahrertausch.\n",
    "    \n",
    "6. **Wetterbedingungen (nominal, 3 Kategorien):** Diese Kontextvariable beschreibt die Witterungsverhältnisse während einer Fahrt – trocken, nass oder winterlich (Schnee/Eis). Sie wird als **nicht erklärende Variable** im Modell geführt, da sie nicht direkt auf die Identität des Fahrers hinweist, aber realistische Umweltbedingungen abbildet. Die Einteilung basiert auf Daten des Statistischen Bundesamtes: Etwa 70–75 % aller Fahrten finden unter trockenen Bedingungen statt, 20–25 % bei Nässe und unter 5 % bei Schnee oder Glätte.\n",
    "\n",
    "Von der Mobilitätsstudie 2017 in Deutschland sind folgende Variablen abzuleiten (https://www.bmv.de/SharedDocs/DE/Anlage/G/mid-ergebnisbericht.pdf):\n",
    "\n",
    "1. **Fahrstrecke (metrisch):** Länge der Fahrt in Kilometern. Aus dem Mobilitätsverhalten in Deutschland beträgt die durchschnittliche Weglänge ca. 12 km. Wir simulieren die Fahrstrecke z.B. lognormal um diesen Mittelwert. Diese Variable steht nur indirekt mit „Fahrverhalten“ im Sinne von Nutzung  in Zusammenhang und ist **nicht erklärend** für den Fahrertausch.\n",
    "2. **Wochentag (nominal, 2–3 Kategorien):** Wochentag oder Woche vs. Wochenende. Verkehrsdaten zeigen z.B. an Wochentagen ca. 3,7 Wege pro Person/Tag, an Sonntagen nur etwa 2,1 Wege. Man kann Kategorien *Werktag* vs *Wochenende* (oder Mo/Di–Fr/Sa/So) bilden. Diese Variable ist für einen Fahrerwechsel irrelevant (sie gehört zum Fahrtenkontext, nicht zur Fahrverhalten)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1468207b",
   "metadata": {},
   "source": [
    "### Bibliotheken Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "97ba29a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import der benötigten Bibliotheken\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from scipy.stats import norm, multinomial, poisson, lognorm, bernoulli\n",
    "\n",
    "np.random.seed(11)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27947656",
   "metadata": {},
   "source": [
    "### Erklärende Variablen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "61247da5",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 1_000_000\n",
    "\n",
    "# 1. Durchschnittsgeschwindigkeit (normalverteilt um 47 km/h)\n",
    "speed_mean = 47\n",
    "speed_std = 10\n",
    "avg_speed = np.random.normal(loc=speed_mean, scale=speed_std, size=N)\n",
    "\n",
    "# 2. Längsbeschleunigung (symmetrisch um 0, leicht positiv verzerrt)\n",
    "long_acc = np.random.normal(loc=0.2, scale=0.5, size=N)\n",
    "\n",
    "# 3. Harte Bremsmanöver (Poisson, durchschnittlich 3 pro 100km)\n",
    "hard_brakes = np.random.poisson(lam=2.5, size=N)\n",
    "\n",
    "# 4. Aggressive Kurvenfahrten (Poisson, kleiner Mittelwert)\n",
    "aggressive_curves = np.random.poisson(lam=0.8, size=N)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0ee5dad",
   "metadata": {},
   "source": [
    "### Nicht Erklärende Variablen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d6b78d6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 5. Straßentyp (Multinomial: 33% Autobahn, 43% außerorts, 24% innerorts)\n",
    "road_type_probs = [0.33, 0.43, 0.24]\n",
    "road_type = np.random.choice(['Autobahn', 'Ausserorts', 'Innerorts'], size=N, p=road_type_probs)\n",
    "\n",
    "# 6. Wetter (Multinomial: 72% trocken, 23% nass, 5% Schnee)\n",
    "weather_probs = [0.72, 0.23, 0.05]\n",
    "weather = np.random.choice(['Trocken', 'Nass', 'Schnee'], size=N, p=weather_probs)\n",
    "\n",
    "# 7. Fahrstrecke (Lognormal mit Mittelwert ca. 12km)\n",
    "mu = np.log(12) - 0.5 * 0.4**2\n",
    "sigma = 0.4\n",
    "trip_distance = np.random.lognormal(mean=mu, sigma=sigma, size=N)\n",
    "\n",
    "# 8. Wochentag (Werktag oder Wochenende)\n",
    "weekday = np.random.choice(['Werktag', 'Wochenende'], size=N, p=[0.7, 0.3])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1b403f2",
   "metadata": {},
   "source": [
    "### Abhängigkeiten zwischen erklärenden Variablen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f10e1366",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Korrelation 1: Geschwindigkeit beeinflusst aggressive Kurven leicht\n",
    "aggressive_curves = np.random.poisson(lam=0.005 * avg_speed + 0.5)\n",
    "\n",
    "# Korrelation 2: Harte Bremsen beeinflussen Längsbeschleunigung\n",
    "long_acc = 0.2 + 0.1 * hard_brakes + np.random.normal(0, 0.3, size=N)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10570201",
   "metadata": {},
   "source": [
    "### Zielvariable: Fahrerwechsel (1 = ja / 0 = nein)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3791cb88",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Regressionskoeffizienten (logistische Regression)\n",
    "beta_0 = -3  # Basiswahrscheinlichkeit\n",
    "beta_speed = 0.05\n",
    "beta_acc = 0.4\n",
    "beta_brake = 0.3\n",
    "beta_curve = 0.6\n",
    "\n",
    "# Lineare Kombination + Störterm\n",
    "logit = (\n",
    "    beta_0\n",
    "    + beta_speed * avg_speed\n",
    "    + beta_acc * long_acc\n",
    "    + beta_brake * hard_brakes\n",
    "    + beta_curve * aggressive_curves\n",
    ")\n",
    "\n",
    "# Wahrscheinlichkeiten mit Sigmoid\n",
    "pi = 1 / (1 + np.exp(-logit))\n",
    "\n",
    "# Zielvariable: Fahrerwechsel\n",
    "driver_change = np.random.binomial(n=1, p=pi)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be2c0596",
   "metadata": {},
   "source": [
    "### Als Dataframe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ab858b82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>avg_speed</th>\n",
       "      <th>long_acc</th>\n",
       "      <th>hard_brakes</th>\n",
       "      <th>aggressive_curves</th>\n",
       "      <th>road_type</th>\n",
       "      <th>weather</th>\n",
       "      <th>trip_distance</th>\n",
       "      <th>weekday</th>\n",
       "      <th>driver_change</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>64.494547</td>\n",
       "      <td>0.472002</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Autobahn</td>\n",
       "      <td>Trocken</td>\n",
       "      <td>9.538071</td>\n",
       "      <td>Wochenende</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>44.139270</td>\n",
       "      <td>0.296863</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>Innerorts</td>\n",
       "      <td>Trocken</td>\n",
       "      <td>11.746167</td>\n",
       "      <td>Werktag</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>42.154349</td>\n",
       "      <td>0.806673</td>\n",
       "      <td>4</td>\n",
       "      <td>2</td>\n",
       "      <td>Innerorts</td>\n",
       "      <td>Trocken</td>\n",
       "      <td>4.822888</td>\n",
       "      <td>Werktag</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20.466814</td>\n",
       "      <td>0.512172</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Innerorts</td>\n",
       "      <td>Trocken</td>\n",
       "      <td>12.270326</td>\n",
       "      <td>Werktag</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>46.917154</td>\n",
       "      <td>0.621950</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>Ausserorts</td>\n",
       "      <td>Trocken</td>\n",
       "      <td>16.073552</td>\n",
       "      <td>Wochenende</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   avg_speed  long_acc  hard_brakes  aggressive_curves   road_type  weather  \\\n",
       "0  64.494547  0.472002            1                  1    Autobahn  Trocken   \n",
       "1  44.139270  0.296863            2                  0   Innerorts  Trocken   \n",
       "2  42.154349  0.806673            4                  2   Innerorts  Trocken   \n",
       "3  20.466814  0.512172            1                  1   Innerorts  Trocken   \n",
       "4  46.917154  0.621950            3                  2  Ausserorts  Trocken   \n",
       "\n",
       "   trip_distance     weekday  driver_change  \n",
       "0       9.538071  Wochenende              1  \n",
       "1      11.746167     Werktag              0  \n",
       "2       4.822888     Werktag              1  \n",
       "3      12.270326     Werktag              0  \n",
       "4      16.073552  Wochenende              1  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'avg_speed': avg_speed,\n",
    "    'long_acc': long_acc,\n",
    "    'hard_brakes': hard_brakes,\n",
    "    'aggressive_curves': aggressive_curves,\n",
    "    'road_type': road_type,\n",
    "    'weather': weather,\n",
    "    'trip_distance': trip_distance,\n",
    "    'weekday': weekday,\n",
    "    'driver_change': driver_change\n",
    "})\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6366cd7c",
   "metadata": {},
   "source": [
    "### Visualisierung der metrischen erklärenden Variablen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a08fa8f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 123668 characters]",
      "text/plain": [
       "<Figure size 1400x1000 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(2, 2, figsize=(14, 10))\n",
    "\n",
    "sns.histplot(df['avg_speed'], bins=50, kde=True, ax=axes[0, 0], color='skyblue')\n",
    "axes[0, 0].set_title('Verteilung: Durchschnittsgeschwindigkeit')\n",
    "\n",
    "sns.histplot(df['long_acc'], bins=50, kde=True, ax=axes[0, 1], color='lightgreen')\n",
    "axes[0, 1].set_title('Verteilung: Längsbeschleunigung')\n",
    "\n",
    "sns.histplot(df['hard_brakes'], bins=30, kde=False, ax=axes[1, 0], color='salmon')\n",
    "axes[1, 0].set_title('Verteilung: Harte Bremsmanöver')\n",
    "\n",
    "sns.histplot(df['aggressive_curves'], bins=30, kde=False, ax=axes[1, 1], color='orange')\n",
    "axes[1, 1].set_title('Verteilung: Aggressive Kurvenfahrten')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "777f980e",
   "metadata": {},
   "source": [
    "### Zielvariable Verteilung"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f3b72ccf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 28040 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.countplot(x='driver_change', data=df, palette='Set2')\n",
    "plt.title('Verteilung der Zielvariable: Fahrerwechsel')\n",
    "plt.xlabel('Fahrerwechsel (0 = nein, 1 = ja)')\n",
    "plt.ylabel('Anzahl')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
