Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

[Projeto] Classificador de Espécies de Flores com Dataset Iris

Vamos implementar um classificador supervisionado completo usando o dataset Iris :

  1. Carregar e explorar os dados
    python
    import pandas as pd
    import numpy as np
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split, cross_val_score
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.metrics import accuracy_score, classification_report

Carregar dataset

iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target

print(df.head())
print(df['species'].value_counts())
2. Pré-processamento
python
X = df[iris.feature_names] # Atributos
y = df['species'] # Rótulos

Divisão treino/teste

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)

Normalização (essencial para KNN)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
3. Treinar modelo (KNN)
python
modelo = KNeighborsClassifier(n_neighbors=5)
modelo.fit(X_train_scaled, y_train)
4. Avaliar modelo
python
y_pred = modelo.predict(X_test_scaled)
acuracia = accuracy_score(y_test, y_pred)

print(f"Acurácia: {acuracia:.2%}")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

Validação cruzada

cv_scores = cross_val_score(modelo, X, y, cv=5)
print(f"Validação cruzada (5 folds): {cv_scores.mean():.2%}")
5. Testar nova flor
python
def classificar_flor(caracteristicas):
"""caracteristicas: [comp_sépala, larg_sépala, comp_pétala, larg_pétala]"""
nova_flor_scaled = scaler.transform([caracteristicas])
especie_id = modelo.predict(nova_flor_scaled)[0]
return iris.target_names[especie_id]

Exemplo

teste = [5.1, 3.5, 1.4, 0.2]
print(f"Flor {teste} → {classificar_flor(teste)}")
Saída esperada
text
Acurácia: 97.78%
Validação cruzada (5 folds): 96.67%
Flor [5.1, 3.5, 1.4, 0.2] → setosa
Resumo do fluxo
Etapa Ação
1 Carregar dataset Iris
2 Separar atributos (X) e rótulos (y)
3 Dividir em treino (70%) e teste (30%)
4 Normalizar dados (StandardScaler)
5 Treinar KNN com k=5
6 Avaliar com acurácia e validação cruzada

1 resposta

Olá, Marcus. Como vai?

Excelente contribuição! O dataset Iris é o "Hello World" perfeito para entender o aprendizado de máquina supervisionado, e o seu guia passo a passo ficou extremamente limpo, didático e pronto para execução.

Você teve um cuidado técnico fantástico que muitos iniciantes esquecem: a normalização dos dados (StandardScaler). Como o KNN calcula a distância Euclidiana entre os pontos para definir a classe de uma nova amostra, atributos com escalas muito maiores dominariam o cálculo se não fossem normalizados. Outro ponto excelente foi usar apenas o transform (e não fit_transform) nos dados de teste, evitando o vazamento de dados (data leakage).

Como boa prática e complemento para o seu projeto, vale levantar uma pequena observação técnica sobre a linha onde você executou a validação cruzada:

cv_scores = cross_val_score(modelo, X, y, cv=5)

Ao passar os dados X puros (sem escala) para o cross_val_score, o KNN roda as dobras da validação cruzada sem a normalização. No dataset Iris o impacto é pequeno porque os dados originais já possuem escalas próximas, mas em datasets reais isso pode distorcer a avaliação do modelo.

Para garantir que o processamento seja aplicado corretamente em cada uma das 5 dobras da validação cruzada (garantindo que o treino de cada dobra seja normalizado e o teste apenas transformado), a melhor prática no ecossistema do Scikit-Learn é utilizar um Pipeline.

Veja como o seu código pode ser otimizado para automatizar esse fluxo:

from sklearn.pipeline import Pipeline

# Criamos um pipeline que encadeia a normalização e o modelo escolhido
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('knn', KNeighborsClassifier(n_neighbors=5))
])

# Treinando o pipeline completo (ele faz o fit_transform no treino de forma automática)
pipeline.fit(X_train, y_train)

# Na validação cruzada, passamos o pipeline e os dados X originais. 
# O Scikit-Learn garante que a normalização ocorra isoladamente em cada dobra!
cv_scores = cross_val_score(pipeline, X, y, cv=5)
print(f"Validação cruzada com Pipeline (5 folds): {cv_scores.mean():.2%}")

O uso do Pipeline deixa o código de produção muito mais seguro, robusto e fácil de ler, além de simplificar a função classificar_flor, que poderia apenas chamar pipeline.predict([caracteristicas]) diretamente, dispensando a necessidade de chamar o scaler manualmente.

Seu tutorial está excelente e serve como um ótimo roteiro de estudos para a comunidade. Parabéns pelo projeto estruturado com tanto capricho!

Espero que possa ter lhe ajudado!