Kredit Scoring, Teil 1

Kredit Scoring, Teil 1

In diesem und dem folgenden Beitrag möchte ich den Unterschied zwischen der klassischen Statistik und dem maschinellen Lernen herausarbeiten. Die Aufgabenstellung kommt dabei aus dem Bereich Kredit Scoring. Beide Techniken basieren auf einem Trainingsset.

Bei der klassischen Statistik basiert das Trainingsset auf einer repräsentativen Stichprobe und Modellannahmen. Diese Modellannahmen sind meist einfacher Natur und können so zur Steuerung von Aktivitäten eines Unternehmens genutzt werden.

Beim maschinellen Lernen bedient man sich ebenfalls eines Trainingssets. Als Ergebnis erhält man unterschiedliche Lösungsmodelle. Welches dieser Lösungsmodell ist nun optimal? Antwort darauf liefert das Testsample (nicht genutzte Trainingsdaten). Im Unterschied zum klassischen Modell sind diese Lösungmodelle meist nichtlinear und eher komplex. Sie werden daher seltener zur Steuerung von Aktivitäten eines Unternehmens genutzt. Das Hauptanwendungsgebiet sind klare Entscheidungen (Schwarz/Weiß, Kredit/kein Kredit, Newsletter/kein Newsletter, …).

Interessierte können sich für das Webinar “Kredit Scoring, Teil 1” eintragen. Das Webinar ist kostenfrei!

Wenn Sie dabei sind R zu lernen, betrachten Sie das Beispiel Kreditscoring als Anregung für die Möglichkeiten die Ihnen R bietet.

Einführung

Ein Kunde erhält einen Kredit und zahlt diesen in regelmäßigen Raten zurück. Dabei verdient der Kreditgeber an den Zinsen. Was passiert, wenn der Kunde in Zahlungsverzug gerät? Je nach Absicherung kann es für den Kreditgeber zu einem teilweisen oder auch totalen Ausfall des noch offenen Kreditbetrags kommen. Um diesem Risiko entgegen zu steuern, ermittelt der Kreditgeber mit Hilfe des Kreditscorings vor Abschluss des Vertrags die Wahrscheinlichkeit, dass ein solches Ereignis eintritt.

Für die Ermittlung der Wahrscheinlichkeit eines Zahlungsverzugs stehen mehrere Techniken zur Verfügung: Die klassische Vorgangsweise besteht in der Erstellung einer Scorekarte. Dabei werden jedem Merkmal Punkte zugeordnet. Überschreitet die Summe aller Scorepunkte einen bestimmten Wert, wird der Kredit genehmigt. Im Grenzfall erfolgt eine individuelle Entscheidung. In allen anderen Fällen wird der Kredit abgelehnt.

Für die Erstellung der Scorekarte benötigt man die Wahrscheinlichkeit für einen Zahlungsverzug. Der Zahlungsverzug wird im englischsprachigen Raum als Default bezeichnet. Als Statistiker würde man diese Wahrscheinlichkeit mit Hilfe einer logistischen Regression ermitteln. Als Data Scientist könnte diese Aufgabe mit Hilfe des maschinellen Lernens, unter Verwendung eines Entscheidungsbaumes, gelöst werden. Ich werde beide Techniken vorstellen.

In diesem und dem folgenden Beitrag geht es nicht um eine detaillierte Darstellung der Methoden; nur wenige Argumente werden erklärt. Ich möchte zeigen, wie Sie mit Hilfe der Sprache R mit wenigen Anweisungen dieses Problem auf elegante Weise lösen. In der Praxis stellt sich dieser Sachverhalt nicht so einfach dar. Viel Zeit wird in die Datenaufbereitung und Modellfindung investiert. Die Modelle müssen ständig auf ihre Aktualität hin geprüft und bei Bedarf angepasst werden. Oft existieren für unterschiedliche Marktsegmente auch unterschiedliche Scoringmodelle.

Lösung mittels klassischer Statistik

Ich beschreibe nun einen Lösungsweg mit Hilfe der klassischen Statistik. Dabei kommt die Methode der logistischen Regression zum Einsatz. Auf Grund der geringen Fallzahl an Kreditausfällen werden in der Praxis die Datensätze gewichtet. Für den Vergleich zwischen den Disziplinen Statistik und Data Science reicht zunächst eine repräsentative Stichprobe (ohne Gewichtung).

Datenbasis

Beginnen wir mit der Beschreibung des Datenbestandes: Im konkreten Fall haben wir einen fiktiven Datenbestand von 18.000 Kreditfällen. In R wird ein Datenbestand in Form eines Data Frames gespeichert.

Ausgangspunkt für unsere Analysen ist also der Data Frame kreditdaten:


Default Kreditbetrag Scoreklasse Wohnen Einkommen Alter Jobdauer Zins
20972 0 4300 A Hypothek 50000 25 15-30 0-8
25477 0 2850 A Eigentum 39300 22 0-15 8-11
22137 0 15000 B Hypothek 53600 26 0-15 11-13.5
25776 0 13550 C Miete 59800 30 0-15 Unbekannt
13278 0 10300 B Miete 71400 23 0-15 8-11
4840 0 10300 B Hypothek 62900 28 0-15 11-13.5

Für das Kredit-Scoring ist das Merkmal Default entscheidend. Default wird dabei mit Zahlungsausfall, Zahlungsverzug übersetzt. Das Ziel ist, den möglichen Zahlungsausfall bereits im Vorfeld zu erkennen, um so eine objektive Entscheidung zur Kreditvergabe zu ermöglichen.

Zur Klärung des Zahlungsausfalls stehen folgende Variablen zur Verfügung:

  • Kreditbetrag in €
  • Scoreklasse: A = beste Bewertung, … , G = schlechteste Bewertung
  • Wohnen: Hypothek, Eigentum, Miete und Sonstige
  • Einkommen in € pro Jahr
  • Alter in Jahren
  • Jobdauer: Dauer der letzten Beschäftigung in Jahresgruppen
  • Zins: Zinsbereich in Zinsgruppen

Trainingsdaten, Testdaten

Die nachfolgende Anweisung zeigt, wie man mit Hilfe der Sprache R eine Zufallsstichprobe zieht. Dabei hat jedes Element die gleiche Wahrscheinlichkeit, gezogen zu werden. Sie ist damit auch repräsentativ.

In Beispiel wähle ich 12.000 Datensätze zufällig auswählen:

trainingIndex <- sample(1:nrow(kreditdaten), 12000)
trainingSet <- kreditdaten[trainingIndex,]
testSet <- kreditdaten[-trainingIndex,]

In R werden Zufallsstichproben mit Hilfe der sample Funktion erstellt. Das erste Argument beschreibt die Zahlen von 1 bis N (Anzahl aller Datensätze) in Form einer Sequenz 1 : nrow(kreditdaten). Aus dieser Sequenz werden nun 12.000 Zahlen ohne Zurücklegen gezogen und im R-Vektor trainingIndex gespeichert.

Mit Hilfe dieses Index‘ können nun die Data Frames (R Tabelle) trainingSet und testSet gebildet werden. Dabei nutzt man die Indexierungsmöglichkeiten [] von R. So sind im trainingSet nur jene Datensätze enthalten, deren Index auch im trainingIndex vorkommt. Beim testSet wird durch das Minus-Zeichen die Auswahl auf die Komplementärmenge beschränkt. Das Ergebnis dieses Schrittes sind die Data Frames:

  • trainingSet: 12.000 Datensätze
  • testSet: 6.000 Datensätze

Wir werden den Trainingsbestand dazu verwenden, unser Modell (logistische Regression) zu bilden. In der Fortsetzung dieses Beitrags werden die beiden Modelle mit Hilfe des Testbestands vergleichen.

In der Praxis spielt die Datenaufbereitung eine große Rolle. Diese nimmt oft den größten Teil des gesamten Zeitaufwands in Anspruch. Die eigentlichen Analysen sind eher technischer Natur und werden vom Computer unter Verwendung von R in kürzester Zeit gelöst. Bei der Beurteilung der Ergebnisse spielt die Erfahrung eine große Rolle.

Logistische Regression

Es ist nun an der Zeit, die logistische Regression auf unseren Trainingsbestand anzuwenden. Im Standardpaket von R existieren dazu die Funktionen lm und glm. Dabei steht lm für lineare Modelle und glm für allgemeine lineare Modelle. Die logistische Regression ist Teil der glm-Funktion.

lreg <- glm(Default ~ ., family = "binomial", data = trainingSet)

Die R Funktion glm (generalized linear model) benötigt drei Argumente:

  • eine Formel für das gewünschte Modell (gekennzeichnet durch die Wellenlinie ~)
  • eine Familie zur Anwendung eines Binärmodells (Ja/Nein Entscheidungen) und
  • den Datenbestand

Die Formel – Default ~ . – sagt aus, dass sich der Default-Wert als Funktion aller anderen Werte darstellen lässt. Mathematisch wird dies mit folgender Gleichung dargestellt:


Bei dieser Gleichung handelt es sich um eine nichtlineare Funktion und für die Bestimmung der Koeffizienten β0, β1, β2, … gibt es keine geschlossene Formel. Wir benötigen daher ein Näherungsverfahren. In der Statistik wird dabei gerne die Maximum Likelihood Methode genutzt. Über diesen komplexen Vorgang müssen Sie sich als Anwender keine Gedanken machen - R verfügt über entsprechende Algorithmen und erledigt dies alles im Hintergrund.

Als Ergebnis erhalten Sie eine erste Lösung. Zunächst haben wir alle Merkmale zur Modellbildung zugelassen. Aber nicht alle Merkmale sind voneinander unabhängig (z. B. Jobdauer und Alter). In diesem Beitrag möchte ich die Schwierigkeiten, die bei der Verletzung von Annahmen entstehen, noch ausblenden. Ich möchte Ihnen in erster Linie die Klarheit und Einfachheit der Sprache R näher bringen.

Betrachten wir die Signifikanz der einzelnen Koeffizienten: In R wird die Signifikanz durch entsprechende Marker (Punkt bzw. einer oder mehrere Sterne) dargestellt.

Mit Hilfe der summary-Funktion können wir das Gesamtmodell im Detail betrachten:

summary(lreg)
## 
## Call:
## glm(formula = Default ~ ., family = "binomial", data = trainingSet)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.1659  -0.5281  -0.4361  -0.3262   3.4996  
## 
## Coefficients:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)       -2.582e+00  1.913e-01 -13.496  < 2e-16 ***
## Kreditbetrag       2.375e-06  7.283e-06   0.326  0.74434    
## ScoreklasseB       3.536e-01  1.414e-01   2.502  0.01236 *  
## ScoreklasseC       6.670e-01  1.598e-01   4.173 3.01e-05 ***
## ScoreklasseD       1.063e+00  1.785e-01   5.955 2.60e-09 ***
## ScoreklasseE       1.316e+00  2.119e-01   6.210 5.29e-10 ***
## ScoreklasseF       1.574e+00  2.969e-01   5.301 1.15e-07 ***
## ScoreklasseG       2.365e+00  4.797e-01   4.930 8.24e-07 ***
## WohnenHypothek     1.095e-01  1.216e-01   0.901  0.36775    
## WohnenMiete        6.849e-02  1.172e-01   0.585  0.55888    
## WohnenSonstige     9.899e-01  3.930e-01   2.519  0.01177 *  
## Einkommen         -8.257e-06  1.404e-06  -5.880 4.10e-09 ***
## Alter             -4.004e-03  4.800e-03  -0.834  0.40421    
## Jobdauer15-30      2.300e-01  1.087e-01   2.116  0.03432 *  
## Jobdauer30-45     -4.596e-01  4.660e-01  -0.986  0.32397    
## Jobdauer45+        1.373e+00  5.394e-01   2.545  0.01093 *  
## JobdauerUnbekannt  5.908e-01  1.577e-01   3.745  0.00018 ***
## Zins11-13.5        5.072e-01  1.738e-01   2.919  0.00351 ** 
## Zins13.5+          3.913e-01  1.912e-01   2.046  0.04071 *  
## Zins8-11           3.439e-01  1.556e-01   2.210  0.02711 *  
## ZinsUnbekannt      2.843e-01  1.710e-01   1.662  0.09645 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 8278.7  on 11999  degrees of freedom
## Residual deviance: 7898.6  on 11979  degrees of freedom
## AIC: 7940.6
## 
## Number of Fisher Scoring iterations: 5

Wir erkennen, dass bestimmte Merkmale wie Kreditbetrag und Alter nicht signifikant sind. Andere Merkmale weisen nur eine geringe Signifikanz auf. Ich selbst bin kein Befürworter dieser Interpretation von Signifikanz. Sie ist aber mittlerweile Standard in vielen Statistik-Programmen.

Wie kann man nun aus diesen Merkmalen jene herausfiltern, die zu einem Modell führen, das die wichtigsten Variablen ohne wesentlichen Informationsverlust enthält?

Rückwärtselimination

Eine häufig genutzte Methode ist die Rückwärtselimination (backward elimination). Dabei wird schrittweise ein Merkmal nach dem anderen eliminiert, solange das eliminierte Merkmal keinen wesentlichen Informationsverlust darstellt.

Diese Formulierung ist noch vage - aber wir stehen ja am Anfang der R-Initiative.

lreg.backward <- step(lreg)

Die R-Funktion step implementiert die backward elimination. Das Argument trace unterdrückt die Ausgabe. Als Ergebnis erhalten wir das reduzierte Modell lreg.backward.

Auch hier sehen wir uns das Ergebnis des Modells lreg.backward im Detail an:

summary(lreg.backward)
## 
## Call:
## glm(formula = Default ~ Scoreklasse + Wohnen + Einkommen + Jobdauer + 
##     Zins, family = "binomial", data = trainingSet)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.1715  -0.5274  -0.4362  -0.3264   3.4835  
## 
## Coefficients:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)       -2.681e+00  1.423e-01 -18.839  < 2e-16 ***
## ScoreklasseB       3.588e-01  1.411e-01   2.543 0.010985 *  
## ScoreklasseC       6.700e-01  1.598e-01   4.194 2.74e-05 ***
## ScoreklasseD       1.068e+00  1.780e-01   5.997 2.01e-09 ***
## ScoreklasseE       1.324e+00  2.106e-01   6.284 3.29e-10 ***
## ScoreklasseF       1.584e+00  2.960e-01   5.353 8.65e-08 ***
## ScoreklasseG       2.386e+00  4.777e-01   4.994 5.91e-07 ***
## WohnenHypothek     1.097e-01  1.216e-01   0.903 0.366788    
## WohnenMiete        6.787e-02  1.172e-01   0.579 0.562333    
## WohnenSonstige     9.985e-01  3.927e-01   2.543 0.010995 *  
## Einkommen         -8.180e-06  1.278e-06  -6.399 1.57e-10 ***
## Jobdauer15-30      2.295e-01  1.087e-01   2.111 0.034747 *  
## Jobdauer30-45     -4.640e-01  4.660e-01  -0.996 0.319367    
## Jobdauer45+        1.378e+00  5.390e-01   2.556 0.010590 *  
## JobdauerUnbekannt  5.878e-01  1.577e-01   3.728 0.000193 ***
## Zins11-13.5        5.045e-01  1.737e-01   2.904 0.003682 ** 
## Zins13.5+          3.888e-01  1.912e-01   2.034 0.041984 *  
## Zins8-11           3.418e-01  1.556e-01   2.197 0.028036 *  
## ZinsUnbekannt      2.826e-01  1.710e-01   1.653 0.098402 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 8278.7  on 11999  degrees of freedom
## Residual deviance: 7899.4  on 11981  degrees of freedom
## AIC: 7937.4
## 
## Number of Fisher Scoring iterations: 5

Unser Modell enthält nun die Merkmale: Scoreklasse, Wohnen, Einkommen, Jobdauer und Zins. Die Merkmale Kreditbetrag und Alter wurden eliminiert.

Ergebnis

Um nun die Wahrscheinlichkeit für einen Zahlungsausfall je Datensatz zu berechnen, müssten wir obige Formel anwenden und für die Parameter β0, β1, β2, … die Werte aus der Spalte Estimate übernehmen - ein mühsamer Prozess.

Es geht aber auch einfacher. Betrachten wir den Data Frame trainingSet:


Default Kreditbetrag Scoreklasse Wohnen Einkommen Alter Jobdauer Zins
2928 0 1050 A Miete 17100 26 0-15 Unbekannt
20350 0 5350 C Eigentum 20000 24 0-15 Unbekannt
10689 0 7150 A Hypothek 50700 34 0-15 0-8
20420 0 17850 E Miete 64300 25 0-15 13.5+
1202 0 2550 A Miete 32100 26 0-15 Unbekannt
25847 0 5150 D Hypothek 37900 24 0-15 13.5+

In der ersten Spalte finden wir die Datensatz-ID. Über diese wird ein Datensatz identifiziert.

So beschreibt der Datensatz mit der ID = 2928 einen Kunden, der einen Kreditbetrag von 1050 € benötig, mit einem Score A bewertet wird, in Miete lebt, über ein Einkommen von 17.100 € im Jahr verfügt, 27 Jahre alt ist und dessen Zinssatz unbekannt ist. Wie wahrscheinlich ist ein Kreditausfall?

Mittels predict kann man nun die Wahrscheinlichkeiten für einen Default vorhersagen. Ein mühsames Rechnen von Hand aus entfällt.

pred <- predict(lreg.backward, type = "response", newdata = trainingSet)

Die predict-Funktion liefert als Ergebnis einen R-Vektor mit den Wahrscheinlichkeiten zum Zahlungsverzug für jeden Datensatz. Sehen wir uns z. B. die ersten sechs Datensätze mittels der head-Funktion an:

head(pred)
##       2928      20350      10689      20420       1202      25847 
## 0.07793758 0.13098030 0.04804708 0.19356698 0.06956404 0.19385165

Die erste Zeile zeigt die Datensatz ID. Darunter findet man die jeweilige Wahrscheinlichkeit. Damit ergibt sich für den Kunden eine Wahrscheinlichkeit für einen Zahlungsausfall in der Höhe von 7,80 %.


Besuchen Sie mich auch auf meiner Hompage www.usedata.com.

Im nächsten Beitrag werde ich das Kreditscoringmodell mit Hilfe eines Entscheidungsbaums unter Anwendung maschineller Lerntechniken erstellen.

Mit statistischen Grüßen

Helmut Grillenberger
24. März 2018

Diese Website benutzt Cookies, um Ihnen das beste Erlebnis zu ermöglichen. Weiterführende Informationen erhalten Sie in unserer Datenschutzerklärung.