Analista de Machine Learning IGTI — Entendendo o trabalho prático do módulo 3

Ricardo Guerra
Ensinando Máquinas
8 min readOct 21, 2020
Photo by Maksym Kaharlytskyi on Unsplash

Neste trabalho, vamos exercitar conceitos sobre medidas de desempenho vistas em aula, a partir da modelagem de 3 problemas diferentes. Para o problema de regressão, usaremos a base diabetes_numeric.csv e uma regressão linear. Para o problema de classificação, usaremos a base bloodtransf.csv e um SVM. Para o problema de clusterização vamos utilizar a base wine.csv e o algoritmo kmeans.

Todo o material utilizado neste post se encontra aqui.

Neste trabalho iremos utilizar basicamente o pandas e o módulo python scikit-learn. As perguntas consistem em uma análise descritiva dos dados e aplicação simples de alguns modelos de ML. Vamos lá!

Atributos são as features ou variáveis do nosso dataset, e se resumem a quantidade de colunas de dados que temos. A questão é simples. Podemos utilizar o comando .head() do pandas para saber quantas variáveis temos ou entãoa o .shape, que nos retornará (instancias,atributos).

Mesmo caso da questão anterior, só que dessa vez eles querem saber quantas instâncias nos temos na base. Um simples .shape vai nos retornar a quantidade de atributos dos nossos dados de classificação.

Aqui nessa questão temos uma pegadinha… quando verificamos o shape desse dataset, a resposta que obtemos é (178, 14), ou seja, 178 instâncias e 14 atributos, mas essa opção não existe.

A pegadinha é que na letra A e letra D temos “classes”. Este dataset foi trazido para realização de clusterização com o algorítimo K-Means, isso foi dito no inicio. Ocorre que o K-Means é um método não-supervisionado de machine learning, ou seja, ele funciona sem que os dados necessitem estar etiquetados.

Ao utilizar o .head() ou .columns, veremos que existe um atributo de nome class, que provavelmente ja é uma etiquetagem da correta classificação e cada instância em seu determinado grupo. Provavelmente irá servir para comparar se nosso modelo agrupou corretamente os dados.

OK, mas e como saber agora quantas classes eu tenho? saio rolando linha por linha e contando? Não, temos um método no pandas chamado unique() que retorna os itens únicos em um atributo e naturalmente no python temos um método que realiza a contagem de quantos itens temos em uma lista, array, etc… que é o len assim, poderemos formar o seguinte comando: len(df[‘class’].unique()) e ele nos retornará a quantidade de itens únicos nessa classe. Testem utilizar só o unique() para ver!

Essa é uma questão relativamente fácil. Ao utilizar o método .info() nos datasets, ele retornará um sumário que diz quantas instancias de dados temos e se temos algum dado nulo (a coluna Non-Null Count diz quantos não nulos temos).

Agora, para responder essa questão teremos que criar nosso modelo e aplicar a métrica para poder responder a questão.

Primeiramente, foi solicitado que realizemos a separação dos dados em treino e teste, com 25% dos dados separado para teste.

Em seguida, para criar nosso modelinho de regressão linear utilizando o sklearn, deveremos inicialmente importar o modulo, depois criar um objeto do modelo, treinar e finalmente realizar a predição.

Figure 1: Imports e criação do modelo de regressão linear

Não vou comentar sobre os imports, voces podem ler mais sobre no site do sklearn. Após isso separei nossos dados em treino e teste. Ali onde escrevi df1.iloc[:,0:2] significa que eu selecionei todas as linhas e depois da coluna 0 até a 2 e coloquei como variáveis de entrada (seria o X), e depois peguei apenas a coluna de indice de 2 a 3 (ou seja, a coluna de indice 3), que seria o meu y. Assim, separei os dados 75% para treino e 25% para teste.

Depois, criamos o objeto da nossa regressão linear (regr=LinearRegression())[perceba que importei ela lá em cima antes]. Realizei o .fit(X_train,y_train), ou seja, realizei o treinamento do meu modelo.

Por fim, realizei a predição (utilizando os dados de teste) em regr.predict(X_test) e coloquei em uma variável: diabetes_y_pred.

Agora podemos responder a questão, calculando o R² através do método metrics.r2_score(y_test, diabetes_y_pred) e encontraremos a resposta!

Agora que ja temos o modelo montado, é só chamar o método que calcula o MAE, ou seja metrics.mean_absolute_error(y_test, diabetes_y_pred). Observe que eu chamo ambos os y, o test (que é o original) e o y_pred (que é o que eu fiz a previsão) e comparo os dois utilizando o MAE.

Mesma coisa da questão anterior, agora usaremos o metrics.mean_squared_error(y_test, diabetes_y_pred). O MSE utiliza o quadrado do erro médio, penalizando erros maiores em relação ao MAE que usa a média do erro absoluto.

Galera, aqui a gente vai fazer a mesma coisa que fizemos para criar o modelo de regressão, porém o modelo a ser utilizado agora é o Suport Vector Machine.

O procedimento é exatamente igual pra criação do modelo, mudando apenas que agora é o SVM (Aparece SVC pq é o Classificador do SVM).

A métrica requerida na questão é a acurácia e encontramos ela dentro do sklearn como metrics.accuracy_score.

Estão vendo como é simples? Além disso o scikit-learn é muito completo e já tem quase todas as ferramentas!

Dentro do sklearn a gente tem o sklearn.metrics.recall_score e também o sklearn.metrics.precision_score, porém indico utilizar o sklearn.metrics.classification_report. Por que? Já explico!

Figura 2: Saída do classification_report

Em casos de classificação, teremos precision e recall para cada atributo de saída, neste caso temos dois atributos, o 1 e o 2, então, se utilizarmos apenas os métodos de precision e recall individualmente obteremos o resultado de algum dos atributos.

Com o classification_report a gente consegue obter o precision e recall para todos os atributos de saída, e nesse caso acho que o IGTI esperava que eu tivesse mapeado os atributos de saída para 0 e 1 e assim eu obteria o precision e recall do atributo de valor 2 (que seria o 1 depois do map). Como eu não fiz isso, se eu utilizasse apenas o método do precision e recall eu teria como resposta 0.75 e 1.00 respectivamente, e essas respostas não existem no gabarito! Mas com o classification_report logo eu enxergo.

De quebra, utilizando o classification_report eu já obtenho o f1_score e a resposta da questão 10, Uhu!

Mais uma questão de métrica, e para isso utilizamos o metrics.roc_auc_score(y_test, y_pred) e já iremos obter a resposta. O importante é você ter assistido todas as aulas e entender o que cada métrica significa, senão eu teria que escrever um post pra cada métrica pra poder explicar.

Para saber se ele é parecido ou não com um baseline aleatório, vou ensinar uma coisa: existe uma classe do sklearn chamada dummy, que deixa voce criar modelos “burros”, ou seja, o mais simples possível. Eu sempre uso o dummy pra comparar com meu modelo, e se tiver muito parecido, então temos um problema hahaha. Entrem no colab que disponibilizei e verifiquem como fiz isso.

Como o AUROC score do dummy e do nosso modelo ficaram muito próximos, podemos concluir que ele não está bom!

Gente, a questão é o seguinte: Daqui pra frente o negócio fica um pouco complicado. Por que? Porque na minha opinião não deram informações suficientes pra resolução do problema e ai foi meio que na adivinhação.

Lembra lá na pegadinha de uma das questões no inicio? Ela já trouxe os labels (etiquetas) do dataset, onde descobrimos que tem 3 classes. Por que agora estão perguntando qual o valor adequado de clusters? A gente já sabe que são 3 pois os dados originais são compostos de 3 classes…

Mesmo assim eu utilizei uma técnica bem conhecida, a técnica do cotovelo, onde um gráfico é gerado a soma dos quadrados dos erros para cada valor de K e no ponto do gráfico que parece o cotovelo vai ser indicado o “melhor valor de K” e o valor de 3 foi confirmado. Entrem lá no colab pra visualizarem isso.

Métricas e mais métricas… Agora é mais do que a gente já fez, cria o modelo do K-Means e depois aplica a métrica, conforme figura 3.

Figura 3: criação do modelo K-Means

Mais e mais métricas:

metrics.davies_bouldin_score(X_test, predictions1_labels)

Finalizando com mais uma métrica:

print('\nMutual information\n', round(metrics.mutual_info_score(y_test, predictions1_labels),2))

FIM! Terminamos! 😍😍

Escrevi esse post para ajudar as pessoas com dificuldade neste trabalho, tentando ser o mais didático possível. Caso ainda reste alguma dúvida, pode deixar um comentário ou me enviar um e-mail, terei o maior prazer em ajudar.

Aqui embaixo temos o notebook no colab para que vocês possam acompanhar o código que escrevi para responder as questões. Até mais!

--

--