[PYTHON] J'ai essayé de créer un pointage de crédit simple avec régression logistique.

motivation

En octobre 2019, SAS Japon nous a invités à une conférence intitulée «SAS Analytics Experience @ Milano», et le Dr Terisa a écouté une conférence sur le score de crédit. 集合写真.jpg [* Photo prise lorsque je suis allé à SAS Analytics Experience @ Milano * en octobre 2019]

Lors de la représentation, nous leur avons fait partager les trois sujets suivants et avons appris que le mécanisme est simple mais a un grand impact commercial.

  1. Qu'est-ce qu'une cote de crédit en premier lieu?
  2. Quels sont les algorithmes courants et de pointe actuels? (Utilisation de l'apprentissage automatique, de l'apprentissage en profondeur, de l'apprentissage par renforcement)
  3. Dans quelles situations la cote de crédit peut-elle être utilisée, sauf pour «l'évaluation du crédit pour les prêts»?

Je n'ai pas participé à la création de cotes de crédit dans la pratique, mais le contexte technique était très intuitif et facile à comprendre, je vais donc le résumer dans cet article.

Cependant, l'explication de la méthode elle-même partagée dans la conférence ne peut pas être partagée en raison de la confidentialité, je vais donc expliquer la méthode décrite dans le livre recommandé par le Dr Terisa au lieu de la version simplifiée. .. [Référence: https://www.wiley.com/en-us/Credit+Risk+Scorecards%3A+Developing+and+Implementing+Intelligent+Credit+Scoring-p-9781119201731]

La méthode décrite dans ce livre n'est pas très différente de la méthode (de pointe) que le Dr Terisa a expliquée dans la performance, et de nombreuses entreprises / startups en Europe et aux États-Unis utilisent également la méthode décrite dans ce livre. Il semble que ce soit une méthode crédible, car il semble y faire référence.

Qu'est-ce qu'une cote de crédit? Organisez d'abord.

Un pointage de crédit est quelqu'un qui veut emprunter de l'argent! Quand j'ai pensé Pouvez-vous faire confiance à cette personne? (Êtes-vous capable de rembourser?) Est quantifié. Cela signifie quantifier et visualiser le crédit social.

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

Le point de la carte de score dans la figure ci-dessus est le nombre qui forme votre pointage de crédit. Afin de créer ce point de carte de score, nous allons faire diverses choses avec Python.

Cela peut sembler difficile à première vue, mais la méthode est très simple. Vous pouvez créer une cote de crédit en seulement 3 étapes ci-dessous.

  1. Hiérarchie des colonnes utilisées pour créer les cotes de crédit (regroupement)
  2. Calcul de WoE dans chaque couche de chaque colonne
  3. Calcul du point de la carte de score à chaque niveau de chaque colonne

Regardons de plus près le contenu de chaque étape!

Un aperçu de l'ensemble de données utilisé pour créer la cote de crédit

Des étudiants et des praticiens du monde entier se disputent leurs capacités, et un ensemble de données appelé "Give Me Some Credit" est partagé à partir du site d'un concours d'analyse de données en ligne appelé Kaggle, donc j'utiliserai ces données. .. Cela a été utilisé dans la compétition en 2011. Ci-dessous, nous partagerons un résumé des données dans un tableau. 特徴量.png [Cliquez ici pour l'ensemble de données] https://www.kaggle.com/brycecf/give-me-some-credit-dataset

À l'aide de cet ensemble de données, créez un modèle de régression logistique avec «SeriousDlpin2yrs» comme variable cible (variable expliquée) et utilisez le coefficient donné à la variable explicative pour calculer la cote de crédit. (J'expliquerai plus en détail plus tard)

Le point important est de "créer une cote de crédit en apprenant l'IA", donc Avez-vous remboursé l'ensemble de données dont vous aviez besoin, bien sûr? / Le remboursement est-il retardé? Vous avez besoin d'un ensemble de données contenant ces informations.

Explication et mise en œuvre de STEP1 et 2

Les étapes 1 et 2 sont comme le prétraitement pour créer une cote de crédit. ステップ1と2.png

Regardons de plus près à partir de STEP1

Le travail ici est assez difficile (boueux). Le montant de la fonction (par exemple, le revenu mensuel) utilisé pour créer la cote de crédit doit être hiérarchisé (regroupement). Comme 100-200 000, 200-300 000.

** Pourquoi devons-nous superposer? ** En parlant de Comme expliqué dans "Qu'est-ce qu'une cote de crédit? D'abord organisé" ci-dessus La cote de crédit est de 50 points pour les personnes ayant un revenu mensuel de 100 000 à 200 000! , 200 à 300 000 personnes obtiennent 55 points! C'est calculé comme ça. C'est-à-dire que du point de vue du côté de la préparation des données, cela signifie que le prétraitement de "superposition de la quantité de caractéristiques" est effectué.

** Je pense qu'on vous posera la question: «Alors, comment devrions-nous stratifier?» **.

Comme cela sera décrit plus loin à l'étape 2, Dans le monde universitaire, on dit que les critères de stratification sont «fixés pour maximiser la différence entre DOG et DOB». [Référence: https://www.wiley.com/en-us/Credit+Risk+Scorecards%3A+Developing+and+Implementing+Intelligent+Credit+Scoring-p-9781119201731]

Cependant, il semble que de nombreux praticiens de la création de pointage de crédit jugent par ** "Try and Error" **. Le Dr Terisa l'a dit.

Juger par Try and Error est ** "Une fois que vous avez spécifié la hiérarchie vous-même, donnez un pointage de crédit et comparez-le avec le domaine et le bon sens pour déterminer si le pointage de crédit est Make Sense" **.

Je voudrais dire: «Formulez avec un problème d'optimisation qui maximise la différence entre DOG et DOB», mais cette ** méthodologie Try and Error ** est assez convaincante.

** Parce que je pense que ceux qui sont actifs dans le monde pratique de la création de points de crédit ont un bon sens de la stratification. Où dois-je séparer mon revenu et mon âge? D'après leur expérience, je suis sûr qu'il y a une idée de la façon dont la création de pointage de crédit fonctionne. ** **

Je n'ai pas encore ce sentiment, mais je l'ai fait avec Try and Error. Pour le moment, je voulais faire l'expérience du workflow d'un praticien de la création de points de crédit.

Ensuite, examinons de plus près l'étape 2

Afin de comprendre Step2, il est nécessaire de comprendre les deux concepts suivants.

1. Qu'est-ce que WoE (Weight of Evidence)?

――Indicateur qui informe "Quel est le meilleur à prévoir, bon client ou mauvais client?"

Sort avec cette définition Un bon client fait référence à des «personnes qui n'ont« jamais »retardé le remboursement de la dette ou qui ont fait défaut dans le passé», et un mauvais client fait référence aux «personnes qui ont retardé le remboursement de la dette ou ont fait défaut dans le passé». Il se réfère à une personne qui "est" devenue.

Une valeur positive aide à prédire un bon client et une valeur négative aide à prédire un mauvais client. Vous pouvez mieux le comprendre en regardant l'image de WoE réellement calculée ci-dessous.

実際に計算した結果.png

Quel est le montant de la dette / dette de DebtRatio pour les actifs que vous avez? C'est un index montrant. (DP = Dette / Actif)

En regardant la figure ci-dessus, plus le Dept Ratio est élevé, plus la valeur WoE est petite, n'est-ce pas? En d'autres termes, vous pouvez lire le message ** "Plus vous avez de dettes pour vos actifs, plus vous êtes en défaut." **. Je pense que c'est intuitif et simple.

2. Qu'est-ce que DOG / DOB?

Jetons à nouveau un coup d'œil à la diapositive décrite aux étapes 1 et 2 ci-dessus. Notez les formules DOG et DOB à l'étape 2. ステップ1と2.png Le "nombre de crédits / non-crédits dans chaque catégorie" dans la formule ici indique, par exemple, "Combien de personnes sont de bons / mauvais clients dans la catégorie avec un revenu mensuel de 200 000 à 300 000 yens?".

"Total crédit / non crédit" indique "Combien de personnes sont de bons / mauvais clients dans l'ensemble de données?"

Dans la colonne de l'ensemble de données utilisé cette fois, c'est le nombre lorsque "SeriousDlqin2yrs" = 0/1. Je pense que c'est difficile à imaginer avec juste des mots, alors veuillez également voir la figure ci-dessous.

image.png comment c'est? Je comprends? Si vous trouvez quelque chose de difficile à comprendre, n'hésitez pas à poser une question :)

Enfin, la méthode d'implémentation (python) jusqu'à l'étape 1-2 est partagée ci-dessous.


#Définir le binning
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

#Définir une fonction pour effectuer des calculs de Binning et WoE
def calc_woe_runner(col, list_bins):
    #Exécuter réellement le binning
    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))
    
    #Calculer DOG et 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)Calculer
    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

#Faites ce qui précède
#Définition des variables utilisées dans la fonction de regroupement
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)

Lorsque vous exécutez le code ci-dessus, vous devriez voir une sortie comme celle ci-dessous. 最終結果.png

Explication et mise en œuvre de l'étape 3

À l'étape 3, nous calculerons le point de la carte de score. La formule de calcul est la suivante.

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

Les termes (conditions) suivants qui apparaissent ici n'ont pas besoin d'être déjà calculés.

  1. WoE a été calculé à l'étape 2.
  2. Le facteur est un facteur d'échelle, c'est donc une constante.
  3. Le décalage est un facteur d'échelle, c'est donc une constante.
  4. n est le nombre de fonctionnalités utilisées pour prédire SeriousDlqin2yrs, c'est donc une constante.

Depuis , les seuls termes à calculer sont β et α. </ u> </ b> Ces β et α sont calculés après modélisation par régression logistique.

En d'autres termes, en prenant l'ensemble de données utilisé cette fois à titre d'exemple,

  1. Modélisation avec régression logistique en utilisant "SeriousDlqin2yrs" comme variable cible
  2. Après la modélisation, obtenez les coefficients et les termes de section des variables utilisées dans Scorecard Point (dans ce cas, âge, DebtRatio, Revenu mensuel).
  3. Le coefficient devient β et le terme de section devient α.

** En d'autres termes, l'étape 3 n'est que le travail de modélisation avec régression logistique, et il vous suffit d'obtenir le coefficient et la section après modélisation. ** **

Enfin, je partagerai la méthode de mise en œuvre de l'étape 3 ci-dessous.


#Former un modèle de régression logistique
lr = LogisticRegression()
lr.fit(X_train, y_train)
print("AUC:{}".format(roc_auc_score(lr.predict(X_test), y_test)))

#Calculez réellement la cote de crédit: 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)

#Définir le facteur d'échelle
n = len(default_features_list)

alpha = lr.intercept_[0]
beta_age    = lr.coef_[0][0]    #Coefficient de la colonne Âge
beta_dept   = lr.coef_[0][1]    #Coefficient DebtRation
beta_income = lr.coef_[0][2] #Coefficient de revenu mensuel

#Mise à l'échelle pour maximiser le total des points du tableau de bord à 600
factor      = 20/np.log(2)
offset      = 600-factor*np.log(20)

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

#Calcul des points de Scorecard
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)

Et j'ai pu créer une cote de crédit en toute sécurité! 信用スコア完成図.png

Merci d'avoir lu jusqu'ici.

Recommended Posts