Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione presenta un esempio end-to-end di un flusso di lavoro di data science Synapse in Microsoft Fabric. Lo scenario crea un modello per prevedere se i clienti di una banca abbandonano. Il tasso di abbandono, o tasso di attrito, rappresenta il tasso a cui i clienti di una banca terminano il loro rapporto con la banca.
Questa esercitazione comprende i seguenti passaggi:
- Installare librerie personalizzate
- Caricare i dati
- Comprendere ed elaborare i dati tramite l'analisi esplorativa dei dati
- Usare scikit-learn e LightGBM per eseguire il training di modelli di Machine Learning
- Valutare e salvare il modello di apprendimento automatico finale
- Visualizzare le prestazioni del modello con le visualizzazioni di Power BI
Prerequisiti
Ottenere una sottoscrizione di Microsoft Fabric. In alternativa, iscriversi per ottenere una versione di valutazione di Microsoft Fabric gratuita.
Accedere a Microsoft Fabric.
Usa il selettore di esperienze sul lato inferiore sinistro della home page per passare a Fabric.
Screenshot del menu con l’opzione esperienza, che mostra dove selezionare Data Science.
- Se necessario, creare un lakehouse di Microsoft Fabric come descritto in Creare un lakehouse in Microsoft Fabric.
Seguire la procedura in un notebook
È possibile scegliere una di queste opzioni per seguire la procedura in un notebook:
- Aprire ed eseguire il notebook predefinito nell'esperienza di data science di Synapse.
- Caricare il notebook da GitHub nell'esperienza di data science di Synapse.
Aprire il notebook predefinito
Il notebook di abbandono dei clienti di esempio accompagna questa esercitazione.
Per aprire il notebook di esempio per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni sull'analisi scientifica dei dati.
Assicurarsi di collegare una lakehouse al notebook prima di iniziare a eseguire il codice.
Importare il notebook da GitHub
Il notebook AIsample - R Bank Customer Churn.ipynb accompagna questa esercitazione.
Per aprire il notebook di accompagnamento per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni di data science per importare il notebook nell'area di lavoro.
Se si preferisce copiare e incollare il codice da questa pagina, è possibile creare un nuovo notebook.
Assicurarsi di collegare un lakehouse al notebook prima di iniziare a eseguire il codice.
Passaggio 1: Installare librerie personalizzate
Per lo sviluppo di modelli di apprendimento automatico o l'analisi dei dati ad hoc, potrebbe essere necessario installare rapidamente una libreria personalizzata per la sessione di Apache Spark. Sono disponibili due opzioni per installare le librerie.
- Usare le risorse di installazione inline, ad esempio
install.packages
edevtools::install_version
, per installare solo nel notebook corrente. - In alternativa, è possibile creare un ambiente Fabric, installare librerie da origini pubbliche o caricarvi librerie personalizzate e quindi l'amministratore dell'area di lavoro può collegare l'ambiente come predefinito per l'area di lavoro. Tutte le librerie nell'ambiente diventano quindi disponibili per l'uso in qualsiasi notebook e definizione del processo Spark nell'area di lavoro. Per altre informazioni sugli ambienti, vedere Creare, configurare e usare un ambiente in Microsoft Fabric.
In questa esercitazione usare install.packages()
per installare le librerie imbalance
e randomForest
. Impostare quiet
su TRUE
per rendere l'output più conciso:
# Install imbalance for SMOTE
install.packages("imbalance", quiet = TRUE)
# Install the random forest algorithm
install.packages("randomForest", quiet=TRUE)
Passaggio 2: Caricare i dati
Il set di dati in churn.csv contiene lo stato di abbandono di 10.000 clienti, insieme a 14 attributi che includono:
- Punteggio sul credito
- Posizione geografica (Germania, Francia, Spagna)
- Sesso (maschio, femmina)
- Età
- Anzianità (numero di anni in cui la persona è stata cliente in quella banca)
- Saldo del conto
- Stipendio stimato
- Numero di prodotti acquistati da un cliente tramite la banca
- Stato della carta di credito (se un cliente ha o meno una carta di credito)
- Stato membro attivo (se la persona è un cliente della banca attivo o meno)
Il set di dati include anche le colonne numero di riga, ID cliente e cognome del cliente. I valori in queste colonne non devono influenzare la decisione di un cliente di lasciare la banca.
Un evento di chiusura del conto bancario del cliente definisce l’abbandono per il cliente. La colonna del set di dati Exited
si riferisce all'abbandono del cliente. Dato che questi attributi hanno poco contesto, non sono necessarie informazioni di base sul set di dati. Si vuole comprendere come questi attributi contribuiscono allo stato Exited
.
Su 10.000 clienti, solo i clienti del 2037 (circa il 20%) hanno lasciato la banca. A causa del rapporto di squilibrio tra classi, è consigliabile generare la generazione di dati sintetici.
Questa tabella mostra un esempio di anteprima dei dati churn.csv
:
CustomerID | Cognome | CreditScore | Geografia | Genere | Età | Mandato | Saldo | NumOfProducts | HasCrCard | IsActiveMember | EstimatedSalary | Usciti |
---|---|---|---|---|---|---|---|---|---|---|---|---|
15634602 | Hargrave | 619 | Francia | Femmina | 42 | 2 | 0.00 | 1 | 1 | 1 | 101348.88 | 1 |
15647311 | Hill | 608 | Spagna | Femmina | 41 | 1 | 83807.86 | 1 | 0 | 1 | 112542.58 | 0 |
Scaricare il set di dati e caricarlo nel lakehouse
Importante
Aggiungere un lakehouse al notebook prima di eseguirlo. In caso contrario, verrà generato un errore.
Questo codice scarica una versione disponibile pubblicamente del set di dati e quindi archivia i dati in un lakehouse di Fabric:
library(fs)
library(httr)
remote_url <- "https://sdkstorerta.blob.core.windows.net/churnblob"
file_list <- c("churn.csv")
download_path <- "/lakehouse/default/Files/churn/raw"
if (!dir_exists("/lakehouse/default")) {
stop("Default lakehouse not found, please add a lakehouse and restart the session.")
}
dir_create(download_path, recurse= TRUE)
for (fname in file_list) {
if (!file_exists(paste0(download_path, "/", fname))) {
r <- GET(paste0(remote_url, "/", fname), timeout(30))
writeBin(content(r, "raw"), paste0(download_path, "/", fname))
}
}
print("Downloaded demo data files into lakehouse.")
Avviare la registrazione del tempo necessario per eseguire questo notebook:
# Record the notebook running time
ts <- as.numeric(Sys.time())
Leggere i dati di data non elaborati dal lakehouse
Questo codice legge i dati non elaborati dalla sezione File del lakehouse:
fname <- "churn.csv"
download_path <- "/lakehouse/default/Files/churn/raw"
rdf <- readr::read_csv(paste0(download_path, "/", fname))
Passaggio 3: Eseguire l'analisi esplorativa dei dati
Visualizzazione di dati non elaborati
Usare i comandi head()
o str()
per eseguire un'esplorazione preliminare dei dati non elaborati:
head(rdf)
Eseguire la pulizia iniziale dei dati
Convertire R DataFrame in un Spark DataFrame. Queste operazioni sul dataframe Spark puliscono il set di dati non elaborato:
- Eliminare le righe con dati mancanti in tutte le colonne
- Eliminare le righe duplicate tra le colonne
RowNumber
eCustomerId
- Escludere la colonna
RowNumber
,CustomerId
eSurname
# Transform the R DataFrame to a Spark DataFrame
df <- as.DataFrame(rdf)
clean_data <- function(df) {
sdf <- df %>%
# Drop rows that have missing data across all columns
na.omit() %>%
# Drop duplicate rows in columns: 'RowNumber', 'CustomerId'
dropDuplicates(c("RowNumber", "CustomerId")) %>%
# Drop columns: 'RowNumber', 'CustomerId', 'Surname'
SparkR::select("CreditScore", "Geography", "Gender", "Age", "Tenure", "Balance", "NumOfProducts", "HasCrCard", "IsActiveMember", "EstimatedSalary", "Exited")
return(sdf)
}
df_clean <- clean_data(df)
Esplorare il dataframe Spark con il comando display
:
display(df_clean)
Questo codice determina gli attributi categorici, numerici e di destinazione:
# Determine the dependent (target) attribute
dependent_variable_name <- "Exited"
print(dependent_variable_name)
# Obtain the distinct values for each column
exprs = lapply(names(df_clean), function(x) alias(countDistinct(df_clean[[x]]), x))
# Use do.call to splice the aggregation expressions to aggregate function
distinct_value_number <- SparkR::collect(do.call(agg, c(x = df_clean, exprs)))
# Determine the categorical attributes
categorical_variables <- names(df_clean)[sapply(names(df_clean), function(col) col %in% c("0") || distinct_value_number[[col]] <= 5 && !(col %in% c(dependent_variable_name)))]
print(categorical_variables)
# Determine the numerical attributes
numeric_variables <- names(df_clean)[sapply(names(df_clean), function(col) coltypes(SparkR::select(df_clean, col)) == "numeric" && distinct_value_number[[col]] > 5)]
print(numeric_variables)
Per semplificare l'elaborazione e la visualizzazione, convertire il dataframe Spark pulito in un dataframe R:
# Transform the Spark DataFrame to an R DataFrame
rdf_clean <- SparkR::collect(df_clean)
Visualizzare il riepilogo in cinque numeri
Usare i box plot per visualizzare il riepilogo a cinque numeri (punteggio minimo, primo quartile, mediano, terzo quartile, punteggio massimo) per gli attributi numerici:
# Set the overall layout of the graphics window
par(mfrow = c(2, 1),
mar = c(2, 1, 2, 1)) # Margin size
for(item in numeric_variables[1:2]){
# Create a box plot
boxplot(rdf_clean[, item],
main = item,
col = "darkgreen",
cex.main = 1.5, # Title size
cex.lab = 1.3, # Axis label size
cex.axis = 1.2,
horizontal = TRUE) # Axis size
}
Screenshot che mostra i tracciati box per il punteggio di credito e l'età.
# Set the overall layout of the graphics window
par(mfrow = c(3, 1),
mar = c(2, 1, 2, 1)) # Margin size
for(item in numeric_variables[3:5]){
# Create a box plot
boxplot(rdf_clean[, item],
main = item,
col = "darkgreen",
cex.main = 1.5, # Title size
cex.lab = 1.3, # Axis label size
cex.axis = 1.2,
horizontal = TRUE) # Axis size
}
Screenshot che mostra i tracciati box per le variabili numeriche.
Visualizzare la distribuzione dei clienti usciti e non usciti
Visualizzare la distribuzione dei clienti usciti rispetto ai clienti non usciti, tra gli attributi categorici:
attr_list <- c('Geography', 'Gender', 'HasCrCard', 'IsActiveMember', 'NumOfProducts', 'Tenure')
par(mfrow = c(2, 1),
mar = c(2, 1, 2, 1)) # Margin size
for (item in attr_list[1:2]) {
counts <- table(rdf_clean$Exited, rdf_clean[,item])
barplot(counts, main=item, col=c("darkblue","yellow"),
cex.main = 1.5, # Title size
cex.axis = 1.2,
legend = rownames(counts), beside=TRUE)
}
Screenshot che mostra i tracciati a barre suddivisi per geografia e sesso.
par(mfrow = c(2, 1),
mar = c(2, 2, 2, 1)) # Margin size
for (item in attr_list[3:4]) {
counts <- table(rdf_clean$Exited, rdf_clean[,item])
barplot(counts, main=item, col=c("darkblue","yellow"),
cex.main = 1.5, # Title size
cex.axis = 1.2,
legend = rownames(counts), beside=TRUE)
}
Screenshot che mostra grafici a barre per i clienti con carta di credito e membri attivi.
par(mfrow = c(2, 1),
mar = c(2, 1, 2, 1)) # Margin size
for (item in attr_list[5:6]) {
counts <- table(rdf_clean$Exited, rdf_clean[,item])
barplot(counts, main=item, col=c("darkblue","yellow"),
cex.main = 1.5, # Title size
cex.axis = 1.2,
legend = rownames(counts), beside=TRUE)
}
Screenshot che mostra grafici a barre per il numero di prodotti e tenure.
Visualizzare la distribuzione degli attributi numerici
Usare un istogramma per visualizzare la distribuzione della frequenza degli attributi numerici:
# Set the overall layout of the graphics window
par(mfrow = c(2, 1),
mar = c(2, 4, 2, 4) + 0.1) # Margin size
# Create a histogram
for (item in numeric_variables[1:2]) {
hist(rdf_clean[, item],
main = item,
col = "darkgreen",
xlab = item,
cex.main = 1.5, # Title size
cex.axis = 1.2,
breaks = 20) # Number of bins
}
Screenshot di un grafico che mostra la distribuzione del punteggio di credito e dell'età.
# Set the overall layout of the graphics window
par(mfrow = c(3, 1),
mar = c(2, 4, 2, 4) + 0.1) # Margin size
# Create a histogram
for (item in numeric_variables[3:5]) {
hist(rdf_clean[, item],
main = item,
col = "darkgreen",
xlab = item,
cex.main = 1.5, # Title size
cex.axis = 1.2,
breaks = 20) # Number of bins
}
Screenshot di un grafico che mostra la distribuzione delle variabili numeriche.
Eseguire l'ingegneria delle funzionalità
Questa progettazione di funzionalità genera nuovi attributi in base agli attributi correnti:
rdf_clean$NewTenure <- rdf_clean$Tenure / rdf_clean$Age
rdf_clean$NewCreditsScore <- as.numeric(cut(rdf_clean$CreditScore, breaks=quantile(rdf_clean$CreditScore, probs=seq(0, 1, by=1/6)), include.lowest=TRUE, labels=c(1, 2, 3, 4, 5, 6)))
rdf_clean$NewAgeScore <- as.numeric(cut(rdf_clean$Age, breaks=quantile(rdf_clean$Age, probs=seq(0, 1, by=1/8)), include.lowest=TRUE, labels=c(1, 2, 3, 4, 5, 6, 7, 8)))
rdf_clean$NewBalanceScore <- as.numeric(cut(rank(rdf_clean$Balance), breaks=quantile(rank(rdf_clean$Balance, ties.method = "first"), probs=seq(0, 1, by=1/5)), include.lowest=TRUE, labels=c(1, 2, 3, 4, 5)))
rdf_clean$NewEstSalaryScore <- as.numeric(cut(rdf_clean$EstimatedSalary, breaks=quantile(rdf_clean$EstimatedSalary, probs=seq(0, 1, by=1/10)), include.lowest=TRUE, labels=c(1:10)))
Eseguire la codifica one-hot
Usare la codifica one-hot per convertire gli attributi categorici in attributi numerici, per inserirli nel modello di Machine Learning:
rdf_clean <- cbind(rdf_clean, model.matrix(~Geography+Gender-1, data=rdf_clean))
rdf_clean <- subset(rdf_clean, select = - c(Geography, Gender))
Creare una tabella differenziale per generare il report di Power BI
table_name <- "rdf_clean"
# Create a Spark DataFrame from an R DataFrame
sparkDF <- as.DataFrame(rdf_clean)
write.df(sparkDF, paste0("Tables/", table_name), source = "delta", mode = "overwrite")
cat(paste0("Spark DataFrame saved to delta table: ", table_name))
Riepilogo delle osservazioni dell'analisi esplorativa dei dati
- La maggior parte dei clienti proviene dalla Francia. La Spagna ha il tasso di abbandono più basso, rispetto alla Francia e alla Germania.
- La maggior parte dei clienti ha carte di credito
- Alcuni clienti superano i 60 anni di età e hanno punteggi di credito inferiori a 400. Tuttavia, non possono essere considerati come outlier
- Pochi clienti hanno più di due prodotti bancari
- I clienti inattivi hanno un tasso di abbandono più elevato
- Il sesso e gli anni di anzianità hanno un impatto minimo sulla decisione di un cliente di chiudere un conto bancario
Passaggio 4: Eseguire il training del modello
Con i dati disponibili, è ora possibile definire il modello. Applicare modelli Random Forest e LightGBM. Usare randomForest e LightGBM per implementare i modelli con poche righe di codice.
Caricare la tabella delta dal lakehouse. È possibile usare altre tabelle delta che considerano il lakehouse come origine.
SEED <- 12345
rdf_clean <- read.df("Tables/rdf_clean", source = "delta")
df_clean <- as.data.frame(rdf_clean)
Importare randomForest e LightGBM:
library(randomForest)
library(lightgbm)
Preparare i set di dati di training e test:
set.seed(SEED)
y <- factor(df_clean$Exited)
X <- df_clean[, !(colnames(df_clean) %in% c("Exited"))]
split <- base::sample(c(TRUE, FALSE), nrow(df_clean), replace = TRUE, prob = c(0.8, 0.2))
X_train <- X[split,]
X_test <- X[!split,]
y_train <- y[split]
y_test <- y[!split]
train_df <- cbind(X_train, y_train)
Applicare SMOTE al set di dati di training
La classificazione sbilanciata presenta un problema, poiché contiene troppi esempi della classe di minoranza per un modello per apprendere efficacemente il limite decisionale. Per gestire questo problema, Synthetic Minority Oversampling Technique (SMOTE) è la tecnica più usata per sintetizzare nuovi campioni per la classe di minoranza. Accedere a SMOTE con la libreria imblearn
installata nel passaggio 1.
Applicare SMOTE solo al set di dati di training. È necessario lasciare il set di dati di test nella distribuzione originale sbilanciata per ottenere un'approssimazione valida delle prestazioni del modello sui dati originali. Questo esperimento rappresenta la situazione in produzione.
In primo luogo, mostrare la distribuzione delle classi nel set di dati per apprendere quale classe è la classe di minoranza. Il rapporto tra la classe di minoranza e la classe di maggioranza è definito come imbalance Ratio
nella libreria imbalance
.
original_ratio <- imbalance::imbalanceRatio(train_df, classAttr = "y_train")
message(sprintf("Original imbalance ratio is %.2f%% as {Size of minority class}/{Size of majority class}.", original_ratio * 100))
message(sprintf("Positive class(Exited) takes %.2f%% of the dataset.", round(sum(train_df$y_train == 1)/nrow(train_df) * 100, 2)))
message(sprintf("Negative class(Non-Exited) takes %.2f%% of the dataset.", round(sum(train_df$y_train == 0)/nrow(train_df) * 100, 2)))
Nel set di dati di training:
Positive class(Exited)
fa riferimento alla classe di minoranza, che accetta il 20,34% del set di dati.Negative class(Non-Exited)
fa riferimento alla classe di maggioranza, che accetta il 79,66% del set di dati.
La cella successiva riscrive la funzione di sovracampionamento della libreria imbalance
per generare un set di dati bilanciato:
binary_oversample <- function(train_df, X_train, y_train, class_Attr = "Class"){
negative_num <- sum(y_train == 0) # Compute the number of the negative class
positive_num <- sum(y_train == 1) # Compute the number of the positive class
difference_num <- abs(negative_num - positive_num) # Compute the difference between the negative and positive classes
originalShape <- imbalance:::datasetStructure(train_df, class_Attr) # Get the original dataset schema
new_samples <- smotefamily::SMOTE(X_train, y_train, dup_size = ceiling(max(negative_num, positive_num)/min(negative_num, positive_num))) # Use SMOTE to oversample
new_samples <- new_samples$syn_data # Get the synthetic data
new_samples <- new_samples[base::sample(1:nrow(new_samples), size = difference_num), ] # Sample and shuffle the synthetic data
new_samples <- new_samples[, -ncol(new_samples)] # Remove the class column
new_samples <- imbalance:::normalizeNewSamples(originalShape, new_samples) # Normalize the synthetic data
new_train_df <- rbind(train_df, new_samples) # Concatenate original and synthetic data by row
new_train_df <- new_train_df[base::sample(nrow(new_train_df)), ] # Shuffle the training dataset
new_train_df
}
Per altre informazioni su SMOTE, vedere le risorse Pacchetto imbalance
e Lavorare con insiemi di dati sbilanciati sul sito web CRAN.
Sovracampionare il set di dati di training
Usare la funzione di sovracampionamento appena definita per eseguire il sovracampionamento nel set di dati di training:
library(dplyr)
new_train_df <- binary_oversample(train_df, X_train, y_train, class_Attr="y_train")
smote_ratio <- imbalance::imbalanceRatio(new_train_df, classAttr = "y_train")
message(sprintf("Imbalance ratio after using smote is %.2f%%\n", smote_ratio * 100))
Eseguire il training del modello
Usare una foresta casuale per eseguire il training del modello, con quattro funzionalità:
set.seed(1)
rfc1_sm <- randomForest(y_train ~ ., data = new_train_df, ntree = 500, mtry = 4, nodesize = 3)
y_pred <- predict(rfc1_sm, X_test, type = "response")
cr_rfc1_sm <- caret::confusionMatrix(y_pred, y_test)
cm_rfc1_sm <- table(y_pred, y_test)
roc_auc_rfc1_sm <- pROC::auc(pROC::roc(as.numeric(y_test), as.numeric(y_pred)))
print(paste0("The auc is ", roc_auc_rfc1_sm))
Usare una foresta casuale per eseguire il training del modello, con sei funzionalità:
rfc2_sm <- randomForest(y_train ~ ., data = new_train_df, ntree = 500, mtry = 6, nodesize = 3)
y_pred <- predict(rfc2_sm, X_test, type = "response")
cr_rfc2_sm <- caret::confusionMatrix(y_pred, y_test)
cm_rfc2_sm <- table(y_pred, y_test)
roc_auc_rfc2_sm <- pROC::auc(pROC::roc(as.numeric(y_test), as.numeric(y_pred)))
print(paste0("The auc is ", roc_auc_rfc2_sm))
Eseguire il training del modello con LightGBM:
set.seed(42)
X_train <- new_train_df[, !(colnames(new_train_df) %in% c("y_train"))]
y_train <- as.numeric(as.character(new_train_df$y_train))
y_test <- as.numeric(as.character(y_test))
lgbm_sm_model <- lgb.train(list(objective = "binary", learning_rate = 0.1, max_delta_step = 2, nrounds = 100, max_depth = 10, eval_metric = "logloss"), lgb.Dataset(as.matrix(X_train), label = as.vector(y_train)), valids = list(test = lgb.Dataset(as.matrix(X_test), label = as.vector(as.numeric(y_test)))))
y_pred <- as.numeric(predict(lgbm_sm_model, as.matrix(X_test)) > 0.5)
accuracy <- mean(y_pred == as.vector(y_test))
cr_lgbm_sm <- caret::confusionMatrix(as.factor(y_pred), as.factor(as.vector(y_test)))
cm_lgbm_sm <- table(y_pred, as.vector(y_test))
roc_auc_lgbm_sm <- pROC::auc(pROC::roc(as.vector(y_test), y_pred))
print(paste0("The auc is ", roc_auc_lgbm_sm))
Passaggio 5: valutare e salvare il modello di apprendimento automatico finale
Valutare le prestazioni dei modelli salvati nel set di dati di test:
ypred_rfc1_sm <- predict(rfc1_sm, X_test, type = "response")
ypred_rfc2_sm <- predict(rfc2_sm, X_test, type = "response")
ypred_lgbm1_sm <- as.numeric(predict(lgbm_sm_model, as.matrix(X_test)) > 0.5)
Mostrare veri/falsi positivi/negativi con una matrice di confusione. Sviluppare uno script per tracciare la matrice di confusione per valutare l'accuratezza della classificazione:
plot_confusion_matrix <- function(cm, classes, normalize=FALSE, title='Confusion matrix', cmap=heat.colors(10)) {
if (normalize) {
cm <- cm / rowSums(cm)
}
op <- par(mar = c(6,6,3,1))
image(1:nrow(cm), 1:ncol(cm), t(cm[nrow(cm):1,]), col = cmap, xaxt = 'n', yaxt = 'n', main = title, xlab = "Prediction", ylab = "Reference")
axis(1, at = 1:nrow(cm), labels = classes, las = 2)
axis(2, at = 1:ncol(cm), labels = rev(classes))
for (i in seq_len(nrow(cm))) {
for (j in seq_len(ncol(cm))) {
text(i, ncol(cm) - j + 1, cm[j,i], cex = 0.8)
}
}
par(op)
}
Creare una matrice di confusione per il classificatore di foresta casuale, con quattro funzionalità:
cfm <- table(y_test, ypred_rfc1_sm)
plot_confusion_matrix(cfm, classes=c('Non Churn','Churn'), title='Random Forest with features of 4')
tn <- cfm[1,1]
fp <- cfm[1,2]
fn <- cfm[2,1]
tp <- cfm[2,2]
Screenshot di un grafico che mostra una matrice di confusione per una foresta casuale con quattro funzionalità.
Creare una matrice di confusione per il classificatore di foresta casuale, con sei funzionalità:
cfm <- table(y_test, ypred_rfc2_sm)
plot_confusion_matrix(cfm, classes=c('Non Churn','Churn'), title='Random Forest with features of 6')
tn <- cfm[1,1]
fp <- cfm[1,2]
fn <- cfm[2,1]
tp <- cfm[2,2]
Screenshot di un grafico che mostra una matrice di confusione per una foresta casuale con sei funzionalità.
Creare una matrice di confusione per LightGBM:
cfm <- table(y_test, ypred_lgbm1_sm)
plot_confusion_matrix(cfm, classes=c('Non Churn','Churn'), title='LightGBM')
tn <- cfm[1,1]
fp <- cfm[1,2]
fn <- cfm[2,1]
tp <- cfm[2,2]
Screenshot di un grafico che mostra una matrice di confusione per LightGBM.
Salvare i risultati per Power BI
Salvare il frame differenziale nel lakehouse per spostare i risultati della stima del modello in una visualizzazione di Power BI:
df_pred <- X_test
df_pred$y_test <- y_test
df_pred$ypred_rfc1_sm <- ypred_rfc1_sm
df_pred$ypred_rfc2_sm <- ypred_rfc2_sm
df_pred$ypred_lgbm1_sm <- ypred_lgbm1_sm
table_name <- "df_pred_results"
sparkDF <- as.DataFrame(df_pred)
write.df(sparkDF, paste0("Tables/", table_name), source = "delta", mode = "overwrite", overwriteSchema = "true")
cat(paste0("Spark DataFrame saved to delta table: ", table_name))
Passaggio 6: Accedere alle visualizzazioni in Power BI
Accedere alla tabella salvata in Power BI:
- A sinistra selezionare Hub dati OneLake
- Selezionare il lakehouse aggiunto a questo notebook
- Nella sezione Apri questo lakehouse selezionare Apri
- Nella barra multifunzione selezionare Nuovo modello semantico. Selezionare
df_pred_results
e quindi Continua per creare un nuovo modello semantico di Power BI collegato alle stime - Nella parte superiore della pagina del set di dati selezionare Nuovo report per aprire la pagina di creazione di report di Power BI.
Lo screenshot seguente mostra alcune visualizzazioni di esempio. Il pannello dati mostra le tabelle e le colonne differenziali da selezionare da una tabella. Dopo aver selezionato l'asse e il valore (y) appropriati, è possibile scegliere i filtri e le funzioni. Ad esempio, è possibile scegliere una somma o una media della colonna della tabella.
Nota
Lo screenshot è un esempio illustrato che mostra l'analisi dei risultati della stima salvata in Power BI. Per un caso d'uso reale della varianza dei clienti, gli utenti della piattaforma potrebbero avere bisogno di un'idea più approfondita delle visualizzazioni da creare, in base alle competenze in materia e a ciò che il team di analisi aziendale e dell’organizzazione hanno standardizzato come metriche.
Screenshot che mostra la dashboard di Power BI dei dati.
Il report di Power BI mostra che i clienti che usano più di due prodotti bancari hanno un tasso di abbandono più elevato. Tuttavia, pochi clienti avevano più di due prodotti. Vedere il tracciato nel pannello in basso a sinistra. La banca dovrebbe raccogliere più dati, ma anche analizzare altre funzionalità correlate a più prodotti.
I clienti della banca in Germania hanno un tasso di abbandono più elevato rispetto ai clienti in Francia e Spagna. Vedere il tracciato nel pannello in basso a destra. In base ai risultati del report, un'indagine sui fattori che hanno incoraggiato i clienti a lasciare potrebbe aiutare.
Ci sono più clienti di mezza età (tra i 25 e i 45 anni). I clienti tra i 45 e i 60 anni tendono a uscire di più.
Infine, i clienti con punteggi di credito più bassi lasciano la banca per altri istituti finanziari. La banca dovrebbe esplorare i modi per incoraggiare i clienti con punteggi di credito e saldi di conto più bassi a rimanere.
# Determine the entire runtime
cat(paste0("Full run cost ", as.integer(Sys.time() - ts), " seconds.\n"))