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.
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
- 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.
- Configuração: Ler o inteiro \(H\) (dimensão dos histogramas), a string \(M\) (métrica:
euclidianaoumanhattan) e o inteiro ímpar \(k\). - 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).
- 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).
- 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|. \]
- 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.
- 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.
- Acurácia: Calcule a acurácia global como a razão entre acertos e \(Q\).
- 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. |
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.
%%writefile EP07_06.py
# Código PythonWriting 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.