Partilhar via


Tutorial: Criar, avaliar e pontuar um modelo de previsão de rotatividade

Este tutorial apresenta um exemplo completo de um fluxo de trabalho Synapse Data Science no Microsoft Fabric. O cenário constrói um modelo para prever a rotatividade ou não dos clientes bancários. A taxa de churn, ou a taxa de atrito, envolve a taxa à qual os clientes bancários terminam os seus negócios com o banco.

Este tutorial aborda estas etapas:

  • Instalar bibliotecas personalizadas
  • Carregar os dados
  • Compreenda e processe os dados por meio da análise exploratória de dados e mostre o uso do recurso Fabric Data Wrangler
  • Use o scikit-learn e o LightGBM para treinar modelos de aprendizado de máquina e acompanhar experimentos com os recursos MLflow e Fabric Autologging
  • Avalie e salve o modelo final de aprendizado de máquina
  • Mostrar o desempenho do modelo com visualizações do Power BI

Pré-requisitos

  • Obtenha uma assinatura do Microsoft Fabric. Ou inscreva-se para uma avaliação gratuita do Microsoft Fabric.

  • Entre no Microsoft Fabric.

  • Use o seletor de experiência no lado esquerdo da sua página inicial para alternar para a experiência Synapse Data Science.

    Screenshot of the experience switcher menu, showing where to select Data Science.

Acompanhe num caderno

Você pode escolher uma destas opções para acompanhar em um bloco de anotações:

  • Abra e execute o bloco de anotações integrado na experiência de Ciência de Dados
  • Carregue seu bloco de anotações do GitHub para a experiência de Ciência de Dados

Abra o bloco de notas incorporado

O exemplo de bloco de anotações de rotatividade do cliente acompanha este tutorial.

Para abrir o bloco de anotações de exemplo integrado do tutorial na experiência Synapse Data Science:

  1. Vá para a página inicial do Synapse Data Science.

  2. Selecione Usar uma amostra.

  3. Selecione a amostra correspondente:

    • Na guia padrão End-to-end workflows (Python), se o exemplo for para um tutorial do Python.
    • Na guia Fluxos de trabalho de ponta a ponta (R), se o exemplo for para um tutorial R.
    • Na guia Tutoriais rápidos, se o exemplo for para um tutorial rápido.
  4. Anexe um lakehouse ao bloco de anotações antes de começar a executar o código.

Importar o bloco de anotações do GitHub

O notebook AIsample - Bank Customer Churn.ipynb acompanha este tutorial.

Para abrir o bloco de anotações que acompanha este tutorial, siga as instruções em Preparar seu sistema para tutoriais de ciência de dados, para importar o bloco de anotações para seu espaço de trabalho.

Se preferir copiar e colar o código desta página, pode criar um novo bloco de notas.

Certifique-se de anexar um lakehouse ao bloco de anotações antes de começar a executar o código.

Etapa 1: Instalar bibliotecas personalizadas

Para desenvolvimento de modelo de aprendizado de máquina ou análise de dados ad-hoc, talvez seja necessário instalar rapidamente uma biblioteca personalizada para sua sessão do Apache Spark. Você tem duas opções para instalar bibliotecas.

  • Utilize as capacidades de instalação em linha (%pip ou %conda) do seu bloco de notas para instalar uma biblioteca, apenas no seu bloco de notas atual.
  • Como alternativa, você pode criar um ambiente de malha, instalar bibliotecas de fontes públicas ou carregar bibliotecas personalizadas para ele e, em seguida, o administrador do espaço de trabalho pode anexar o ambiente como padrão para o espaço de trabalho. Todas as bibliotecas no ambiente ficarão disponíveis para uso em quaisquer blocos de anotações e definições de trabalho do Spark no espaço de trabalho. Para obter mais informações sobre ambientes, consulte criar, configurar e usar um ambiente no Microsoft Fabric.

Para este tutorial, use %pip install para instalar a imblearn biblioteca em seu bloco de anotações.

Nota

O kernel do PySpark é reiniciado após %pip install as execuções. Instale as bibliotecas necessárias antes de executar quaisquer outras células.

# Use pip to install libraries
%pip install imblearn

Passo 2: Carregue os dados

O conjunto de dados no churn.csv contém o status de rotatividade de 10.000 clientes, juntamente com 14 atributos que incluem:

  • Pontuação de crédito
  • Localização geográfica (Alemanha, França, Espanha)
  • Sexo (masculino, feminino)
  • Antiguidade
  • Titularidade (número de anos em que a pessoa foi cliente desse banco)
  • Saldo da conta
  • Salário estimado
  • Número de produtos que um cliente comprou através do banco
  • Estado do cartão de crédito (quer o cliente tenha ou não um cartão de crédito)
  • Estatuto de membro ativo (quer a pessoa seja ou não um cliente bancário ativo)

O conjunto de dados também inclui colunas de número de linha, ID do cliente e sobrenome do cliente. Os valores nestas colunas não devem influenciar a decisão de um cliente de sair do banco.

Um evento de encerramento da conta bancária do cliente define a rotatividade desse cliente. A coluna do conjunto Exited de dados refere-se ao abandono do cliente. Como temos pouco contexto sobre esses atributos, não precisamos de informações básicas sobre o conjunto de dados. Queremos entender como esses atributos contribuem para o Exited status.

Desses 10.000 clientes, apenas 2037 clientes (cerca de 20%) deixaram o banco. Devido à taxa de desequilíbrio de classe, recomendamos a geração de dados sintéticos. A precisão da matriz de confusão pode não ter relevância para uma classificação desequilibrada. Podemos querer medir a precisão usando a Área sob a Curva de Precisão-Recordação (AUPRC).

  • Esta tabela mostra uma visualização dos churn.csv dados:
IDDeCliente Apelido Pontuação de Crédito Geografia Sexo Antiguidade Situação profissional Saldo NumOfProducts HasCrCard IsActiveMember Salário estimado Saiu
15634602 Hargrave 619 França Feminino 42 2 0.00 1 1 1 101348.88 5
15647311 Colina 608 Espanha Feminino 41 5 83807.86 5 0 5 112542.58 0

Faça o download do conjunto de dados e faça o upload para a casa do lago

Defina estes parâmetros, para que possa utilizar este bloco de notas com diferentes conjuntos de dados:

IS_CUSTOM_DATA = False  # If TRUE, the dataset has to be uploaded manually

IS_SAMPLE = False  # If TRUE, use only SAMPLE_ROWS of data for training; otherwise, use all data
SAMPLE_ROWS = 5000  # If IS_SAMPLE is True, use only this number of rows for training

DATA_ROOT = "/lakehouse/default"
DATA_FOLDER = "Files/churn"  # Folder with data files
DATA_FILE = "churn.csv"  # Data file name

Esse código baixa uma versão disponível publicamente do conjunto de dados e, em seguida, armazena esse conjunto de dados em uma casa de lago de malha:

Importante

Adicione uma casa de lago ao bloco de anotações antes de executá-lo. Se não o fizer, haverá um erro.

import os, requests
if not IS_CUSTOM_DATA:
# With an Azure Synapse Analytics blob, this can be done in one line

# Download demo data files into the lakehouse if they don't exist
    remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/bankcustomerchurn"
    file_list = ["churn.csv"]
    download_path = "/lakehouse/default/Files/churn/raw"

    if not os.path.exists("/lakehouse/default"):
        raise FileNotFoundError(
            "Default lakehouse not found, please add a lakehouse and restart the session."
        )
    os.makedirs(download_path, exist_ok=True)
    for fname in file_list:
        if not os.path.exists(f"{download_path}/{fname}"):
            r = requests.get(f"{remote_url}/{fname}", timeout=30)
            with open(f"{download_path}/{fname}", "wb") as f:
                f.write(r.content)
    print("Downloaded demo data files into lakehouse.")

Comece a gravar o tempo necessário para executar o notebook:

# Record the notebook running time
import time

ts = time.time()

Leia dados brutos da casa do lago

Esse código lê dados brutos da seção Arquivos da casa do lago e adiciona mais colunas para diferentes partes de data. A criação da tabela delta particionada usa essas informações.

df = (
    spark.read.option("header", True)
    .option("inferSchema", True)
    .csv("Files/churn/raw/churn.csv")
    .cache()
)

Criar um DataFrame pandas a partir do conjunto de dados

Este código converte o Spark DataFrame em um Pandas DataFrame, para facilitar o processamento e a visualização:

df = df.toPandas()

Etapa 3: Executar a análise exploratória de dados

Exibir dados brutos

Explore os dados brutos com display, calcule algumas estatísticas básicas e mostre visualizações de gráficos. Você deve primeiro importar as bibliotecas necessárias para visualização de dados - por exemplo, seaborn. Seaborn é uma biblioteca de visualização de dados Python e fornece uma interface de alto nível para construir visuais em dataframes e arrays.

import seaborn as sns
sns.set_theme(style="whitegrid", palette="tab10", rc = {'figure.figsize':(9,6)})
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib import rc, rcParams
import numpy as np
import pandas as pd
import itertools
display(df, summary=True)

Usar o Data Wrangler para executar a limpeza inicial de dados

Inicie o Data Wrangler diretamente do notebook para explorar e transformar dataframes pandas. Na guia Dados da faixa de opções do bloco de anotações, use o prompt suspenso Data Wrangler para procurar os DataFrames pandas ativados disponíveis para edição. Selecione o DataFrame que deseja abrir no Data Wrangler.

Nota

O Data Wrangler não pode ser aberto enquanto o kernel do notebook estiver ocupado. A execução da célula deve ser concluída antes de iniciar o Data Wrangler. Saiba mais sobre o Data Wrangler.

Screenshot that shows where to access Data Wrangler.

Depois que o Data Wrangler é iniciado, uma visão geral descritiva do painel de dados é gerada, conforme mostrado nas imagens a seguir. A visão geral inclui informações sobre a dimensão do DataFrame, quaisquer valores ausentes, etc. Você pode usar o Data Wrangler para gerar o script para soltar as linhas com valores ausentes, as linhas duplicadas e as colunas com nomes específicos. Em seguida, você pode copiar o script em uma célula. A próxima célula mostra esse script copiado.

Screenshot that shows the Data Wrangler menu.

Screenshot that shows missing data in Data Wrangler.

def clean_data(df):
    # Drop rows with missing data across all columns
    df.dropna(inplace=True)
    # Drop duplicate rows in columns: 'RowNumber', 'CustomerId'
    df.drop_duplicates(subset=['RowNumber', 'CustomerId'], inplace=True)
    # Drop columns: 'RowNumber', 'CustomerId', 'Surname'
    df.drop(columns=['RowNumber', 'CustomerId', 'Surname'], inplace=True)
    return df

df_clean = clean_data(df.copy())

Determinar atributos

Este código determina os atributos categóricos, numéricos e de destino:

# Determine the dependent (target) attribute
dependent_variable_name = "Exited"
print(dependent_variable_name)
# Determine the categorical attributes
categorical_variables = [col for col in df_clean.columns if col in "O"
                        or df_clean[col].nunique() <=5
                        and col not in "Exited"]
print(categorical_variables)
# Determine the numerical attributes
numeric_variables = [col for col in df_clean.columns if df_clean[col].dtype != "object"
                        and df_clean[col].nunique() >5]
print(numeric_variables)

Mostrar o resumo de cinco números

Use gráficos de caixa para mostrar o resumo de cinco números

  • a pontuação mínima
  • Primeiro quartil
  • mediana
  • terceiro quartil
  • pontuação máxima

para os atributos numéricos.

df_num_cols = df_clean[numeric_variables]
sns.set(font_scale = 0.7) 
fig, axes = plt.subplots(nrows = 2, ncols = 3, gridspec_kw =  dict(hspace=0.3), figsize = (17,8))
fig.tight_layout()
for ax,col in zip(axes.flatten(), df_num_cols.columns):
    sns.boxplot(x = df_num_cols[col], color='green', ax = ax)
# fig.suptitle('visualize and compare the distribution and central tendency of numerical attributes', color = 'k', fontsize = 12)
fig.delaxes(axes[1,2])

Screenshot that shows a notebook display of the box plot for numerical attributes.

Mostrar a distribuição de clientes que saíram e não saíram

Mostrar a distribuição de clientes saídos versus clientes não saídos, entre os atributos categóricos:

attr_list = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember', 'NumOfProducts', 'Tenure']
fig, axarr = plt.subplots(2, 3, figsize=(15, 4))
for ind, item in enumerate (attr_list):
    sns.countplot(x = item, hue = 'Exited', data = df_clean, ax = axarr[ind%2][ind//2])
fig.subplots_adjust(hspace=0.7)

Screenshot that shows a notebook display of the distribution of exited versus non-exited customers.

Mostrar a distribuição dos atributos numéricos

Use um histograma para mostrar a distribuição de frequência dos atributos numéricos:

columns = df_num_cols.columns[: len(df_num_cols.columns)]
fig = plt.figure()
fig.set_size_inches(18, 8)
length = len(columns)
for i,j in itertools.zip_longest(columns, range(length)):
    plt.subplot((length // 2), 3, j+1)
    plt.subplots_adjust(wspace = 0.2, hspace = 0.5)
    df_num_cols[i].hist(bins = 20, edgecolor = 'black')
    plt.title(i)
# fig = fig.suptitle('distribution of numerical attributes', color = 'r' ,fontsize = 14)
plt.show()

Screenshot that shows a notebook display of numerical attributes.

Executar engenharia de recursos

Essa engenharia de recursos gera novos atributos com base nos atributos atuais:

df_clean["NewTenure"] = df_clean["Tenure"]/df_clean["Age"]
df_clean["NewCreditsScore"] = pd.qcut(df_clean['CreditScore'], 6, labels = [1, 2, 3, 4, 5, 6])
df_clean["NewAgeScore"] = pd.qcut(df_clean['Age'], 8, labels = [1, 2, 3, 4, 5, 6, 7, 8])
df_clean["NewBalanceScore"] = pd.qcut(df_clean['Balance'].rank(method="first"), 5, labels = [1, 2, 3, 4, 5])
df_clean["NewEstSalaryScore"] = pd.qcut(df_clean['EstimatedSalary'], 10, labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

Use o Data Wrangler para executar uma codificação a quente

Com as mesmas etapas para iniciar o Data Wrangler, conforme discutido anteriormente, use o Data Wrangler para executar uma codificação a quente. Esta célula mostra o script gerado copiado para codificação one-hot:

Screenshot that shows one-hot encoding in Data Wrangler.

Screenshot that shows the selection of columns in Data Wrangler.

df_clean = pd.get_dummies(df_clean, columns=['Geography', 'Gender'])

Criar uma tabela delta para gerar o relatório do Power BI

table_name = "df_clean"
# Create a PySpark DataFrame from pandas
sparkDF=spark.createDataFrame(df_clean) 
sparkDF.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Resumo das observações da análise exploratória dos dados

  • A maioria dos clientes são da França. A Espanha tem a menor taxa de rotatividade, em comparação com a França e a Alemanha.
  • A maioria dos clientes tem cartões de crédito
  • Alguns clientes têm ambos mais de 60 anos e pontuações de crédito inferiores a 400. No entanto, eles não podem ser considerados como outliers
  • Muito poucos clientes têm mais de dois produtos bancários
  • Clientes inativos têm maior taxa de churn
  • O género e os anos de posse têm pouco impacto na decisão de um cliente de encerrar uma conta bancária

Etapa 4: Realizar o treinamento e o rastreamento do modelo

Com os dados instalados, agora você pode definir o modelo. Aplique modelos aleatórios de floresta e LightGBM neste notebook.

Use as bibliotecas scikit-learn e LightGBM para implementar os modelos, com algumas linhas de código. Além disso, use MLfLow e Fabric Autologging para rastrear os experimentos.

Este exemplo de código carrega a tabela delta da casa do lago. Você pode usar outras tabelas delta que usam a casa do lago como fonte.

SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()

Gere um experimento para rastrear e registrar os modelos usando MLflow

Esta seção mostra como gerar um experimento e especifica os parâmetros de modelo e treinamento e as métricas de pontuação. Além disso, mostra como treinar os modelos, registrá-los e salvar os modelos treinados para uso posterior.

import mlflow

# Set up the experiment name
EXPERIMENT_NAME = "sample-bank-churn-experiment"  # MLflow experiment name

O registro automático captura automaticamente os valores dos parâmetros de entrada e as métricas de saída de um modelo de aprendizado de máquina, à medida que esse modelo é treinado. Essas informações são então registradas em seu espaço de trabalho, onde as APIs MLflow ou o experimento correspondente em seu espaço de trabalho podem acessá-las e visualizá-las.

Quando concluído, seu experimento se assemelha a esta imagem:

Screenshot that shows the experiment page for the bank churn experiment.

Todos os experimentos com seus respetivos nomes são registrados, e você pode acompanhar seus parâmetros e métricas de desempenho. Para saber mais sobre o registro automático, consulte Registro automático no Microsoft Fabric.

Definir especificações de experimento e registro automático

mlflow.set_experiment(EXPERIMENT_NAME) # Use a date stamp to append to the experiment
mlflow.autolog(exclusive=False)

Importe scikit-learn e LightGBM

# Import the required libraries for model training
from sklearn.model_selection import train_test_split
from lightgbm import LGBMClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score, precision_score, confusion_matrix, recall_score, roc_auc_score, classification_report

Preparar conjuntos de dados de treinamento e teste

y = df_clean["Exited"]
X = df_clean.drop("Exited",axis=1)
# Train/test separation
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=SEED)

Aplicar SMOTE aos dados de treinamento

A classificação desequilibrada tem um problema, porque tem poucos exemplos da classe minoritária para que um modelo aprenda efetivamente o limite da decisão. Para lidar com isso, a Synthetic Minority Oversampling Technique (SMOTE) é a técnica mais utilizada para sintetizar novas amostras para a classe minoritária. Aceda ao SMOTE com a imblearn biblioteca que instalou no passo 1.

Aplique o SMOTE somente ao conjunto de dados de treinamento. Você deve deixar o conjunto de dados de teste em sua distribuição original desequilibrada para obter uma aproximação válida do desempenho do modelo nos dados originais. Esta experiência representa a situação na produção.

from collections import Counter
from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=SEED)
X_res, y_res = sm.fit_resample(X_train, y_train)
new_train = pd.concat([X_res, y_res], axis=1)

Para obter mais informações, consulte SMOTE e From random over-sampling to SMOTE and ADASYN. O site de aprendizagem desequilibrada hospeda esses recursos.

Preparar o modelo

Use Random Forest para treinar o modelo, com uma profundidade máxima de quatro e com quatro características:

mlflow.sklearn.autolog(registered_model_name='rfc1_sm')  # Register the trained model with autologging
rfc1_sm = RandomForestClassifier(max_depth=4, max_features=4, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc1_sm") as run:
    rfc1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc1_sm_run_id, run.info.status))
    # rfc1.fit(X_train,y_train) # Imbalanced training data
    rfc1_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc1_sm.score(X_test, y_test)
    y_pred = rfc1_sm.predict(X_test)
    cr_rfc1_sm = classification_report(y_test, y_pred)
    cm_rfc1_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc1_sm = roc_auc_score(y_res, rfc1_sm.predict_proba(X_res)[:, 1])

Use Random Forest para treinar o modelo, com uma profundidade máxima de oito e com seis recursos:

mlflow.sklearn.autolog(registered_model_name='rfc2_sm')  # Register the trained model with autologging
rfc2_sm = RandomForestClassifier(max_depth=8, max_features=6, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc2_sm") as run:
    rfc2_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc2_sm_run_id, run.info.status))
    # rfc2.fit(X_train,y_train) # Imbalanced training data
    rfc2_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc2_sm.score(X_test, y_test)
    y_pred = rfc2_sm.predict(X_test)
    cr_rfc2_sm = classification_report(y_test, y_pred)
    cm_rfc2_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc2_sm = roc_auc_score(y_res, rfc2_sm.predict_proba(X_res)[:, 1])

Treine o modelo com LightGBM:

# lgbm_model
mlflow.lightgbm.autolog(registered_model_name='lgbm_sm')  # Register the trained model with autologging
lgbm_sm_model = LGBMClassifier(learning_rate = 0.07, 
                        max_delta_step = 2, 
                        n_estimators = 100,
                        max_depth = 10, 
                        eval_metric = "logloss", 
                        objective='binary', 
                        random_state=42)

with mlflow.start_run(run_name="lgbm_sm") as run:
    lgbm1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    # lgbm_sm_model.fit(X_train,y_train) # Imbalanced training data
    lgbm_sm_model.fit(X_res, y_res.ravel()) # Balanced training data
    y_pred = lgbm_sm_model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    cr_lgbm_sm = classification_report(y_test, y_pred)
    cm_lgbm_sm = confusion_matrix(y_test, y_pred)
    roc_auc_lgbm_sm = roc_auc_score(y_res, lgbm_sm_model.predict_proba(X_res)[:, 1])

Exibir o artefato do experimento para acompanhar o desempenho do modelo

As execuções do experimento são salvas automaticamente no artefato do experimento. Você pode encontrar esse artefato no espaço de trabalho. Um nome de artefato é baseado no nome usado para definir o experimento. Todos os modelos treinados, suas execuções, métricas de desempenho e parâmetros do modelo são registrados na página do experimento.

Para ver as suas experiências:

  1. No painel esquerdo, selecione seu espaço de trabalho.
  2. Encontre e selecione o nome do experimento, neste caso, sample-bank-churn-experiment.

Screenshot that shows logged values for one of the models.

Etapa 5: Avaliar e salvar o modelo final de aprendizado de máquina

Abra o experimento salvo no espaço de trabalho para selecionar e salvar o melhor modelo:

# Define run_uri to fetch the model
# MLflow client: mlflow.model.url, list model
load_model_rfc1_sm = mlflow.sklearn.load_model(f"runs:/{rfc1_sm_run_id}/model")
load_model_rfc2_sm = mlflow.sklearn.load_model(f"runs:/{rfc2_sm_run_id}/model")
load_model_lgbm1_sm = mlflow.lightgbm.load_model(f"runs:/{lgbm1_sm_run_id}/model")

Avaliar o desempenho dos modelos salvos no conjunto de dados de teste

ypred_rfc1_sm = load_model_rfc1_sm.predict(X_test) # Random forest with maximum depth of 4 and 4 features
ypred_rfc2_sm = load_model_rfc2_sm.predict(X_test) # Random forest with maximum depth of 8 and 6 features
ypred_lgbm1_sm = load_model_lgbm1_sm.predict(X_test) # LightGBM

Mostrar verdadeiros/falsos positivos/negativos usando uma matriz de confusão

Para avaliar a precisão da classificação, construa um script que plote a matriz de confusão. Você também pode plotar uma matriz de confusão usando as ferramentas SynapseML, conforme mostrado no exemplo de Deteção de Fraude.

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    print(cm)
    plt.figure(figsize=(4,4))
    plt.rcParams.update({'font.size': 10})
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45, color="blue")
    plt.yticks(tick_marks, classes, color="blue")

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="red" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

Crie uma matriz de confusão para o classificador de floresta aleatório, com uma profundidade máxima de quatro, com quatro características:

cfm = confusion_matrix(y_test, y_pred=ypred_rfc1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 4')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of four.

Crie uma matriz de confusão para o classificador de floresta aleatório com profundidade máxima de oito, com seis características:

cfm = confusion_matrix(y_test, y_pred=ypred_rfc2_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 8')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of eight.

Crie uma matriz de confusão para o LightGBM:

cfm = confusion_matrix(y_test, y_pred=ypred_lgbm1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='LightGBM')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for LightGBM.

Guardar resultados para o Power BI

Salve o quadro delta na casa do lago para mover os resultados da previsão do modelo para uma visualização do Power BI.

df_pred = X_test.copy()
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=spark.createDataFrame(df_pred)
sparkDF.write.mode("overwrite").format("delta").option("overwriteSchema", "true").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Etapa 6: Acessar visualizações no Power BI

Aceda à tabela guardada no Power BI:

  1. À esquerda, selecione Hub de dados OneLake
  2. Selecione a casa do lago que você adicionou a este bloco de anotações
  3. Na seção Abrir este Lakehouse, selecione Abrir
  4. Na faixa de opções, selecione Novo modelo semântico. Selecione df_pred_resultse, em seguida, selecione Continuar para criar um novo modelo semântico do Power BI vinculado às previsões
  5. Selecione Novo relatório nas ferramentas na parte superior da página de modelos semânticos para abrir a página de criação de relatórios do Power BI

A captura de tela a seguir mostra alguns exemplos de visualizações. O painel de dados mostra as tabelas e colunas delta a serem selecionadas em uma tabela. Após a seleção dos eixos de categoria (x) e valor (y) apropriados, você pode escolher os filtros e funções - por exemplo, soma ou média da coluna da tabela.

Nota

Nesta captura de tela, o exemplo ilustrado descreve a análise dos resultados de previsão salvos no Power BI:

Screenshot that shows a Power BI dashboard example.

No entanto, para um caso de uso real de rotatividade de clientes, o usuário pode precisar de um conjunto mais completo de requisitos das visualizações para criar, com base na experiência no assunto e no que a empresa e a equipe de análise de negócios padronizaram como métricas.

O relatório do Power BI mostra que os clientes que usam mais de dois produtos bancários têm uma taxa de rotatividade mais alta. No entanto, poucos clientes tinham mais de dois produtos. (Veja o gráfico no painel inferior esquerdo.) O banco deve coletar mais dados, mas também deve investigar outras características que se correlacionam com mais produtos.

Os clientes bancários na Alemanha têm uma taxa de churn mais elevada em comparação com os clientes em França e Espanha. (Veja o gráfico no painel inferior direito). Com base nos resultados do relatório, uma investigação sobre os fatores que incentivaram os clientes a sair pode ajudar.

Há mais clientes de meia-idade (entre os 25 e os 45 anos). Clientes entre 45 e 60 anos tendem a sair mais.

Por fim, clientes com pontuações de crédito mais baixas provavelmente deixariam o banco para outras instituições financeiras. O banco deve explorar formas de incentivar os clientes com pontuações de crédito e saldos de contas mais baixos a permanecerem no banco.

# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")