Tutorial i logistisk regresjon (Gjøres i timen + som øvelse utenom)

Author

Henrik Sveinsson

Tutorial
Vi skal jobbe med denne tutorial-oppgaven i undervisningen, så denne trenger dere ikke gjøre på forhånd.

I leseleksa så dere på logistisk regresjon og på hvordan man kan validere en modell. Dette skal vi nå jobbe med. Vi skal bruke logistisk regresjon til å klassifisere individer som gode eller dårlige betalere av kredittkortregningen sin.

Logistisk regresjon er en klassifiseringsmetode. Det vil si at vi ønsker å predikere kategoriske utfall. Altså utfall slik som kjønn (mann/kvinne), blodtype (A/B/AB/0) osv. Det som kjennetegner slike utfall er at de ikke enkelt kan tilordnes en numerisk verdi på en skala. Det gir ikke mening å si at blodtype B ligger midt mellom A og AB. De er bare forskjellige blodtyper. Noen ganger kan det være uklart om et utfall må være kategorisk eller om det kunne vært numerisk. Det gjelder i tilfeller der vi vet hvordan vi skal sortere kategoriene. I slike tilfeller kan det gi mening å modellere kategoriske utfall som numeriske utfall.

Videoløsning

Her er video med løsning av en tidligere, men ganske lik, versjon av denne tutorial-oppgaven.

Kategorisk vs. numerisk

Hvilke av følgende utfall er kategoriske og hvilke er numeriske?

  • Temperatur
  • Navn på by
  • Vindstyrke
  • Vindretning
  • Politisk parti
  • Øltype
  • Karakterer
  • Farge
  • Kjønn

Logistisk/sigmoid funksjon

Plott den logistiske funksjonen (s. 139 i ITSL). Hvorfor er denne funksjonen egnet til å predikere et binært kategorisk utfall?

Parametrene \(\beta_0\) og \(\beta_1\)

Uforsk hvordan parametrene \(\beta_0\) og \(\beta_1\) flytter på funksjonen.

Datasett med kredittkortmislighold

Last inn default-datasettet (zenodo.org/record/6199560/files/default.csv). Plott mislighold mot hvor mye kredittkortlån en person har (balance). Ser du noen sammenheng i dataene?

Litt starthjelp her:

import pandas as pd

# Load the dataset
url = 'https://zenodo.org/record/6199560/files/default.csv'
data = pd.read_csv(url)

Datavisualisering

Bruk funksjonen np.histogram til å lage et histogram over hvem som misligholder og ikke. Bruk deretter histogramverdiene til å regne ut hvor stor andel som misligholder kridittkortlånene innenfor hvert intervall av balance. Altså for hvert intervall i histogrammet.

Vi kan hente ut arrayer med true/false på mislighold på denne måten:

import numpy as np
x = np.linspace(0, 3000, 100)
df_yes = data[data["default"] == "Yes"]
df_no = data[data["default"] == "No"]

Tilpasse \(\beta_0\) og \(\beta_1\)

Prøv å finne gode verdier for parametrene \(\beta_0\) og \(\beta_1\) slik at du får tegnet en logistisk funksjon som følger dataene brukbart. Trenger ikke å fintune helt, bare finne en strek som er sånn noen lunde på rett sted.

Automatisk tilpassing

Bruk scikit-learn sin metode for å gjøre logistisk regresjon for mislighold som funsjon av balansen på kredittkortet.

Litt kode til å komme i gang:

from sklearn.linear_model import LogisticRegression
my_regressor = LogisticRegression()
my_fit = my_regressor.fit(x.reshape(-1,1), y.reshape(-1,1))

Men sett inn riktige tall! Det kjipeste med koden over er at LogisticRegressionsin fit-funksjon forventer å få en array med potensielt flere prediktorer, ikke bare én (som her er “balance”). Derfor vil den ha en array med arrayer, og vi må gjøre .reshape for å lage en array med arrayer av lengde 1. Det er som å pakke bamsemums i cellofan før de går i godteposen.

Om tilpasningen har gått riktig, vil du nå kunne finne igjen \(\beta_0\) og \(\beta_1\) som henholdsvis my_regressor.intercept_ og my_regressor.coef_.

Plott deretter den logistiske funksjonen sammen med grafen som viser andel “yes” for å verifisere at du har fått riktige koeffisienter.

Skriv også opp, med tall, hva som er likningen som beskriver modellen din for mislighold av kredittkortgjeld.

Går det an å si noe vettugt om verdien på koeffisientene opp mot hva vi ser i plottet?

Multippel logistisk regresjon

Til nå har vi tenkt av vi modellerer sannsynligheten for å misligholde kun som en funksjon av én forklaringsvariabel \(x_1\), som er hvor stor kredittkortgjeld en person har. \[f(x) = \frac{e^{\beta_0 + \beta_1 x_1}}{1 + e^{\beta_0 + \beta_1 x_1}}\]

Vi skal nå utvide til også å ta med on den som har kredittkortet er student eller ikke:

\[f(x) = \frac{e^{\beta_0 + \beta_1 x_1 + \beta_2 x_2}}{1 + e^{\beta_0 + \beta_1 x_1 + \beta_2 x_2}}\]

der \(x_2\) inneholder enten tallet 1, smo betyr student eller tallet 0, som betyr ikke student.

For å kunne sende forklaringsvariablene våre til LogisticRegression sin fit-funksjon, må vi pakke dataene på en måte som den godtar. Det gjør vi slik:

x_1 = data["balance"].array
x_2 = data["student"].array == "Yes"
y = data["default"].array == "Yes"
X = np.array([x_1, x_2]).T

Print først data. Print så x_1, x_2, y og X, og forklar hva vi har gjort med dataene våre.

Gjør så logistisk regresjon på datasettet og les ut koeffisientene \(\beta_0, \beta_1\) og \(\beta_2\).

Plott så modellen som funsjon av "balance" for studenter og ikke-studenter separat.

  • På hvilken måte kan kredittkortselskapet bruke det om en kunde er student eller ikke til å sette en fornuftig kredittgrense?
  • Hva sier verdien av \(\beta_2\) om hva det å være student har å si for sannsynligheten for å ikke betale kredittkortet sitt?