[PYTHON] Ich habe versucht, einen einfachen Kredit-Score mit logistischer Regression zu erstellen.

Motivation

Im Oktober 2019 lud uns SAS Japan zu einer Konferenz mit dem Titel "SAS Analytics Experience @ Milano" ein, und Dr. Terisa hörte sich einen Vortrag über Credit Score an. 集合写真.jpg [* Foto aufgenommen, als ich im Oktober 2019 zu SAS Analytics Experience @ Milano * ging]

Bei der Aufführung ließen wir sie die folgenden drei Themen teilen und stellten fest, dass der Mechanismus einfach ist, aber große geschäftliche Auswirkungen hat.

  1. Was ist überhaupt ein Kredit-Score?
  2. Was sind die aktuellen Mainstream- und State-of-the-Art-Algorithmen? (Mit maschinellem Lernen, tiefem Lernen, verstärktem Lernen)
  3. In welchen Situationen kann der Kredit-Score verwendet werden, außer für die "Beurteilung des Kredits für Kreditkredite"?

Ich war in der Praxis nicht an der Erstellung von Kredit-Scores beteiligt, aber der technische Hintergrund war sehr intuitiv und leicht zu verstehen, daher werde ich ihn in diesem Artikel zusammenfassen.

In der Vorlesung ist die Erklärung der Methode selbst aufgrund der Vertraulichkeit jedoch nicht möglich. Daher werde ich die in dem von Dr. Terisa empfohlenen Buch beschriebene Methode anstelle der vereinfachten Version erläutern. .. [Referenz: https://www.wiley.com/en-us/Credit+Risk+Scorecards%3A+Developing+and+Implementing+Intelligent+Credit+Scoring-p-9781119201731]

Die in diesem Buch beschriebene Methode unterscheidet sich nicht wesentlich von der Methode nach dem Stand der Technik, die Dr. Terisa in der Aufführung erläutert hat, und viele Unternehmen / Startups in Europa und den USA verwenden ebenfalls die in diesem Buch beschriebene Methode. Es scheint, dass es eine glaubwürdige Methode ist, weil es sich zu beziehen scheint.

Was ist ein Kredit-Score? Zuerst organisieren.

Ein Kredit-Score ist jemand, der Geld ausleihen will! Als ich dachte Kannst du dieser Person vertrauen? (Können Sie zurückzahlen?) Wird quantifiziert. Es bedeutet, soziale Kredite zu quantifizieren und zu visualisieren.

信用スコアのイメージ.png

Der Score Card Point in der obigen Abbildung ist die Zahl, die Ihren Kredit-Score bildet. Um diesen Score Card Point zu erstellen, werden wir verschiedene Dinge mit Python tun.

Es mag auf den ersten Blick schwierig erscheinen, aber die Methode ist sehr einfach. Sie können einen Kredit-Score in nur 3 Schritten unten erstellen.

  1. Hierarchie der Spalten, die zum Erstellen von Kredit-Scores verwendet werden (Binning)
  2. Berechnung des WoE in jeder Schicht jeder Spalte
  3. Berechnung des Score Card Point auf jeder Ebene jeder Spalte

Schauen wir uns den Inhalt jedes Schritts genauer an!

Eine Übersicht über den Datensatz, der zum Erstellen des Kredit-Scores verwendet wurde

Studenten und Praktiker aus der ganzen Welt konkurrieren um ihre Fähigkeiten, und ein Datensatz namens "Give Me Some Credit" wird von der Website eines Online-Datenanalysewettbewerbs namens Kaggle geteilt, daher werde ich diese Daten verwenden. .. Dies wurde im Wettbewerb im Jahr 2011 verwendet. Im Folgenden werden wir eine Zusammenfassung der Daten in einer Tabelle teilen. 特徴量.png [Klicken Sie hier für den Datensatz] https://www.kaggle.com/brycecf/give-me-some-credit-dataset

Erstellen Sie anhand dieses Datensatzes ein logistisches Regressionsmodell mit "SeriousDlpin2yrs" als Zielvariable (erklärte Variable) und verwenden Sie den Koeffizienten für die erklärende Variable, um die Kreditwürdigkeit zu berechnen. (Ich werde später genauer erklären)

Der wichtige Punkt ist also, "durch Erlernen der KI einen Kredit-Score zu erstellen" Haben Sie den benötigten Datensatz natürlich zurückgezahlt? / Verzögert sich die Rückzahlung? Sie benötigen einen Datensatz, der diese Informationen enthält.

Erläuterung und Implementierung von STEP1 und 2

Die Schritte 1 und 2 ähneln der Vorverarbeitung beim Erstellen eines Kredit-Scores. ステップ1と2.png

Schauen wir uns STEP1 genauer an

Die Arbeit hier ist ziemlich schwierig (schlammig). Der zur Erstellung des Kredit-Scores verwendete Feature-Betrag (z. B. monatliches Einkommen) muss hierarchisiert werden (Binning). Wie 100-200.000, 200-300.000.

** Warum müssen wir schichten? ** Apropos Wie oben unter "Was ist ein Kredit-Score? Zuerst organisiert" erläutert, Der Kredit-Score beträgt 50 Punkte für Personen mit einem monatlichen Einkommen von 100.000 bis 200.000! 200-300.000 Menschen erhalten 55 Punkte! Es wird so berechnet. Das heißt, aus Sicht der Datenaufbereitungsseite bedeutet dies, dass die Vorverarbeitung der "Überlagerung der Merkmalsmenge" durchgeführt wird.

** Ich denke, Ihnen wird die Frage gestellt: "Wie sollen wir dann schichten?" **.

Wie später in Schritt 2 beschrieben wird, In der akademischen Welt sollen die Kriterien für die Schichtung "festgelegt werden, um den Unterschied zwischen DOG und DOB zu maximieren". [Referenz: https://www.wiley.com/en-us/Credit+Risk+Scorecards%3A+Developing+and+Implementing+Intelligent+Credit+Scoring-p-9781119201731]

Es scheint jedoch, dass viele Praktiker der Erstellung von Kredit-Scores nach ** "Try and Error" ** urteilen. Dr. Terisa sagte es.

Nach Versuch und Irrtum zu urteilen ist ** "Wenn Sie die Hierarchie selbst festgelegt haben, geben Sie einen Kredit-Score an und vergleichen Sie ihn mit der Domäne und dem gesunden Menschenverstand, um festzustellen, ob der Kredit-Score Make Sense ist" **.

Ich möchte sagen: "Formulieren Sie mit einem Optimierungsproblem, das den Unterschied zwischen DOG und DOB maximiert", aber diese ** Try and Error-Methode ** ist ziemlich überzeugend.

** Weil ich denke, dass diejenigen, die in der praktischen Welt der Kredit-Score-Erstellung aktiv sind, ein gutes Gefühl der Schichtung haben. Wo soll ich mein Einkommen und mein Alter trennen? Aus ihrer / ihrer Erfahrung bin ich sicher, dass es ein Gefühl dafür gibt, wie gut die Erstellung von Kredit-Scores funktioniert. ** **.

Ich habe dieses Gefühl noch nicht, aber ich habe es mit Try and Error gemacht. Vorerst wollte ich den Workflow eines Praktikers der Erstellung von Kredit-Scores erleben.

Schauen wir uns als nächstes Schritt 2 genauer an

Um Schritt 2 zu verstehen, müssen die folgenden beiden Konzepte verstanden werden.

1. Was ist WoE (Weight of Evidence)?

――Indikator, der "Guter oder schlechter Kunde, welcher ist nützlich für die Vorhersage?" Informiert.

Kommt mit dieser Definition heraus Guter Kunde bezieht sich auf "Personen, die" nie "die Rückzahlung von Schulden verzögert haben oder in der Vergangenheit in Verzug geraten sind", und schlechter Kunde bezieht sich auf "Personen, die die Rückzahlung von Schulden verzögert haben oder in der Vergangenheit in Verzug geraten sind". Es bezieht sich auf eine Person, die "geworden" ist.

Ein positiver Wert hilft, einen guten Kunden vorherzusagen, und ein negativer Wert hilft, einen schlechten Kunden vorherzusagen. Sie können es besser verstehen, wenn Sie sich das unten berechnete Bild von WoE ansehen.

実際に計算した結果.png

Wie viel Schulden / Schulden hat DebtRatio für das Vermögen, das Sie haben? Es ist ein Index, der zeigt. (DP = Schulden / Aktiva)

In der obigen Abbildung ist der WoE-Wert umso kleiner, je höher das Dept Ratio ist, nicht wahr? Mit anderen Worten, Sie können die Meldung lesen ** "Je mehr Schulden Sie in Bezug auf Ihr Vermögen haben, desto mehr sind Sie in Verzug." **. Ich denke, das ist intuitiv und unkompliziert.

2. Was ist DOG / DOB?

Schauen wir uns noch einmal die in Schritt 1 und 2 oben beschriebene Folie an. Beachten Sie die DOG- und DOB-Formeln in Schritt 2. ステップ1と2.png Die "Anzahl der Gutschriften / Nicht-Gutschriften in jeder Kategorie" in der Formel hier gibt beispielsweise an, "wie viele Personen sind gute / schlechte Kunden in der Kategorie mit einem monatlichen Einkommen von 200.000 bis 300.000 Yen?".

"Gesamtkredit / Nichtkredit" gibt an, "Wie viele Personen sind im gesamten Datensatz gute / schlechte Kunden?"

In der Spalte des diesmal verwendeten Datensatzes ist dies die Zahl, wenn "SeriousDlqin2yrs" = 0/1 ist. Ich denke, es ist schwer, sich nur Worte vorzustellen. Bitte sehen Sie auch die folgende Abbildung.

image.png Wie ist das? Ich verstehe? Wenn Sie etwas schwer zu verstehen finden, können Sie gerne eine Frage stellen :)

Schließlich wird die Implementierungsmethode (Python) bis zu Schritt 1-2 unten geteilt.


#Binning definieren
def binning(col, list_bins_func):
    binned_df_list = []
    for each in list_bins_func:
        binned_df_list.append(df[(df[col]>=each[0])&(df[col]<each[1])])
    return binned_df_list

#Definieren Sie eine Funktion zum Durchführen von Binning- und WoE-Berechnungen
def calc_woe_runner(col, list_bins):
    #Binning tatsächlich ausführen
    list_binned_df  = binning(col, list_bins)
    each_num         = np.zeros(len(list_binned_df))
    dist_good         = np.zeros(len(list_binned_df))
    dist_bad           = np.zeros(len(list_binned_df))
    good_number  = np.zeros(len(list_binned_df))
    bad_number    = np.zeros(len(list_binned_df))
    
    #Berechnen Sie DOG und DOB
    for i, each in enumerate(list_binned_df):
        each_num[i]        = len(each)
        good_number[i]  = len(each[each["SeriousDlqin2yrs"] == 0])
        bad_number[i]    = len(each[each["SeriousDlqin2yrs"] == 1])
    
    dist_good   = good_number/good_number.sum()
    dist_bad    = bad_number/bad_number.sum()
    dist_total  =  (good_number + bad_number)/len(df)
    
    # WOE(Weight of Evidence)Berechnen
    woe = np.log(dist_good/dist_bad)*100
    
    return col,woe,dist_total, good_number.sum(), good_number, bad_number.sum(),bad_number, dist_good, dist_bad

#Mach das oben
#Definition der in der Binning-Funktion verwendeten Variablen
col_list = ["age", "DebtRatio", 'MonthlyIncome']

age_bin_list = [[0,30], [30,40], [40,50],
                [50,60], [60,70], [70,80], 
                [80,90], [90,130]]

deptRatio_bin_list = [[0,0.2], [0.2,0.4], [0.4,0.6],
                      [0.6,0.8], [0.8,1.0], [1.0,1.2], 
                      [1.2,1.4], [1.4,1.6]]

monthlyIncome_bin_list = [[0,2000], [2000,4000], [4000,6000],
                          [6000,8000], [8000,10000], [10000,12000], 
                          [12000,14000], [14000,160000]]

list_combined = [age_bin_list, deptRatio_bin_list, monthlyIncome_bin_list]

# Actually calculate woe
col_list_for_df = []
woe_list_for_df = []
iv_list_for_df  = []
df_woe_list     = []
good_list_sum   = []
good_list_each  = []
bad_list_sum    = []
bad_list_each   = []
dist_good_list  = []
dist_bad_list   = []
total_dist_list = []
df_woe_concat   = pd.DataFrame()
i = 0
for col, each_bin_for_col in zip(col_list,list_combined):
    col_list_for_df, woe_list_for_df, total_dist_list, good_list_sum, good_list_each, bad_list_sum, bad_list_each, dist_good_list, dist_bad_list = calc_woe_runner(col, each_bin_for_col)
    col_df = pd.DataFrame(data=[col_list_for_df]*len(list_combined[0]), columns=["col"])
    
    woe_list_for_df = pd.DataFrame(data=woe_list_for_df, columns=["WoE"])
    good_list_df    = pd.DataFrame(data=good_list_each, columns=["Num_good"], dtype=int)
    bad_list_df     = pd.DataFrame(data=bad_list_each, columns=["Num_bad"], dtype=int)
    dist_good_df    = pd.DataFrame(data=dist_good_list, columns=["Distr_good"])
    dist_bad_df     = pd.DataFrame(data=dist_bad_list, columns=["Distr_bad"])
    total_dist_df   = pd.DataFrame(data=total_dist_list, columns=["Distr_total"])
    l = []
    for e in np.array(list_combined[i]):
        l.append(str(e[0]) + "-" + str(e[1]))
    bin_value_df = pd.DataFrame(data=l, columns=["Attribute"])
    
    df_woe_concat = pd.concat([col_df, bin_value_df,good_list_df, 
                               bad_list_df,dist_good_df, dist_bad_df, 
                               woe_list_for_df, total_dist_df], axis=1)
    df_woe_list.append(df_woe_concat)
    i += 1
df_woe = pd.concat(df_woe_list, axis=0)

Wenn Sie den obigen Code ausführen, sollte eine Ausgabe wie die folgende angezeigt werden. 最終結果.png

Erläuterung und Implementierung von Schritt 3

In Schritt 3 berechnen wir tatsächlich den Scorekartenpunkt. Die Berechnungsformel lautet wie folgt.

Scorecard Point = (β×WoE+ α/n)×Factor + Offset/n

Die folgenden Begriffe (Begriffe), die hier erscheinen, müssen nicht bereits berechnet werden.

  1. WoE wurde in Schritt 2 berechnet.
  2. Faktor ist ein Skalierungsfaktor, also eine Konstante.
  3. Der Versatz ist ein Skalierungsfaktor, also eine Konstante.
  4. n ist die Anzahl der Features, die zur Vorhersage von SeriousDlqin2yrs verwendet werden. Es handelt sich also um eine Konstante.

Da sind die einzigen zu berechnenden Terme β und α. </ u> </ b> Diese β und α werden nach Modellierung mit logistischer Regression berechnet.

Mit anderen Worten, wenn Sie den Datensatz verwenden, der dieses Mal als Beispiel verwendet wird,

  1. Modellierung mit logistischer Regression unter Verwendung von "SeriousDlqin2yrs" als Zielvariable
  2. Ermitteln Sie nach der Modellierung die Koeffizienten und Abschnittsbedingungen der in Scorecard Point verwendeten Variablen (in diesem Fall Alter, Schuldenverhältnis, monatliches Einkommen).
  3. Der Koeffizient wird zu β und der Abschnittsbegriff wird zu α.

** Mit anderen Worten, Schritt 3 ist nur die Arbeit der Modellierung mit logistischer Regression, und Sie müssen nur den Koeffizienten und den Abschnitt nach der Modellierung erhalten. ** ** **

Abschließend werde ich die Implementierungsmethode von Schritt 3 weiter unten erläutern.


#Trainieren Sie ein logistisches Regressionsmodell
lr = LogisticRegression()
lr.fit(X_train, y_train)
print("AUC:{}".format(roc_auc_score(lr.predict(X_test), y_test)))

#Berechnen Sie tatsächlich die Kredit-Score: Score = (β×WoE+ α/n)×Factor + Offset/n
df_woe_with_score = df_woe.reset_index().copy()
df_woe_with_score.iloc[:, 3:-1] = df_woe_with_score.iloc[:, 3:-1].astype(float)

#Skalierungsfaktor definieren
n = len(default_features_list)

alpha = lr.intercept_[0]
beta_age    = lr.coef_[0][0]    #Altersspaltenkoeffizient
beta_dept   = lr.coef_[0][1]    #DebtRation-Koeffizient
beta_income = lr.coef_[0][2] #Monatlicher Einkommenskoeffizient

#Skalierung zur Maximierung der Gesamtpunktzahl auf 600 Punkte
factor      = 20/np.log(2)
offset      = 600-factor*np.log(20)

print("factor:{0}, offset:{1}".format(factor, offset))

#Scorecard Punkteberechnung
df_woe_with_score["score"] = None
score_list = []
for i in range(len(df_woe)):
    woe = df_woe_with_score["WoE"].iloc[i]
    if df_woe_with_score.iloc[i]["col"] == "age":
        score = (beta_age*woe+(alpha/n))*factor + (offset/n)
        df_woe_with_score["score"].iloc[i] = round(score, 1)
    elif df_woe_with_score.iloc[i]["col"] == "DebtRatio":
        coef = beta_dept.copy()
        score = (beta_dept*woe+(alpha/n))*factor + (offset/n)
        df_woe_with_score["score"].iloc[i] = round(score, 1)
    elif df_woe_with_score.iloc[i]["col"] == "MonthlyIncome":
        coef = beta_income.copy()
        score = (beta_income*woe+(alpha/n))*factor + (offset/n)
        df_woe_with_score["score"].iloc[i] = round(score,1)

Und ich konnte sicher einen Kredit-Score erstellen! 信用スコア完成図.png

Vielen Dank, dass Sie so weit gelesen haben.

Recommended Posts