Pular para o conteúdo
</>RoByte

Buscar cursos e aulas

Aulas do curso

Vídeo em breve

Por enquanto, esta aula está disponível só em texto — o vídeo entra assim que ficar pronto.

Modelos clássicos

Classificação: KNN e árvores de decisão

Dois classificadores intuitivos, como treiná-los com scikit-learn e como comparar os resultados. · 18 min

Na classificação, o target é uma categoria: qual espécie de flor, se é spam ou não, qual dígito. Vamos ver dois algoritmos muito intuitivos e usar o dataset da íris, com 150 flores de 3 espécies e 4 medidas cada.

Preparando os dados

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)

X_treino, X_teste, y_treino, y_teste = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

O parâmetro stratify=y garante que as três espécies apareçam nas mesmas proporções no treino e no teste. Isso é importante em classificação, para que o teste não fique sem exemplos de alguma classe.

KNN: os vizinhos mais próximos

A ideia do K-Nearest Neighbors é simples: para classificar uma amostra nova, olhe as k amostras mais parecidas do treino e adote a classe que mais aparece entre elas. “Mais parecidas” significa mais próximas no espaço das features.

from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_treino, y_treino)

print(knn.score(X_teste, y_teste))   # acurácia: fração de acertos

Aqui o score é a acurácia, a proporção de previsões corretas. Na íris o resultado costuma ficar acima de 90%.

Dica

O k é um hiperparâmetro: um ajuste que você escolhe antes do treino. Com k muito pequeno o modelo fica sensível a ruído, e com k muito grande ele fica “genérico” demais. Testar vários valores é parte do trabalho.

Atenção

O KNN mede distâncias, então features em escalas muito diferentes atrapalham (uma medida em milhares vai dominar outra em unidades). Na íris todas as medidas têm escala parecida, mas em dados reais é comum precisar padronizar. Vamos ver isso na aula de pipelines.

Árvore de decisão

Uma árvore de decisão aprende uma sequência de perguntas de sim ou não sobre as features, como “a largura da pétala é menor que 0,8?”. Cada resposta leva a um ramo, até chegar a uma classe.

from sklearn.tree import DecisionTreeClassifier

arvore = DecisionTreeClassifier(max_depth=3, random_state=42)
arvore.fit(X_treino, y_treino)

print(arvore.score(X_teste, y_teste))
print(arvore.feature_importances_)   # quanto cada feature pesou nas decisões

max_depth limita a profundidade da árvore, ou seja, o número máximo de perguntas em sequência. Sem esse limite, a árvore pode crescer até decorar o treino inteiro (o problema do overfitting, que vamos estudar em detalhe mais à frente).

A grande vantagem das árvores é a interpretabilidade: dá para ler as regras que o modelo aprendeu. Já o KNN não aprende regras, só guarda os dados e compara na hora de prever.

Comparando

Como todos os modelos do scikit-learn têm a mesma interface (fit, predict, score), trocar de algoritmo é trocar uma linha. Você pode comparar vários num laço:

for k in [1, 3, 5, 7, 9, 11]:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_treino, y_treino)
    print(k, knn.score(X_teste, y_teste))

Exercícios

Exercício

1. Aquecimento. Rode o laço acima e descubra qual valor de k deu a melhor acurácia no teste. O resultado muda se você trocar o random_state do train_test_split?

Exercício

2. Profundidade. Treine árvores com max_depth de 1 a 8 e imprima a acurácia de cada uma no teste. A partir de que profundidade o ganho para de valer a pena?

Exercício

3. Desafio. Repita a comparação entre KNN e árvore usando o dataset load_breast_cancer (diagnóstico de tumores, com 30 features). Qual modelo se saiu melhor? Imprima também as 3 features mais importantes da árvore (dica: np.argsort(arvore.feature_importances_)[-3:]).