Applicazioni pratiche di machine learning/Approvazione carte di credito
Caricamento librerie
[modifica | modifica sorgente] library(dplyr)
library(caret)
library(h2o)
Parte 1 : Dati
[modifica | modifica sorgente]Una banca per decidere se emettere una carta di credito ad un cliente può valutare l'entità del rischio utilizzando un algoritmo di machine learning . I datasets credit_record.csv e application_record.csv scaricabili da qui : https://www.kaggle.com/rikdifos/credit-card-approval-prediction possono essere utilizzati per prevedere se un candidato è un cliente "buono" o "cattivo" al fine di ricevere la carta di credito.
I dati relativi al cliente sono contenuti in application_record.csv :
- ID: numero identificativo cliente
- CODE_GENDER: Sesso
- FLAG_OWN_CAR: Ha una macchina
- FLAG_OWN_REALTY: Ha proprietà
- CNT_CHILDREN: Numero di bambini
- AMT_INCOME_TOTAL: Reddito annuo
- NAME_INCOME_TYPE: Tipo di reddito
- NAME_EDUCATION_TYPE: Livello di istruzione
- NAME_FAMILY_STATUS: Stato civile
- NAME_HOUSING_TYPE: Stile di vita
- DAYS_BIRTH: Numero di giorni indietro fino al compleanno (0), -1 significa ieri
- DAYS_EMPLOYED: Numero di giorni indietro fino alla data di inizio del rapporto di lavoro .Giorno corrente = 0. Se il numero è positivo, indica la persona attualmente disoccupata viceversa se negativo indica che la persona è occupata.
- FLAG_MOBIL: Ha un telefono cellulare
- FLAG_WORK_PHONE: Ha un proprio telefono al lavoro
- FLAG_PHONE: Ha un telefono fisso
- FLAG_EMAIL: Ha un'e-mail
- OCCUPATION_TYPE: Tipo di lavoro
- CNT_FAM_MEMBERS: Dimensione della famiglia
Il dataset credit_record.csv contiene dati relativi a prestiti e crediti fatti al cliente:
- ID: numero identificativo cliente
- MONTHS_BALANCE: Numero di mesi all'indietro rispetto al mese corrente che è 0, -1 è il mese precedente e così via ...
- STATUS:
- 0: da 1-29 giorni in ritardo nel pagamento
- 1: da 30-59 giorni in ritardo nel pagamento
- 2: da 60-89 giorni in ritardo nel pagamento
- 3: da 90-119 giorni in ritardo nel pagamento
- 4: da 120-149 giorni in ritardo nel pagamento
- 5: Crediti scaduti o inesigibili, cancellazioni per più di 150 giorni
- C: pagato quel mese
- X: Nessun prestito per il mese
Caricamento dati::
credit_record <- read.csv("credit_record.csv")
application_record <- read.csv("application_record.csv")
#Eliminazione records duplicati:
application_record <- unique(application_record, by="ID")
Si stabilisce che chi non paga un credito da più di 60 giorni non è un buon cliente e non merita la carta di credito, per cui (target=1). Invece chi è in ritardo nel pagamento da meno di 60 giorni è un buon cliente e merita la carta di credito (target=0):
# Si crea una nuova variabile target e la si aggiunge al dataset credit_record :
n<-nrow(credit_record)
target <- rep(NA,n)
target[which(credit_record$STATUS=="2")]<- 1
target[which(credit_record$STATUS=="3")]<- 1
target[which(credit_record$STATUS=="4")]<- 1
target[which(credit_record$STATUS=="5")]<- 1
target[which(credit_record$STATUS=="1")]<- 0
target[which(credit_record$STATUS=="0")]<- 0
target[which(credit_record$STATUS=="C")]<- 0
target[which(credit_record$STATUS=="X")]<- 0
credit_record <- cbind(credit_record,target)
Si uniscono i due datasets in un unico dataset df:
df <- merge(application_record,credit_record, by.x = "ID")
df$target <- as.factor(df$target)
Non ci sono valori mancanti nel dataset df :
colSums(is.na(df))
Modellizzazione
[modifica | modifica sorgente]A partire dal dataset df si creano 2 datasets training e testing, il primo contenente il 70% dei records in modo casuale su cui verrà addestrato il modello e il secondo contenente il restante 30% su cui verrà testato il modello :
trainIndex <- createDataPartition(df$target,p=0.7, list = FALSE)
training <- df[trainIndex,]
testing <- df[-trainIndex,]
Si utilizza la libreria h2o per cercare automaticamente per 300 secondi un algoritmo di machine learning idoneo per prevedere con una buona accuratezza la variabile target:
h2o.init()
H2O is not running yet, starting it now...
openjdk version "11.0.8" 2020-07-14 OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu120.04) OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)
Starting H2O JVM and connecting: .... Connection successful!
R is connected to the H2O cluster: H2O cluster uptime: 5 seconds 862 milliseconds H2O cluster timezone: Europe/Rome H2O data parsing timezone: UTC H2O cluster version: 3.28.0.2 H2O cluster version age: 8 months and 13 days !!! H2O cluster name: H2O_started_from_R_gian_kyb058 H2O cluster total nodes: 1 H2O cluster total memory: 1.92 GB H2O cluster total cores: 2 H2O cluster allowed cores: 2 H2O cluster healthy: TRUE H2O Connection ip: localhost H2O Connection port: 54321 H2O Connection proxy: NA H2O Internal Security: FALSE H2O API Extensions: Amazon S3, XGBoost, Algos, AutoML, Core V3, TargetEncoder, Core V4 R Version: R version 3.6.3 (2020-02-29)
df_hf <- as.h2o(training)
y <- "target"
x <- names(training)[2:18]
aml <- h2o.automl(x = x, y = y,
training_frame = df_hf,
max_runtime_secs = 300)
Come algoritmo viene trovato XGBoost
lb <- aml@leaderboard
lb
1 XGBoost_1_AutoML_20201003_190717
Il modello trovato si prova sul dataset di testing...
test <- as.h2o(testing)
model <- aml@leader
p1 = h2o.predict(model, newdata=test)
Si calcola l'accuratezza che è del 99,53% sul testing set:
df2 <- as.data.frame(p1$predict)
mean(df2$predict==testing$target)
[1] 0.9953368
Si costruisce la matrice di confusione e si trova l'accuratezza del 99,53% con una specificity del 34,55% che indica la possibilità di trovare molti falsi positivi sebbene il modello sia molto accurato:
confusionMatrix(df2$predict,testing$target)
Confusion Matrix and Statistics
Reference Prediction 0 1 0 231933 555 1 533 293 Accuracy : 0.9953 95% CI : (0.9951, 0.9956) No Information Rate : 0.9964 P-Value [Acc > NIR] : 1.0000 Kappa : 0.3477 Mcnemar's Test P-Value : 0.5243 Sensitivity : 0.9977 Specificity : 0.3455 Pos Pred Value : 0.9976 Neg Pred Value : 0.3547 Prevalence : 0.9964 Detection Rate : 0.9941 Detection Prevalence : 0.9965 Balanced Accuracy : 0.6716 'Positive' Class : 0
Controversie sull'uso del modello
[modifica | modifica sorgente]Con questo modello una persona povera, proveniente da un quartiere disagiato rischia di non avere la carta di credito o di averla con un credito basso e tassi di interesse più elevati.[1]
- ↑ Cathy O'Neil, Armi di distruzione matematica, Saggi Bompiani.