Como utilizar Pandas Profiling e PyCaret para prever preços de custo de seguro de vida

Raffaela Loffredo
13 min readSep 12, 2023

--

Click here to read this article in English.

Nesse artigo trago o passo a passo que eu fiz na construção de um modelo de regressão para prever o custo do seguro de vida com o auxílio das bibliotecas Pandas Profiling e PyCaret.

Sumário

  1. Seguro de Vida
  2. Objetivo Geral
    2.1. Objetivos Específicos
  3. Obtenção dos Dados
  4. Dicionário de Variáveis
  5. Importação dos Dados e das Bibliotecas
  6. Análise Exploratória dos Dados
    6.1. Por que utilizar Pandas Profiling?
    6.2. Gerar Relatório
  7. Tratamento dos Dados
  8. Criação dos modelos de Machine Learning
    8.1. Por que utilizar PyCaret?
    8.2. Configuração
    8.3. Criação e comparação de modelos
    8.4. Ajuste do modelo
    8.5. Visualizações
    8.6. Realizar previsões
    8.7. Finalizar o modelo
  9. Avaliação no conjunto de testes
  10. Conclusão

1. Seguro de Vida

O seguro de vida é uma garantia financeiras dada aos beneficiários, que geralmente são familiares, em caso de doença grave, invalidez ou morte do segurado, também conhecido como titular do seguro.

Esse tipo de seguro é feito, assim como outros, por meio de um contrato com uma seguradora. E, por ser um contrato, há diferentes tipos de seguro de vida, com diferentes períodos de validade, quantidade de titulares, entre outras características que, a depender da seguradora, podem ser personalizados.

O funcionamento desse seguro se dá por meio de pagamentos, geralmente de forma mensal (mas podem ter outras formas como semestral ou mesmo um pagamento único), pelo segurado e, no caso de ocorrer um sinistro, isto é, alguma das situações previstas no seguro, a seguradora é acionada e paga a indenização aos beneficiários previstos no contrato.

Por isso, o seguro de vida costuma ser um instrumento utilizado como planejamento financeiro, de forma que garanta uma segurança aos familiares do titular.

O valor a ser pago por esse tipo de contrato é variável e deve ser levado em consideração fatores como: o prazo de cobertura do seguro, quantidade de pessoas que irão receber o benefício, tipos de cobertura (doença grave, incapacidade temporária, invalidez, morte), histórico familiar de enfermidades, profissão do titular (pois existem profissões consideradas mais arriscadas como policial e bombeiros, por exemplo), entre outros fatores.

Para resolver esse problema para as empresas de seguro, é possível criar um modelo de machine-learning que faça uso de um algoritmo de regressão para prever qual o valor deverá ser cobrado do titular.

2. Objetivo Geral

Desenvolver um algoritmo capaz de prever o custo do seguro de saúde com o uso de machine-learning.

2.1. Objetivos Específicos

  • Realizar uma análise exploratória nos dados para conhecer o data set e verificar presença de anormalidades que necessitem de tratamentos adequados.
  • Criar modelos de machine learning com diversos tipos de aprendizado de máquina.
  • Avaliar modelos para encontrar o que tem o melhor desempenho.

3. Obtenção dos Dados

Os dados utilizados nesse projeto foram disponibilizados no Kaggle. O arquivo foi salvo em nuvem, e encontra-se nesse link para o caso de ficar indisponível futuramente.

4. Dicionário de Variáveis

A compreensão do conjunto de dados passa pela checagem das variáveis disponíveis nele para que se possa realizar uma boa análise. Segue-se um resumo dos atributos encontrados e seus respectivos significados.

em ordem alfabética

age: idade
bmi: índice de massa corporal (IMC)
charges: valor a ser cobrado (em dólares)
children: filhos
sex: gênero (feminino/masculino)
region: região (sudeste/sudoeste/noroeste/nordeste)
smoker: fumante (sim/não)

5. Importação dos Dados e das Bibliotecas

Ao iniciar um projeto é necessário instalar pacotes, importar as bibliotecas que possuem funções específicas a serem utilizadas nas linhas de código seguintes e realizar as configurações necessárias para a saída do código. Também, se prossegue com a importação do dataset, salvando-o em uma variável específica para que seja usada posteriormente.

# instalar pacote adicional
!pip install pycaret -q # auto machine-learning
!pip install pandas_profiling -q # produção de relatório de análise exploratória
# importar as bibliotecas necessárias
import pandas as pd # manipulação de dados
from pandas_profiling import ProfileReport # produção de relatório de análise exploratória
from pycaret.regression import * # criação de modelos de regressão
# importar os dados e atribuir em uma variável
data_path = 'https://www.dropbox.com/scl/fi/c36wjctk07hu5rqxuqbzb/insurance.csv?rlkey=b5td662pyx3jcrnf4f8lkhlf9&dl=1'
df_raw = pd.read_csv(data_path)

6. Análise Exploratória dos Dados

Essa é uma etapa essencial em projetos de ciência de dados onde se busca compreender melhor os dados seja por identificar padrões, outliers, possíveis relações entre as variáveis, etc. Nesse estudo, se exploraram informações que fossem relevantes para orientar as respostas dos objetivos indicados anteriormente (ver Objetivo Geral e Objetivos Específicos).

Para isso vou gerar um relatório que resume os dados, com o uso da biblioteca ProfileReport. A partir dele, se houver necessidade, será feito uma análise mais profunda. Contudo, ele já nos fornecerá informações suficientes para identificar anomalias como outliers e desbalanceamento nos dados.

6.1. Por que utilizar Pandas Profiling?

A biblioteca Pandas Profiling oferece a função ProfileReport que cria automaticamente um relatório completo de análise exploratória de dados. Ele inclui as seguintes informações:

  • Visão Geral
    Com a quantidade de registros e atributos do dataset, bem como valores ausentes e duplicados.
  • Estatística Descritiva
    Para cada variável irá calcular: média, mediana, valor máximo e mínimo, desvio padrão, quartis, entre outros dados estatísticos.
  • Distribuição
    Para as variáveis numéricas, ele irá criar gráficos como histogramas, boxplot, densidade, para que seja visualmente fácil compreender a distribuição dos dados.
  • Frequência
    Para os atributos numéricos será feita a identificação dos principais valores únicos, e suas respectivas contagens.
  • Correlação
    É gerada uma matriz de correlação para verificação do relacionamento entre as variáveis.

Por isso, o uso do ProfileReport agiliza a rotina da análise exploratória dos dados, contudo, não exime o cientista de dados de realizar o estudo aprofundado do relatório para compreender e interpretar os dados, além de identificar eventuais problemas que necessitam de tratamento.

6.2. Gerar relatório

# criar relatório
report = ProfileReport(df_raw)

# visualizar relatório
report.to_notebook_iframe()

No relatório gerado na saída do código acima, percebe-se que:

  • o conjunto é formado por 1338 registros e 7 atributos
  • pelas primeiras e últimas entradas do dataset ele parece estar bem preenchido e sem anormalidades
  • não há dados ausentes
  • existe uma linha duplicada
  • a idade tem uma alta correlação com o preço cobrado pelo seguro, o que faz bastante sentido
  • bem como, é apontada a alta correlação entre a pessoa ser fumante, acabar pagando mais caro no seguro

Foi observado que as variáveis age e children estão em formato float o que não haveria necessidade e poderiam ser convertidos em tipo inteiro para economizar memória computacional, contudo, como é um conjunto relativamente pequeno, essa alteração não terá tantos efeitos.

As variáveis age e smoker estão desbalanceadas, uma vez que, na primeira há um pico maior na faixa dos 20 anos, enquanto que na segunda, há uma quantidade maior de pessoas não-fumantes do que de pessoas que fumam.

Já as variáveis sex, region, children e bmi estão bem balanceadas, sendo que em bmi identifica-se, inclusive, uma distribuição normal.

Dessa forma, o único tratamento necessário será a identificação e exclusão dos registros duplicado.

7. Tratamento dos Dados

Nessa sessão, irei prosseguir com 2 etapas de tratamento de dados:

  • tratar dados duplicados
  • preparar dados para machine learning

Conforme visto na etapa anterior, existe a presença de dados duplicados nesse dataset. Portanto, nessa sessão vou prosseguir com a identificação e remoção desse dado.

# identificar e visualizar registros duplicados
duplicatas = df_raw.duplicated()
print(df_raw[duplicatas])

Pode-se reparar que a linha mostrada acima, está de acordo com o que foi mostrado no documento. Vamos prosseguir com a exclusão desse registro.

# remover linhas duplicadas
df_clean = df_raw.drop_duplicates()

Por fim, a etapa essencial em qualquer projeto de machine learning envolver a preparação dos dados com a separação dos mesmos em 2 conjuntos distintos: um conjunto de treino e outro de testes para que o de treino seja utilizado no treinamento do algoritmo e o de testes seja usado apenas ao final desse estudo, como forma de compreender os acertos e erros do modelo criado.

Será feito na proporção de 90% para treino e 10% para testes. Bem como, vou aproveitar para resetar o index dos conjuntos para que não haja nenhuma possibilidade de identificação e relação entre os dados e, visualizar o tamanho que ficaram os conjuntos.

# separar os dados em teste e treino
## criar variável 'test' com 10% do data frame original
## com seed para gerar resultados reproduzíveis
## resetar index
test = df_clean.sample(frac=0.10, random_state=82).reset_index(drop=True)

## criar variável 'train' com tudo o que não estiver em 'test'
## resetar index
train = df_clean.drop(test.index).reset_index(drop=True)

# checar tamanho dos conjuntos
print(train.shape)
print(test.shape)
'''
(1203, 7)
(134, 7)
'''

8. Criação dos modelos de Machine Learning

A construção de um projeto completo de regressão com a utilização da biblioteca PyCaret demanda 6 etapas:

  1. configuração
  2. criação e comparação de algoritmos
  3. ajuste do modelo
  4. visualização
  5. realizar previsões
  6. finalizar modelo

Na etapa posterior usaremos o conjunto de testes separado acima para avaliação do modelo criado.

8.1. Por que utilizar PyCaret?

PyCaret é uma biblioteca de uso simplificado que auxiliam o processo de construção de modelos de machine-learning por meio de funções automatizadas de etapas comuns ao desenvolvimento desses modelos. Isso faz dela uma ferramenta extremamente útil para rapidamente construir modelos de aprendizado de máquina.

Vale ressaltar que ferramentas de auto machine-learning como essa não substitui o trabalha do cientista de dados. A utilização dela deve ser feita com o intuito de dar suporte e agilidade ao processo da construção de modelos.

8.2. Configuração

A primeira etapa consiste em passar os parâmetros necessários para configurar os dados do nosso problema de regressão.

Para isso, informamos qual é o conjunto de dados que deverá ser utilizado, ou seja, df_clean; precisamos apontar qual é o atributo alvo, isto é, aquele que queremos que seja previsto pelo algoritmo; também passei uma divisão de 75% para o conjunto de treino, o que faz com que o conjunto de testes fique com os 25% restantes; coloquei True para o parâmetro normalize para que os dados sejam normalizados (pelo padrão da biblioteca que usa o ZScore); e, por fim, passei um valor inteiro para que os resultados possam ser reproduzidos novamente em qualquer ambiente.

# 1. configurar regressão
reg = setup(data=train, # conjunto de dados
target='charges', # classe alvo
train_size=0.75, # definir tamanho da divisão dos conjuntos
normalize=True, # normalizar os dados em uma única escala (zscore)
session_id=38) # seed para gerar resultados reproduzíveis

8.3. Criação e comparação de modelos

Aqui, serão criados e treinados todos os modelos disponíveis na biblioteca do PyCaret, e então, avaliados com validação cruzada estratificada (por padrão 10 dobras). Ademais, os resultados, por padrão, são ranqueados de acordo com o valor obtido com a métrica do Coeficiente de Determinação — R2 (mas isso poderia ser alterado se houvesse necessidade). Vou manter essa configuração, pois essa será a métrica utilizada também na próxima etapa.

Veremos abaixo as seguintes métricas de avaliação:

  • Mean Absolute Error (MAE)
    média das somas do valor absoluto da magnitude dos erros
  • Mean Squared Error (MSE)
    média das somas do valor da magnitude dos erros, elevada ao quadrado
  • Root Mean Squared Error (RMSE)
    raiz quadrada do MSE
  • Coefficient of Determination (R2)
    variância em relação à média e à reta
  • Root Mean Squared Log Error (RMSLE)
    diferença entre os logaritmos dos valores reais e previstos
  • Mean Absolute Percentage Error (MAPE)
    é a porcentagem equivalente ao MAE
# 2. criar e comparar modelos
best = compare_models()

Acima, foram criados e testados 19 modelos diferentes. Sendo que, os que apresentaram os melhores resultados foram o Gradient Boosting Regressor e o Passive Aggressive Regressor.

Podemos confirmar o melhor algoritmo criado com o código abaixo:

# imprimir o melhor modelo
print(best)
'''
GradientBoostingRegressor(random_state=38)
'''

Portanto, vamos dar continuidade utilizando o Gradient Boosting Regressor.

Esse é um algoritmo de machine-learning, da família de métodos Ensemble de Árvores de Decisão, que aprende com erros e, por isso, melhora a cada iteração. Ele é usado para regressões e, por conta disso, se adaptou muito bem ao nosso problema em questão.

Em essência, ele possui 3 elementos:

  • loss function: para ser otimizada
  • weak learner: para fazer previsões
  • modelo aditivo para adicionar aos weak learners para minimizar a loss function
# instanciar modelo
gbr = create_model('gbr')

Note que as médias das métricas mostradas acima são as mesmas para o modelo criado na lista de todos os algoritmos. Isso porque o modelo é criado e avaliado da mesma forma que foi feito anteriormente.

8.4. Ajuste do modelo

O modelo será otimizado pela métrica R2 e, como já é o padrão da função tune_model não há necessidade de especificá-la.

Relembrando que R2 ou R² é o Coeficiente de Determinação é uma forma de medir a acurácia do modelo, contudo não trata dos erros em sim, mas das variâncias em relação à média e à reta. Dessa forma, ele mede como o modelo se encaixa nos dados.

Seus resultados variam entre 0 e 1.0, sendo que quanto mais próximo de 1.0 melhor é o resultado.

Sua fórmula é dada por:

# ajuste dos parâmetros
tuned_gbr = tune_model(gbr)

Com o ajuste de parâmetros não tivemos nenhuma melhora no resultado do R2: saímos de 0.8430 para 0.8427. Portando, ele volta ao estado original do melhor resultado.

8.5. Visualizações

Nessa sessão vou gerar diferentes gráficos para visualizar e auxiliar a compreensão do modelo criado.

Primeiro, vamos ao gráfico de Previsão de Erro, para avaliar o desempenho do modelo em relação à previsão do custo do seguro de vida. Com ele podemos checar os erros do modelo.

plot_model(tuned_gbr, plot='error')

Vamos checar também quais atributos são mais relevantes para o modelo gerado com o gráfico abaixo.

plot_model(tuned_gbr, plot='feature')

A seguir, no gráfico de Resíduos, pode-se avaliar os resíduos do modelo quanto à previsão do modelo. O resíduo é a diferença entre os valores reais e os valores previstos pelo modelo. Portanto, com esse gráfico consegue-se avaliar a qualidade do modelo que criamos.

plot_model(tuned_gbr, plot='residuals')

Por fim, o gráfico de Curva de Aprendizado. Com ele podemos checar o desempenho do modelo à medida que o conjunto de treinamento aumenta. Ou seja, pode-se entender o comportamento do modelo com diferentes quantidades de dados, o que pode levar à reflexões quanto à necessidade de mais dados ou mesmo da complexidade do modelo.

plot_model(tuned_gbr, plot='learning')

Podemos observar acima, que as linhas tendem a convergir para um valor razoavelmente estável, próximo de 0.91 e 0.84.

Vale imprimir ainda, um modelo interativo geral de avaliação, disponível com a função evaluate_model o qual fornece diversas informações sobre o modelo construído. Por exemplo: a estrutura do pipeline do modelo e os hiperparâmetros finais utilizados.

evaluate_model(tuned_gbr)

8.6. Realizar previsões

Antes de finalizar o modelo, fazemos uma verificação no qual realizamos uma previsão, com o conjunto de testes separado pela função setup na primeira etapa de criação do modelo. Dessa forma, checamos se não há divergências nos resultados apresentados.

# fazer previsões
predict_model(tuned_gbr);

Observe que o resultado de 0.8246 encontra-se dentro do desvio padrão previsto na etapa 2, de 0.0870.

8.7. Finalizar o modelo

Na última etapa do processo de criação do modelo, finalizamos ele com a função finalize_model que irá treinar o modelo com o conjunto completo que foi informado na função setup. Ou seja, ele irá incluir o conjunto que havia sido separado para os testes.

# finalizar modelo
final_gbr = finalize_model(tuned_gbr)

Podemos imprimir o modelo final, para checar os parâmetros utilizados no modelo.

# verificar parâmetros
print(final_gbr)

9. Avaliação no conjunto de testes

Para concluir esse estudo, utilizamos o conjunto de testes separado na sessão de Tratamento de Dados para que possamos avaliar o modelo com dados que ele nunca teve contato anteriormente.

# previsão em dados não vistos
prediction = predict_model(final_gbr, data=test)
prediction.head()

Observa-se que ele obteve um R2 maior do que o valor obtido nos testes, de 0.8430 para 0.9166 e, dentro do desvio padrão previsto de 0.0870

Além disso, temos um novo atributo denominado prediction_label no qual podemos ver a previsão do modelo para o custo do seguro de vida.

10. Conclusão

O estudo teve por objetivo central o desenvolvimento um algoritmo capaz de prever o custo do seguro de saúde com o uso de machine-learning.

Com o uso da biblioteca Pandas Profiling foi possível obter em poucos segundos um panorama do conjunto de dados, com a geração de um relatório completo, que auxiliou na análise exploratória.

Após o devido tratamento dos dados, com a ajuda da biblioteca PyCaret, foram gerados 19 modelos de regressão, que foram avaliados por diversas métricas. Contudo, optou-se por ordenar os resultados pelo Coeficiente de Determinação — R2. Com isso, se chegou ao melhor modelo criado pelo algoritmo Gradient Boosting Regressor com o R2 igual a 0.8430.

Na sequência foi feito o ajuste de hiperparâmetros do modelo, ao qual não foi possível obter uma melhora do modelo. E, na etapa seguinte, de realizar testes com os dados do PyCaret o modelo ficou dentro do esperado. Já nos testes finais, onde se utilizaram novos dados, o Coeficiente de Determinação apresentou uma melhora significativa, saltando para 0.9166 e dentro dos limites de desvio padrão previstos.

Saiba Mais

Esse estudo encontra-se disponível nas plataformas Google Colab e GitHub. Basta clicar nos links das imagens abaixo para ser redirecionado.

[LoffredoDS] Previsão de custo de Seguro de Vida.ipynb
raffaloffredo/life_insurance_price_prediction_portuguese

--

--

Raffaela Loffredo

💡 Transforming data into impactful solutions | Co-founder @BellumGalaxy | Data Scientist | Blockchain Data Analyst