PDI+VC · Ejercicio de Programación

EP07_02 — 🟡 Normalización Z-score y Robustez del k-NN ante Escalas Distintas

7.18.2 EP07_02 🟡 Normalización Z-score y Robustez del k-NN ante Escalas Distintas

Este ejercicio revisita el clasificador implementado en el EP07_01, esta vez bajo la óptica discutida en la sección El Impacto de la Escala y la Normalización de Características del capítulo: el k-NN decide basándose en la distancia entre vectores, de modo que una característica medida en una escala mucho mayor que las demás tiende a dominar el cálculo de la distancia, incluso cuando no es la más relevante para separar las clases.

Un sistema de inspección registra, para cada pieza, su área (en píxeles, pudiendo llegar a cientos o miles) y su circularidad (siempre entre \(0\) y \(1\)). Usted ha sido encargado de clasificar nuevas piezas mediante k-NN de dos formas — con y sin la estandarización Z-score presentada en el capítulo — y de reportar en qué casos ambas aproximaciones divergen.

7.18.2.1 📋 Directrices de Implementación

  1. Cantidad y parámetro: Leer el entero \(N\) (número de ejemplos de entrenamiento) y el entero impar \(k\).
  2. Ejemplos de entrenamiento: Para cada uno de los \(N\) ejemplos, leer tres valores: el área \(x_1\) (real), la circularidad \(x_2\) (real) y la etiqueta \(r\) (entero, \(0\) o \(1\)).
  3. Consultas: Leer el entero \(Q\) y, a continuación, las coordenadas \(x_1, x_2\) de cada consulta.
  4. Clasificación sin normalización: Para cada consulta, clasifíquela mediante k-NN directamente sobre \((x_1, x_2)\), con distancia euclidiana y las mismas reglas de desempate del EP07_01 (orden de lectura para distancias empatadas; vecino más cercano entre clases empatadas en la votación).
  5. Parámetros de normalización: Calcular la media \(\mu_j\) y la desviación estándar poblacional \(\sigma_j\) (división por \(N\), no por \(N-1\) — la misma convención adoptada por la clase StandardScaler) de cada característica \(j \in \{1,2\}\), exclusivamente sobre el conjunto de entrenamiento.
  6. Estandarización: Transformar cada característica de entrenamiento y de consulta mediante \[ z_j = \frac{x_j - \mu_j}{\sigma_j}. \] Si \(\sigma_j = 0\) (característica constante en el entrenamiento), definir \(z_j = 0\) para todas las muestras de esa característica, evitando la división por cero.
  7. Clasificación con normalización: Repetir la clasificación k-NN del punto 4, ahora sobre los vectores estandarizados \((z_1, z_2)\), con las mismas reglas de desempate.
  8. Salida: Para cada consulta, en el orden de entrada, imprimir las dos clases previstas. Al final, imprimir el número de consultas en las que las dos clasificaciones divergen.

7.18.2.2 📌 Restricciones Computacionales

  • Ajuste solo en el entrenamiento: \(\mu_j\) y \(\sigma_j\) se calculan únicamente a partir del conjunto de entrenamiento y se reaplican a las consultas — nunca se recalculan a partir de ellas. Esta práctica evita la fuga de datos (data leakage), mencionada en la sección de normalización del capítulo.
  • Desviación estándar poblacional: utilizar \(\sigma_j = \sqrt{\frac{1}{N}\sum_i (x_{i,j}-\mu_j)^2}\), y no la versión muestral (división por \(N-1\)).
  • Característica constante: tratar \(\sigma_j = 0\) como caso especial (punto 6); no debe ocurrir un error de división por cero.
  • Reglas de desempate: reutilizar exactamente las convenciones del EP07_01, tanto en la selección de los \(k\) vecinos como en la votación mayoritaria.

7.18.2.3 🧠 Fundamentación Teórica

Elemento Papel
Estandarización Z-score Reescala cada característica para media \(0\) y desviación estándar \(1\), haciendo comparables escalas heterogéneas
Ajuste (fit) solo en el entrenamiento Garantiza que la evaluación sobre las consultas refleje únicamente lo que el modelo aprendió en el entrenamiento
Distancia euclidiana sin normalización Dominada por la característica de mayor amplitud — aquí, el área
Predicción divergente Evidencia que la escala de las características, y no solo el algoritmo o los datos, puede determinar la frontera de decisión del k-NN

Este ejercicio refuerza, de forma controlada, la razón por la cual el StandardScaler se aplica antes del k-NN a lo largo del capítulo: sin esta etapa, las características de circularidad — incluso siendo altamente discriminativas — pueden ser prácticamente ignoradas por el clasificador frente a una característica de área con amplitud cientos de veces mayor.

7.18.2.4 📦 Especificación de Entrada y Salida (VPL)

Entrada:

  • Línea 1: Enteros \(N\) y \(k\), separados por espacio.
  • Siguientes \(N\) líneas: tres valores por línea — \(x_1\), \(x_2\) (reales) y \(r\) (entero \(\in \{0,1\}\)), separados por espacio.
  • Siguiente línea: entero \(Q\).
  • Siguientes \(Q\) líneas: dos valores por línea — \(x_1\), \(x_2\) (reales) de la consulta, separados por espacio.

Salida:

  • \(Q\) líneas, en el formato SemNorm=<0|1> ComNorm=<0|1>, en el orden de entrada de las consultas.
  • Última línea: Divergiu: <int>.

7.18.2.5 📌 Ejemplos

Entrada Salida Observación
4 3
10 0.9 0
12 0.85 0
900 0.2 1
950 0.25 1
1
500 0.88
SemNorm=1 ComNorm=0
Divergiu: 1
Sin normalización, el área (escala de cientos) domina la distancia y la consulta se clasifica como clase 1. Tras la estandarización, la circularidad — mucho más cercana a las muestras de clase 0 — pasa a pesar de forma comparable, y la predicción cambia a 0.
2 1
0 0.5 0
100 0.5 1
1
60 0.5
SemNorm=1 ComNorm=1
Divergiu: 0
La circularidad es constante en el entrenamiento (\(\sigma_2=0\)); por la regla del punto 6, \(z_2=0\) para todas las muestras, y la clasificación depende solo del área en ambos casos.
🎮 Simulador EP07_02: Normalización Z-score y Distancia k-NN Estandarización de Características
Cada ejemplo posee dos características: área (px) y circularidad [0, 1]. Alterne la normalización y observe el cambio en la clase prevista.
–
Figura 7.22: Simulador EP07_02: Efecto de la Normalización Z-score en la Distancia k-NN
%%writefile EP07_02.py
# Código Python
Overwriting EP07_02.py
TestSuite("EP07_02.py").run()
✔️ EP07_02.cases ya existe en casos/
📋 5 caso(s) cargado(s) de casos/EP07_02.cases

🔍 Probando Python: EP07_02.py
⚠️ EP07_02.py: archivo vacío (menos de 3 líneas). Pruebas omitidas.