Olá, sou Bruno Raphaell e vou te acompanhar neste curso de otimização de hiperparâmetros.
Audiodescrição: Bruno se identifica como um homem de pele negra. Tem olhos castanhos, cabelos cacheados e barba curta. Está utilizando um óculos de armação arredondada e uma camiseta na cor preta. Ao fundo, estante e armário iluminados por um tom rosa.
Neste curso, vamos explorar diversas técnicas de otimização de hiperparâmetros de modelos de Machine Learning, utilizadas para classificar clientes inadimplentes em uma empresa de empréstimo de automóveis.
Nesse projeto, vamos utilizar essas técnicas para melhorar nossos modelos a partir da alteração de seus hiperparâmetros e analisar os resultados obtidos.
Importante ressaltar que não vamos nos preocupar com a etapa de preparação dos dados, pois este não será o nosso foco do curso.
O ideal é que você já tenha conhecimento de como preparar os dados para inseri-los em um modelo de Machine Learning.
Nosso foco será conhecer e utilizar as diferentes técnicas para otimização de hiperparâmetros.
Para o melhor aproveitamento do curso, é ideal que você possua conhecimento na linguagem de programação Python e também conceitos de Machine Learning.
Vamos aprender como podemos melhorar nossos modelos de Machine Learning?
Nos encontramos no próximo vídeo. Até mais!
Vamos dar início ao nosso trabalho. Utilizaremos diversas técnicas para classificar clientes inadimplentes em uma loja de automóveis.
Mas antes, o que seria inadimplente? Inadimplente é quando uma pessoa deixa de pagar suas dívidas. No nosso caso, a pessoa realizou o empréstimo e não pagou. Nosso objetivo é buscar técnicas que melhorem os modelos desenvolvidos para essa atividade.
Antes de mais nada, precisamos conhecer o nosso objeto de trabalho. Quando trabalhamos com ciência de dados, machine learning e inteligência artificial, o nosso objeto de trabalho são os dados.
Vamos conhecer os dados que utilizaremos para realizar todo esse processo.
Primeiro, devemos importar os dados para o Google Colab. Na aba lateral esquerda, vamos clicar em "Arquivo" cujo ícone é uma pasta e clicar em "Fazer upload para o armazenamento da sessão".
Você procura o arquivo dados_inadimplencia (formato CSV, tamanho 1.526 KB), que você precisa ter baixado de acordo com a atividade "Preparando o ambiente". Realizamos o upload para o ambiente de trabalho e esperamos ser importado.
Após o upload finalizar, precisamos realizar a leitura para que possamos manipular esse dado no ambiente. Para isso, vamos importar a biblioteca Pandas, que é a biblioteca que utilizaremos.
Em uma célula de código, escrevemos import pandas as pd
, que é o "apelido" que daremos. E apertamos "Shift + Enter" para executar e criar uma nova célula.
import pandas as pd
Na nova célula criada, fazemos a leitura. Para isso, referenciamos a biblioteca, pd
, e o método .read_csv()
. Entre parênteses e aspas, passamos o dado.
Para não errar o nome do dado, podemos copiar e colar caminho do arquivo, o dados_inadimplencia.csv
.
Queremos colocar o conjunto em uma variável para manipular os dados no nosso ambiente de trabalho. Por isso, temos que atribuir essa linha a uma variável que chamaremos de dados
.
Na próxima linha colocamos dados.head()
, para visualizar somente as 5 primeiras linhas do dataframe.
dados = pd.read_csv('dados_inadimplencia.csv')
dados.head()
Novamente, executamos a célula com "Shift + Enter". Foi retornado o nosso conjunto de dados, já no formato tabular.
# | receita_cliente | anuidade_emprestimo | anos_casa_propria | telefone_trab | avaliacao_cidade | score_1 | score_2 | score_3 | score_social | troca_telefone | inadimplente |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 16855.246324 | 2997.000000 | 12.157324 | 0 | 2.0 | 0.501213 | 0.003109 | 0.513171 | 0.117428 | 243.0 | 1 |
1 | 13500.000000 | 2776.050000 | 12.157324 | 0 | 2.0 | 0.501213 | 0.269730 | 0.513171 | 0.097900 | 617.0 | 0 |
2 | 11250.000000 | 2722.188351 | 12.157324 | 0 | 3.0 | 0.701396 | 0.518625 | 0.700184 | 0.118600 | 9.0 | 0 |
3 | 27000.000000 | 6750.000000 | 3.000000 | 0 | 2.0 | 0.501213 | 0.649571 | 0.513171 | 0.047400 | 300.0 | 0 |
4 | 22500.000000 | 3097.800000 | 12.157324 | 0 | 2.0 | 0.440744 | 0.509677 | 0.513171 | 0.014400 | 2913.0 | 1 |
Temos o nosso conjunto de dados, com algumas colunas:
receita_cliente
: quanto essa pessoa cliente ganha em reais;anuidade _empréstimo
: o valor do empréstimo que deve ser pago anualmente em reais;anos_casa_propria
: tempo da propriedade da clientela em anos;telefone_trab
: se possui telefone de trabalho ou não;avaliacao_cidade
: avaliação da cidade em que a pessoa mora, indicando se ela é boa, ruim, muito boa, de acordo com um determinado número;troca_telefone
: quanto tempo faz que essa pessoa trocou de telefone antes de pegar o empréstimo;inadimplente
: de acordo com suas características, se esse cliente é inadimplente ou não.O dicionário deses dados estará disponível na atividade, para você conferir com detalhes o que significa cada uma dessas colunas.
Agora, temos que verificar algumas informações iniciais do conjunto de dados, e para isso, o Pandas já fornece um método chamado info()
:
dados.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14578 entries, 0 to 14577
Data columns (total 11 columns):
# | Column | Non-Null Count | Dtype |
---|---|---|---|
0 | receita_cliente | 14578 | float64 |
1 | anuidade_emprestimo | 14578 | float64 |
2 | anos_casa_propria | 14578 | float64 |
3 | telefone_trab | 14578 | int64 |
4 | avaliacao_cidade | 14578 | float64 |
5 | score_1 | 14578 | float64 |
6 | score_2 | 14578 | float64 |
7 | score_3 | 14578 | float64 |
8 | score_social | 14578 | float64 |
9 | troca_telefone | 14578 | float64 |
10 | inadimplente | 14578 | int64 |
dtypes: float64(9), int64(2)
memory usage: 1.2 MB
Esse método retorna alguns dados. Vamos interpretá-los? Ele retorna o RangeIndex
que informa o quanto o nosso índice está variando, ou seja, temos 14578 entradas que variam de 0 a 14577. Isso significa que não tem índice saltado.
Também retorna o total de colunas, que no caso é 11. Além disso, retorna o nome dessas colunas e a quantidade de valores não nulos, algo que devemos nos atender.
Nesse dataframe, todas as colunas têm 14578 amostras não-nulas. O que interpretamos? Que não há valor nulo no nosso conjunto de dados, justamente porque é o total de entradas. Está exatamente como queríamos.
Por fim, temos a coluna Dtype
, que retorna o tipo da coluna. Como estamos trabalhando somente com valores numéricos, só teremos valores numéricos int
e float
, está de acordo com o que precisamos e queremos.
Agora vamos verificar outra informação muito importante quando trabalhamos com algoritmos de machine learning, que é justamente a distribuição das nossas classes, que é, no caso, a inadimplência.
Para fazer isso, referenciamos a coluna dados['inadimplente']
e usamos o método value_counts()
para fazer a contagem de valores.
round(dados['inadimplente'].value_counts()
- 0 9862
- 1 4716
Se executamos dessa forma, ele já retorna que existem 9862 do valor 0 e 4716 do valor 1. Mas desta forma fica difícil de visualizar a proporção.
Como queremos visualizar a proporção, colocamos o parâmetro normalize
igual a True
, isso faz com que ele retorne em relação à porcentagem. Fora dos parênteses de value_counts()
, multiplicamos por 100 para verificar na porcentagem correta.
Por fim, arredondamos todo o valor para 2
casas decimais, usando o método round()
.
round(dados['inadimplente'].value_counts(normalize=True)*100, 2)
- 0 67.65
- 1 32.35
Então, temos 67.65% de valores 0 e 32.35% de valores 1, ou seja, existe uma diferença de proporção. Essa proporção não é tão desproporcional no nosso conjunto de dados, mas ele tem uma certa proporção que devemos nos atentar.
Conferimos que a proporção não é tão grande, e verificamos também que o nosso conjunto de dados não possui valores nulos e que o tipo de dados está correto.
O que temos que fazer agora é separar o nosso conjunto de dados em x
e y
, variáveis explicativas e a nossa variável target.
Para isso, chamamos uma variável de x
, em uma próxima linha de código. Definiremos que x
é igual a dados.drop()
, passando a coluna inadimplente
e axis
igual a 1
. Ou seja, ele vai nos retornar o dataframe sem a coluna inadimplente
.
E quem será a y
? O y
será igual a dados['inadimplente']
.
x = dados.drop('inadimplente', axis =1)
y = dados['inadimplente']
Se executamos dessa forma, temos o nosso conjunto de dados separado. No caso, a y
é somente a coluna inadimplente, e a x
são todas as variáveis explicativas.
Agora temos que separar em treino e teste. Para isso, vamos importar o método train_test_split
desde sklearn.model_selection
.
Depois, definimos RANDOM_STATE
igual à 42
, que é a nossa semente, para garantir que os resultados que obtivermos sejam os mesmos resultados que você está obtendo.
Na próxima linha, de fato separamos em treino e teste. Para isso, colocamos x_treino, x_teste, y_treino, y_teste
igual ao train_test_split()
, passando as variáveis x
e y
.
Além disso, colocamos o test_size
como 0.33
, mas também é possível colocar outro valor. Nesse caso, 33% dessas amostras vão ser para teste e o restante será para treino.
Depois, colocamos o parâmetro random_state
a variável RANDOM_STATE
que acabamos de criar com a nossa semente. E por fim, definimos stratify
igual a y
.
Esse stratify
garante a proporção de classes sejam mantidas tanto em treino quanto em teste. Já que o nosso conjunto de dados não é perfeitamente balanceado, é importante inserir esse parâmetro.
from sklearn.model_selection import train_test_split
RANDOM_STATE = 42
x_treino, x_teste, y_treino, y_teste = train_test_split(x, y, test_size=0.33, random_state=RANDOM_STATE, stratify=y)
Após executar, o nosso conjunto de dados foi separado em treino e teste e podemos prosseguir para a próxima etapa.
No nosso próximo passo, vamos criar esses modelos que devem ser otimizados. Faremos isso no próximo vídeo.
Já verificamos nossos dados, asseguramos que eles não possuem inconsistências e estão prontos para serem inseridos em modelos de machine learning.
Mas quais serão esses modelos que vamos criar para serem otimizados? Vamos criar dois: o DecisionTreeClassifier
e o LogisticRegression
(ou regressão logística).
No Google Colab, vamos criar uma nova célula de código, clicando no canto superior esquerdo em "+ Código" (ou "Ctrl + M + B").
Primeiramente, vamos importar e instanciar estes algoritmos. O primeiro que vamos criar será o DecisionTreeClassifier
.
Confira a documentação do Scikit Learn sobre Decision Tree Classifier para conhecer sobre suas propriedades e exemplos de código.
Em uma nova célula, vamos inserir from sklearn.tree import DecisionTreeClassifier
e executar com o "Shift + Enter".
from sklearn.tree import DecisionTreeClassifier
Pronto, já temos no nosso ambiente o nosso DecisionTreeClassifier
e agora temos que criar o nosso modelo.
Para isso, vamos criar a variável modelo_dt
que vai ser igual ao DecisionTreeClassifier()
.
Entre os parênteses, vamos passar um parâmetro chamado max_depth
que será igual a 3
.
Esse parâmetro vai controlar a profundidade da árvore. Se deixarmos ele como padrão, que é none, pode acontecer de ter um overfit no nosso modelo. E vamos entender isso mais adiante.
Outro parâmetro que vamos inserir é o random_state
, que será definido de acordo com a variável RANDOM_STATE
definida anteriormente.
Agora, como fazemos o ajuste do modelo? Colocamos modelo_dt.fit()
e passamos os dados de treino. No caso, x_treino
e y_treino
.
modelo_dt = DecisionTreeClassifier(max_depth=3, random_state=RANDOM_STATE)
modelo_dt.fit(x_treino, y_treino)
O nosso modelo já foi instanciado, criado e ajustado.
Mas devemos avaliar esse modelo, pois queremos melhorá-lo ainda mais.
Existem diversas métricas que podemos utilizar para avaliar um modelo de classificação. Mas temos que analisar o contexto.
Não podemos, por exemplo, apenas utilizar a acurácia para avaliar esse modelo.
Nesse caso, queremos identificar as pessoas que são inadimplentes corretamente e minimizar a não-previsão da inadimplência quando de fato ela ocorre.
Em outras palavras, se não estamos prevendo inadimplência de um cliente que vai ser inadimplente, isso tem um custo muito grande para a empresa.
Quando queremos identificar corretamente os casos positivos, usamos a métrica recall (revocação). Por isso, vamos utilizá-la para avaliar os nossos modelos de classificação.
Como avaliamos o nosso modelo de acordo com o recall no Google Colab?
Faremos from sklearn.metrics
para importar uma métrica da biblioteca Scikit-Learn. Nesse caso, vamos fazer um import recall_score
.
Se deixarmos o nosso mouse em cima da métrica de recall_score
, aparece um trecho da documentação que ensina como utilizá-la.
Temos que passar o y_true
e o y_pred
nessa ordem.
O
y_true
são as respostas verdadeiras que temos, enquanto oy_pred
é o que o modelo está prevendo.
Em uma nova linha, criamos a variável recall_dt
que será igual à recall_score()
.
Primeiro, devemos passar o y_true
que, no nosso caso, é o y_teste
.
Depois, devemos passar o y_pred
que é modelo_dt.predict()
para prever de acordo com x_teste
.
Agora queremos deixar essa impressão mais organizada. Por isso, vamos fazer o print()
de uma f-string.
Entre aspas, definimos o texto Recall do DT =
e adicionamos a variável recall_dt
entre colchetes para imprimir seu valor. Como queremos imprimi-la com três casas decimais, vamos adicionar dois-pontos seguido de .3f
.
from sklearn.metrics import recall_score
recall_dt = recall_score(y_teste, modelo_dt.predict(x_teste))
print(f"Recall do DT = {recall_dt:.3f}")
Recall do DT = 0.143
Executando essa célula com "Shift + Enter", temos que o recall do DecisionTreeClassifier
é 0.143.
Com isso, concluímos o nosso primeiro algoritmo que deve ser otimizado.
O curso Classificação: otimizando modelos de machine learning possui 112 minutos de vídeos, em um total de 50 atividades. Gostou? Conheça nossos outros cursos de Machine Learning em Data Science, ou leia nossos artigos de Data Science.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.