Implementação de Classificador de Espécies Iris via scikit-learn e Flask

Arquitetura e Fluxo de Implementação

A construção de um sistema de classificação supervisionada requer a orquestração de três camadas: aquisição e particionamento dos dados, treinamento do modelo estatístico e exposição da inferência via serviço web. O conjunto de dados Iris, nativo da biblioteca scikit-learn, disponibiliza 150 instâncias distribuídas em três categorias taxonômicas, cada uma caracterizada por quatro atributos métricos (comprimento e largura de sépala e pétala).

Preparação dos Dados e Treinamento do Modelo

A extração das variáveis independentes (atributos) e do vetor alvo (etiquetas) precede a divisão estratificada da base. Utilizando uma proporção de 70% para ajuste e 30% para validação, aplica-se o algoritmo de Floresta Aleatória. Esta escolha técnica justifica-se pela sua capacidade de lidar com interações não linearres sem exigir normalização prévia dos atributos e pela baixa suscetibilidade a ruídos nos dados.

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import joblib

base_iris = load_iris()
X, y = base_iris.data, base_iris.target

X_treinamento, X_teste, y_treinamento, y_teste = train_test_split(
    X, y, test_size=0.30, random_state=89
)

arvore_aleatoria = RandomForestClassifier(
    n_estimators=150, max_depth=4, min_samples_split=2, random_state=42
)
arvore_aleatoria.fit(X_treinamento, y_treinamento)

predicoes_val = arvore_aleatoria.predict(X_teste)
indice_acerto = accuracy_score(y_teste, predicoes_val)

joblib.dump(arvore_aleatoria, 'classificador_iris.bin')
print(f"Precisão obtida no conjunto de teste: {indice_acerto:.2%}")

Integração com Interface Web

A camada de apresentação é construída sobre o microframework Flask. Uma rota principal recebe requisições POST, valida os valores numéricos inseridos pelo usuário, converte-os em um arranjo multidimensional compatível com a API do scikit-learn e invoca o método de predição. O índice retornado é traduzido para a nomenclatura botânica correspondente através de um dicionário de mapeamento estático, garantindo baixa sobrecarga de memória.

from flask import Flask, request, render_template_string
import numpy as np
import joblib

aplicacao = Flask(__name__)
modelo_serializado = joblib.load('classificador_iris.bin')

DICIONARIO_ESPECIES = {
    0: 'Iris-setosa',
    1: 'Iris-versicolor',
    2: 'Iris-virginica'
}

TEMPLATE_FORM = """


<title>Predição Iris</title>

  <h2>Análise Morfométrica</h2>
  <form method="POST">
    Comprimento Sépala: <input name="s_len" required="" step="0.1" type="number"></input><br></br><br></br>
    Largura Sépala: <input name="s_wid" required="" step="0.1" type="number"></input><br></br><br></br>
    Comprimento Pétala: <input name="p_len" required="" step="0.1" type="number"></input><br></br><br></br>
    Largura Pétala: <input name="p_wid" required="" step="0.1" type="number"></input><br></br><br></br>
    <button type="submit">Executar Classificação</button>
  </form>
  {% if resultado %}
    <h3>Resultado: {{ resultado }}</h3>
  {% endif %}


"""

@aplicacao.route('/classificar', methods=['GET', 'POST'])
def executar_inferencia():
    resultado_saida = None
    if request.method == 'POST':
        try:
            s_l = float(request.form['s_len'])
            s_w = float(request.form['s_wid'])
            p_l = float(request.form['p_len'])
            p_w = float(request.form['p_wid'])
            
            vetor_entrada = np.array([[s_l, s_w, p_l, p_w]])
            classe_predita = modelo_serializado.predict(vetor_entrada)[0]
            resultado_saida = DICIONARIO_ESPECIES[classe_predita]
        except (ValueError, KeyError, TypeError):
            resultado_saida = 'Entrada inválida. Verifique os parâmetros numéricos.'
            
    return render_template_string(TEMPLATE_FORM, resultado=resultado_saida)

if __name__ == '__main__':
    aplicacao.run(host='0.0.0.0', port=8080, debug=False)

Diretrizes de Produção e Expansão

A serialização via joblib garante que o carregamento do modelo em tempo de execução seja eficiente, evitando o custo computacional do ajuste durante cada ciclo de requisição. Para algoritmos sensíveis à escala (como SVM ou Redes Neurais Artificiais), a inserção de um pipeline contendo StandardScaler é mandatória antes da etapa de inferência. A validação rigorosa dos limites superiores e inferiores das medidas no formulário previne a propagação de outliers para o modelo treinado.

A evolução da solução contempla a adição de módulos de visualização dinâmica para análise de distribuição de clusters, a implementação de testes A/B comparando métricas de precisão e recall entre múltiplos classificadores, e a refatoração do endpoint para um padrão RESTful com autenticação por tokens, permitindo a integração com ecossistemas de terceiros.

Tags: scikit-learn Flask RandomForestClassifier DatasetIris SerializacaoJoblib

Publicado em 9-22 08:07