Alura > Cursos de Data Science > Cursos de Machine Learning > Conteúdos de Machine Learning > Primeiras aulas do curso Classificação: otimizando modelos de machine learning

Classificação: otimizando modelos de machine learning

Construindo os modelos iniciais - Apresentação

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.

O que vamos aprender?

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.

Pré-requisitos

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!

Construindo os modelos iniciais - Conhecendo os dados

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.

Conhecendo os dados

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_clienteanuidade_emprestimoanos_casa_propriatelefone_trabavaliacao_cidadescore_1score_2score_3score_socialtroca_telefoneinadimplente
016855.2463242997.00000012.15732402.00.5012130.0031090.5131710.117428243.01
113500.0000002776.05000012.15732402.00.5012130.2697300.5131710.097900617.00
211250.0000002722.18835112.15732403.00.7013960.5186250.7001840.1186009.00
327000.0000006750.0000003.00000002.00.5012130.6495710.5131710.047400300.00
422500.0000003097.80000012.15732402.00.4407440.5096770.5131710.0144002913.01

Temos o nosso conjunto de dados, com algumas colunas:

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):

#ColumnNon-Null CountDtype
0receita_cliente14578float64
1anuidade_emprestimo14578float64
2anos_casa_propria14578float64
3telefone_trab14578int64
4avaliacao_cidade14578float64
5score_114578float64
6score_214578float64
7score_314578float64
8score_social14578float64
9troca_telefone14578float64
10inadimplente14578int64

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()

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)

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.

Separando o conjunto de dados

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.

Construindo os modelos iniciais - Treinando o DecisionTreeClassifier

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).

Treinando a árvore de decisão

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.

Avaliando o modelo

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 o y_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.

Sobre o curso Classificação: otimizando modelos de machine learning

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:

Aprenda Machine Learning acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas