PDI+VC · Exercício de Programação

EP07_06 — 🟣 Pipeline Completo: Descritores + k-NN + Avaliação Multi-Classe

7.18.6 EP07_06 🟣 Pipeline Completo: Descritores + k-NN + Avaliação Multi-Classe

Este exercício integra as três etapas centrais do capítulo em um único pipeline, reproduzindo em miniatura o Projeto Prático 2 (classificação de texturas sintéticas por LBP): um conjunto de histogramas de descritores já extraídos (como se fossem histogramas LBP) é utilizado para treinar um classificador k-NN, que por sua vez é avaliado sobre um conjunto de teste independente por meio de uma matriz de confusão multi-classe.

Diferentemente do EP07_01, aqui o espaço de características tem dimensão arbitrária \(H\) (o tamanho do histograma), existem mais de duas classes, e a métrica de distância é um parâmetro de entrada — permitindo reproduzir o experimento de comparação de métricas discutido no capítulo.

7.18.6.1 📋 Diretrizes de Implementação

  1. Classes: Ler o inteiro \(C\) (número de classes) seguido de \(C\) nomes de classe (strings sem espaço), na ordem em que devem aparecer na matriz de confusão.
  2. Configuração: Ler o inteiro \(H\) (dimensão dos histogramas), a string \(M\) (métrica: euclidiana ou manhattan) e o inteiro ímpar \(k\).
  3. Treinamento: Ler o inteiro \(N\) e, em seguida, \(N\) linhas, cada uma contendo o nome da classe seguido de \(H\) valores reais (o histograma de descritor).
  4. Teste: Ler o inteiro \(Q\) e, em seguida, \(Q\) linhas, cada uma contendo o nome da classe real seguido de \(H\) valores reais (o histograma de descritor da amostra de teste).
  5. Distância: Para cada amostra de teste, calcule a distância a cada exemplo de treinamento usando a métrica \(M\): \[ d_{\text{euclidiana}}(u,v) = \sqrt{\sum_{j=1}^{H}(u_j-v_j)^2}, \qquad d_{\text{manhattan}}(u,v) = \sum_{j=1}^{H} |u_j - v_j|. \]
  6. Classificação k-NN: Selecione os \(k\) exemplos de treinamento mais próximos (desempate de distância pela ordem de leitura, como no EP07_01) e classifique pela classe majoritária entre eles. Em caso de empate de votação entre duas ou mais classes, escolha a que aparece primeiro na lista de classes do item 1.
  7. Matriz de confusão: Construa uma matriz \(C \times C\) em que a linha corresponde à classe real e a coluna à classe prevista, seguindo a ordem de classes do item 1.
  8. Acurácia: Calcule a acurácia global como a razão entre acertos e \(Q\).
  9. Saída: Para cada amostra de teste, na ordem de entrada, imprimir a classe prevista. Em seguida, imprimir a matriz de confusão (uma linha por classe real, valores separados por espaço, na ordem das classes). Por fim, imprimir a acurácia arredondada a 4 casas decimais.

7.18.6.2 📌 Restrições Computacionais

  • Métrica selecionável: implemente ambas as distâncias; a métrica \(M\) define qual é utilizada em toda a execução (não é possível misturar métricas na mesma chamada).
  • Desempate de votação determinístico: o critério do item 6 (ordem da lista de classes) deve ser seguido mesmo quando o empate envolve mais de duas classes.
  • Independência de treino e teste: não há necessidade de validar que as amostras de teste não aparecem no treino — assuma que a entrada é válida.

7.18.6.3 🧠 Fundamentação Teórica

Etapa do exercício Etapa correspondente no capítulo
Histogramas de treino/teste já extraídos descritor_lbp aplicado às texturas sintéticas
Distância euclidiana ou Manhattan Parâmetro metric do KNeighborsClassifier
Votação majoritária com \(k\) vizinhos KNeighborsClassifier.predict
Matriz de confusão \(C\times C\) confusion_matrix do scikit-learn
Acurácia global accuracy_score do scikit-learn

Este exercício evidencia, de forma controlada, um resultado discutido no capítulo: a escolha da métrica de distância e do valor de \(k\) pode alterar a classe prevista para uma mesma amostra, mesmo mantendo fixo o descritor utilizado — reforçando que, no reconhecimento de padrões clássico, o descritor, a métrica e o classificador formam um sistema interdependente, e não peças isoladas.

7.18.6.4 📦 Especificação de Entrada e Saída (VPL)

Entrada:

  • Linha 1: inteiro \(C\) seguido de \(C\) nomes de classe.
  • Linha 2: inteiro \(H\), string \(M\) e inteiro \(k\).
  • Linha 3: inteiro \(N\).
  • Próximas \(N\) linhas de treinamento: nome da classe seguido de \(H\) reais.
  • Próxima linha: inteiro \(Q\).
  • Próximas \(Q\) linhas de teste: nome da classe real seguido de \(H\) reais.

Saída:

  • \(Q\) linhas com a classe prevista de cada amostra de teste, na ordem de entrada.
  • \(C\) linhas com a matriz de confusão (uma linha por classe real).
  • Última linha: Acuracia: <valor>.

7.18.6.5 📌 Exemplos

Entrada (resumida) Saída Observação
2 granular listrada
2 euclidiana 1
4
granular 0.9 0.1
granular 0.8 0.2
listrada 0.1 0.9
listrada 0.2 0.8
2
granular 0.85 0.15
listrada 0.15 0.85
granular
listrada
1 0
0 1
Acuracia: 1.0000
Com \(k=1\), cada teste é classificado pelo vizinho de treino mais próximo.
Nota

Este simulador usa um conjunto simplificado de 3 classes (granular, listrada, manchada) sobre pontos 2D fictícios, apenas para ilustrar o pipeline de votação, desempate e matriz de confusão do k-NN. No EP07_07, você aplicará essa mesma lógica a um mosaico de imagem real, que introduz uma quarta classe (xadrez) e substitui os pontos 2D por histogramas LBP extraídos diretamente dos pixels da imagem.

🎮 Simulador EP07_06: Pipeline k-NN Multi-Classe 6 Treino · 3 Teste · 3 Classes

Escolha a métrica, o valor de k e a amostra de teste (★). Veja os k vizinhos mais próximos, a votação, o desempate quando necessário, e como isso se propaga para a matriz de confusão e a acurácia do conjunto inteiro.

Métrica (M)
Vizinhos (k)
Amostra de teste (★)
📏 Distâncias até a amostra de teste (ordenadas) — #i = ordem de leitura na lista de treino (passe o mouse)
🗳️ Votação entre os k vizinhos
📋 Matriz de confusão e acurácia — rodando o pipeline sobre as 3 amostras de teste
Figura 7.26: Simulador EP07_06: Pipeline k-NN Multi-Classe (votacao, desempate e matriz de confusao)
%%writefile EP07_06.py
# Código Python
Writing EP07_06.py
TestSuite("EP07_06.py").run()
✔️ EP07_06.cases já existe em casos/
📋 5 caso(s) carregado(s) de casos/EP07_06.cases

🔍 Testando Python: EP07_06.py
⚠️ EP07_06.py: Arquivo sem conteúdo (menos de 3 linhas). Testes ignorados.