Tutorial: criar, avaliar e pontuar um modelo de previsão de rotatividade
Este tutorial apresenta um exemplo de ponta a ponta de um fluxo de trabalho da Ciência de Dados do Synapse no Microsoft Fabric. O cenário cria um modelo para prever a rotatividade ou não dos clientes do banco. A taxa de rotatividade, ou a taxa de desgaste, envolve a taxa na qual os clientes de bancos encerram seus negócios com o banco.
Este tutorial cobre estas etapas:
- Instalar bibliotecas personalizadas
- Carregar os dados
- Compreender e processar os dados por meio da análise exploratória de dados e mostrar o uso do recurso Fabric Data Wrangler
- Usar o scikit-learn e o LightGBM para treinar modelos de machine learning e acompanhar os experimentos com os recursos de Log Automático do Fabric e MLflow
- Avaliar e salvar o modelo de machine learning final
- 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 de Ciência de Dados do Synapse.
- Se necessário, crie um lakehouse do Microsoft Fabric como está descrito em Criar um lakehouse no Microsoft Fabric.
Acompanhar em um notebook
Você pode escolher uma dessas opções para acompanhar em um notebook:
- Abra e execute o Notebook interno na experiência de Ciência de Dados
- Carregue seu Notebook do GitHub para a experiência de Ciência de Dados
Abrir o Notebook interno
O Notebook de exemplo Rotatividade de clientes acompanha este tutorial.
Para abrir o Notebook de amostra interno do tutorial na experiência de Ciência de Dados do Synapse:
Vá para a página inicial de Synapse Data Science.
Selecione Usar um exemplo.
Selecione o exemplo correspondente:
- Na guia padrão fluxos de trabalho de ponta a ponta (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 do R.
- Na guia Tutoriais rápidos, se o exemplo for para um tutorial rápido.
Anexe um lakehouse ao notebook antes de começar a executar o código.
Importar o Notebook do GitHub
O notebook AIsample - Bank Customer Churn.ipynb acompanha este tutorial.
Para abrir o notebook que acompanha este tutorial, siga as instruções em Preparar seu sistema para ciência de dados para importar os notebooks do tutorial para seu espaço de trabalho.
Se preferir copiar e colar o código a partir dessa página, você poderá criar um novo notebook.
Certifique-se de anexar um lakehouse ao notebook antes de começar a executar o código.
Etapa 1: Instalar bibliotecas personalizadas
Para o desenvolvimento de modelo de machine learning 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.
- Usar os recursos de instalação embutido (
%pip
ou%conda
) do notebook para instalar a biblioteca somente no notebook atual. - Como alternativa, você pode criar um ambiente de Fabric, 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 notebooks e definições de trabalho do Spark no espaço de trabalho. Para obter mais informações sobre ambientes, confira Criar, configurar e usar um ambiente no Microsoft Fabric.
Para este tutorial, use %pip install
para instalar a biblioteca imblearn
no notebook.
Observação
O kernel do PySpark é reiniciado após executar %pip install
. Instale as bibliotecas necessárias antes de executar quaisquer outras células.
# Use pip to install libraries
%pip install imblearn
Etapa 2: Carregar os dados
O conjunto de dados em churn.csv contém o status de rotatividade de 10.000 clientes, junto com 14 atributos que incluem:
- Pontuação de crédito
- Localização geográfica (Alemanha, França, Espanha)
- Gênero (masculino, feminino)
- Idade
- Posse (número de anos em que a pessoa foi cliente naquele banco)
- Saldo da conta
- Salário estimado
- Número de produtos que um cliente comprou por meio do banco
- Status do cartão de crédito (se um cliente tem ou não um cartão de crédito)
- Status de membro ativo (se é um cliente ativo ou não do banco)
O conjunto de dados também inclui colunas de número de linha, ID do cliente e sobrenome do cliente. Os valores nessas colunas não devem influenciar na decisão do cliente de deixar o banco.
O fechamento da conta bancária do cliente é o evento que define a rotatividade daquele cliente. O conjunto de dados da coluna Exited
refere-se ao abandono do cliente. Como temos pouco contexto sobre esses atributos, não precisamos de informações de histórico sobre o conjunto de dados. Queremos entender como esses atributos contribuem para o status Exited
.
Destes 10.000 clientes, apenas 2.037 clientes (aproximadamente 20%) deixaram o banco. Por causa da 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 a classificação desequilibrada. Podemos querer medir a precisão usando a Área sob a Curva de Recordação de Precisão (AUPRC).
- Esta tabela mostra uma amostra de visualização dos dados
churn.csv
:
CustomerID | Sobrenome | CreditScore | Geografia | Gender | Age | Posse | Saldo | NumOfProducts | HasCrCard | IsActiveMember | EstimatedSalary | Demitido |
---|---|---|---|---|---|---|---|---|---|---|---|---|
15634602 | Hargrave | 619 | França | Feminino | 42 | 2 | 0,00 | 1 | 1 | 1 | 101348.88 | 1 |
15647311 | Colina | 608 | Espanha | Feminino | 41 | 1 | 83807.86 | 1 | 0 | 1 | 112542.58 | 0 |
Baixar o conjunto de dados e carregar no lakehouse
Defina estes parâmetros, para que você possa usar este Notebook 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 faz o download de uma versão disponível publicamente do conjunto de dados e, em seguida, armazena esse conjunto de dados em um lakehouse do Fabric:
Importante
Adicione um lakehouse ao notebook antes de você executá-lo. Se você não fizer isso, receberá 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()
Ler dados brutos do lakehouse
Esse código lê os dados brutos da seção Arquivos do lakehouse e adiciona mais colunas para diferentes partes da data. A criação da tabela delta particionada usa essa informação.
df = (
spark.read.option("header", True)
.option("inferSchema", True)
.csv("Files/churn/raw/churn.csv")
.cache()
)
Criar um DataFrame do pandas com base no conjunto de dados
Esse código converte o DataFrame do Spark em DataFrame do pandas para facilitar o processamento e a visualização:
df = df.toPandas()
Etapa 3: Executar análise exploratória de dados
Exibir dados brutos
Explore os dados brutos com display
, calcule algumas estatísticas básicas e mostre exibições de gráficos. Você deve primeiro importar as bibliotecas necessárias para visualização de dados, como por exemplo, seaborn. Seaborn é uma biblioteca de visualização de dados do Python que fornece uma interface de alto nível para criar visuais em dataframes e matrizes.
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 Estruturador de Dados para executar a limpeza inicial de dados
Inicialize o Data Wrangler diretamente do notebook para explorar e transformar dataframes do pandas. Na guia Dados da faixa de opções do notebook, use a solicitação suspensa do Data Wrangler para procurar os DataFrames do Pandas ativados disponíveis para edição. Selecione o DataFrame que você deseja abrir no Data Wrangler.
Observação
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.
Depois de iniciar o Data Wrangler, 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, valores ausentes, etc. Você pode utilizar o Data Wrangler para gerar o script para remover 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 célula seguinte mostra o script copiado.
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 os atributos
Esse código determina os atributos categorizados, 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
- média
- 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])
Mostrar a distribuição dos clientes que saíram e dos que não saíram
Mostrar a distribuição dos clientes que saíram e dos que não saíram de acordo com os atributos categorizados:
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)
Mostrar a distribuição de atributos numéricos
Usar um histograma para mostrar a distribuição da frequência de 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()
Executar a 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 a codificação one-hot
Com as mesmas etapas para iniciar o Data Wrangler, como discutido anteriormente, utilize o Data Wrangler para executar a codificação one-hot. Essa célula mostra o script gerado copiado para a codificação one-hot:
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 de dados
- A maioria dos clientes são da França. A Espanha tem a menor taxa de rotatividade comparado com a França e a Alemanha.
- A maioria dos clientes tem cartões de crédito
- Alguns clientes têm mais de 60 anos e contagem de crédito abaixo de 400. No entanto, eles não podem ser considerados como exceção
- Pouquíssimos clientes têm mais de dois produtos do banco
- Clientes inativos têm uma taxa de rotatividade mais alta
- O gênero e os anos de posse tem pouco impacto sobre a decisão do cliente de encerrar uma conta bancária
Etapa 4: realizar o treinamento e acompanhamento do modelo
Com os dados no lugar, agora você pode definir o modelo. Aplique os modelos de floresta aleatória e LightGBM no seu notebook.
Use as bibliotecas scikit-learn e LightGBM para implementar os modelos com algumas linhas de código. Além disso, use o MLfLow e o Registro de Log Automático do Fabric para rastrear os experimentos.
Este exemplo de código carrega a tabela delta do lakehouse. Você pode utilizar outras tabelas Delta que elas mesma usam o lakehouse como origem.
SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()
Gerar um experimento para rastrear e registrar em log os modelos utilizando o MLflow
Esta seção mostra como gerar um experimento e especifica o modelo e os parâmetros de treinamento e as métricas de pontuação. Além disso, ele 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 log automático captura automaticamente os valores de parâmetros de entrada e métricas de saída de um modelo de machine learning enquanto o modelo é treinado. Essa informação é então registrada em log no seu espaço de trabalho, onde as APIs do MLflow ou o experimento correspondente no seu espaço de trabalho podem ser acessados e visualizados.
Quando concluído, seu experimento ficará parecido com esta imagem:
Todos os experimentos com seus respectivos nomes são registrados em log e você poderá acompanhar seus parâmetros e métricas de desempenho. Para obter mais informações 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)
Importar o scikit-learn e o 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 o SMOTE aos dados de treinamento
A classificação desequilibrada possui um problema, pois há poucos exemplos da classe minoritária para que um modelo aprenda efetivamente o limite de decisão. Para lidar com isso, a Técnica de Sobreamostragem de Minorias Sintéticas (SMOTE) é a abordagem mais amplamente utilizada para sintetizar novas amostras para a classe minoritária. Acesse o SMOTE utilizando a biblioteca imblearn
que você instalou na Etapa 1.
Aplique o SMOTE somente ao conjunto de dados de treinamento. Você deve deixar o conjunto de dados de teste em sua distribuição desequilibrada original para obter uma aproximação válida de desempenho de modelo nos dados originais. Este experimento 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 De amostragem excessiva aleatória a SMOTE e ADASYN. O site de aprendizagem desequilibrada hospeda esses recursos.
Treinar o modelo
Use Floresta Aleatória para treinar o modelo com uma profundidade máxima de quatro, com quatro recursos:
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 a Floresta Aleatória para treinar o modelo com uma profundidade máxima de oito, 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 o 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])
Visualizar o artefato de experimentos 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 exibir seus experimentos:
- No painel esquerdo, selecione seu espaço de trabalho.
- Encontre e selecione o nome do experimento, neste caso, sample-bank-churn-experiment.
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")
Avalie 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 a matriz de confusão
Para avaliar a precisão da classificação, desenvolva um script para plotar a matriz de confusão. Você também pode plotar uma matriz de confusão utilizando as ferramentas do SynapseML, como é mostrada na amostra de Detecçã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ória com a profundidade máxima de quatro, com quatro recursos:
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()
Crie uma matriz de confusão para o classificador de floresta aleatória com profundidade máxima de oito, com seis recursos:
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()
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()
Salvar os resultados do Power BI
Salve o quadro de diferença no lakehouse para mover os resultados da previsão do modelo para a 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
Acesse sua tabela salva no Power BI:
- À esquerda, selecione Hub de dados do OneLake
- Selecione o lakehouse que você precisa adicionar a este notebook
- Na seção Abrir esta Lakehouse, selecione Abrir
- Na faixa, selecione Novo modelo semântico. Selecionar
df_pred_results
, depois selecione Continuar para criar um novo modelo semântico do Power BI vinculado às previsões - Selecionar Novo relatório nas ferramentas na parte superior da página do modelo semântico para abrir a página de criação de relatório 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 para selecionar de uma tabela. Depois de selecionar as categorias (x) valores (y) de eixos apropriados, você pode selecionar, por exemplo, a soma ou a média da coluna da tabela.
Observação
Nesta captura de tela, o exemplo ilustrado descreve a análise dos resultados de previsão salvos no Power BI:
Entretanto, para um caso de uso real de rotatividade de clientes, o usuário pode ter que fazer um conjunto de requisitos mais completo das visualizações a serem criadas, com base em sua 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 de banco têm uma taxa de rotatividade maior. 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 investigar outros recursos correlacionados com mais produtos.
Os clientes de bancos na Alemanha têm uma taxa de rotatividade mais elevada em comparação com os clientes na 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 25 e 45 anos). Clientes entre 45 e 60 anos tendem a sair mais.
Por fim, os clientes com pontuações de crédito mais baixas provavelmente deixariam o banco e iriam para outras instituições financeiras. O banco deve explorar maneiras de incentivar os clientes com pontuações de crédito e saldos de conta mais baixos a permanecerem no banco.
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")