Problemas de classificação representam uma ampla categoria de problemas de machine learning que envolvem a previsão de valores dentro de um conjunto finito e discreto de casos.

Neste exemplo, construiremos um classificador para prever a qual espécie uma flor pertence.

Leitura dos dados


In [ ]:
import pandas as pd

iris = # carregue o arquivo 'datasets/iris.csv'

In [ ]:
# Exiba informações sobre o dataset

In [ ]:
# Exiba as classes presentes nesse dataset usando o método unique() na coluna "Class"

In [ ]:
# Use o método describe() para exibir estatísticas sobre o dataset

Visualização dos dados


In [ ]:
# Criação de um scatterplot dos valores as colunas "Sepal_length" e "Sepal_width"
import matplotlib.pyplot as plt
%matplotlib inline

sl = iris['Sepal_length']
sw = iris['Sepal_width']

# Crie um scatterplot dessas duas propriedades usando a função plt.scatter()
# Atribua cores diferentes a cada exemplo do dataset de acordo com a classe à qual ele pertence

# Atribua labels aos eixos X e Y

# Exiba o gráfico

In [ ]:
# Criação de um scatterplot dos valores as colunas "Petal_length" e "Pepal_width"
pl = iris['Petal_length']
pw = iris['Petal_width']

# Crie um scatterplot dessas duas propriedades usando a função plt.scatter()
# Atribua cores diferentes a cada exemplo do dataset de acordo com a classe à qual ele pertence

# Atribua labels aos eixos X e Y

# Exiba o gráfico

Classificação de espécies

Usaremos a classe LogisticRegression do scikit-learn para construir o classificador.


In [ ]:
X = # Crie um DataFrame com todas as features através da remoção da coluna "Class"
t = # Pegue os valores da coluna "Class"
RANDOM_STATE = 4321

# Use o método train_test_plit() para dividir os dados em dois conjuntos
from sklearn.model_selection import train_test_split

Xtr, Xts, ytr, yts = train_test_split(X, t, random_state=RANDOM_STATE)

In [ ]:
# Use o conjunto de treinamento para construir um modelo LogisticRegression
from sklearn.linear_model import LogisticRegression

lr = # Crie um objeto LogisticRegression aqui
# Treine o modelo usando os dados do conjunto de treinamento

In [ ]:
# Use o método score() do objeto LogisticRegression para avaliar a acurácia do modelo

In [ ]:
# Use o método score() do objeto LogisticRegression para avaliar a acurácia
# do modelo no conjunto de teste

Inspeção dos resultados

Cálculos como o realizado acima geralmente não representam bem aquilo que queremos avaliar quando estamos resolvendo um problema de classificação. Ele apenas retorna o erro médio obtido entre as previsões e as classes reais do dataset de treinamento.

Pense, por exemplo, no que aconteceria se você estivesse treinando um modelo para classificar se uma pessoa possui ou não uma doença em um contexto onde sabe-se que, normalmente, 99% ads pessoas não têm essa doença. O que poderia dar errado se calculássemos a taxa de erros e acertos do modelo como uma forma de avaliá-lo? Dica: qual seria o valor dessa taxa de erros/acertos para um classificador "hardcoded" que sempre retorna 0 (isto é, ele sempre diz que a pessoa não tem a doença)?

Métricas simples de acurácia geralmente não são recomendadas para problemas de classificação. Existem pelo menos três métricas que costumam ser usadas dependendo do contexto:

  • Precisão: esse número responde à seguinte pergunta: dentre os exemplos que o classificador disse que pertencem a uma classe, quantos de fato pertencem a ela?
  • Recall: esse número responde a uma pergunta levemente diferente da mostrada na Precisão: dentre os exemplos que realmente pertencem a uma classe, quantos o classificador conseguiu identificar?
  • F1-Score: essa métrica representa uma soma ponderada de precisão e recall - ela não apresenta uma interpretação intuitiva, mas a ideia é que o f1-score representa um meio-termo entre precisão e recall.

Source: https://en.wikipedia.org/wiki/Precision_and_recall

Outras métodos de avaliação para mdodelos de classificação incluem análise de curva ROC e, relacionada a essa técnica, o conceito de área sob a curva ROC.

Qual dessas métricas você priorizaria para o exemplo do classificador de doença descrito no parágrafo anterior? Quais são os custos para falsos positivos e falsos negativos nesse caso?


In [ ]:
# scikit-learn implementa uma função chamada "classification_report" que calcula as três métricas acima
# para um dado classificador.
from sklearn.metrics import classification_report

# Use essa função para exibir as métricas de classificação no modelo treinado anteriormente
# http://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html

Outra técnica útil para inspecionar os resultados gerados por um modelo de classificação é a checagem da matriz de confusão. A matriz de confusão é uma matriz de dimensões K x K (onde K é o número de classes que o classificador pode identificar) que mostra, na posição (i,j), quantos exemplos pertencentes à classe i foram classificados como pertencentes à classe j.

Isso pode trazer insights a respeito de quais classes possuem a maior quantidade de classificações incorretas, por exemplo, e que portanto poderiam receber uma maior atenção por parte da pessoa cientista de dados.


In [ ]:
from sklearn.metrics import confusion_matrix

# Use a função confusion_matrix para entender quais classes estão sendo classificadas incorretamente
# http://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html

No exemplo acima, o que você investigaria mais a fundo? Quais classes o classificador tem mais dificuldade de identificar corretamente?