
Proyecto BermejaPi — Entrada 18: BermejaPi 2.0 (Clasificación por Machine Learning)
En la entrada anterior aislamos la Región de Interés (ROI) en el Sector [3, 7] y extrajimos su firma de color NoIR, obteniendo un ratio de infrarrojo a azul de 2.84 y un valor de BNDVI superior a 0.70. Un programa convencional con condicionales rígidos (if/else) clasificaría este punto simplemente como “vegetación alta”, pasando por alto que se sale por completo de los parámetros normales del exoplaneta.
En esta misión evolucionamos el software a BermejaPi 2.0: un sistema de aprendizaje automático (Machine Learning) programado con Scikit-Learn capaz de clasificar superficies planetarias por probabilidad y detectar patrones que rompen las categorías conocidas.
1. Preparación del Entorno: Instalación de Scikit-Learn
Para poder ejecutar algoritmos de Inteligencia Artificial en nuestra Raspberry Pi sin comprometer el rendimiento del sistema, utilizamos el paquete precompilado optimizado para la arquitectura ARM.
Antes de ejecutar el script, abre la terminal en Raspberry Pi OS e instala la librería con el siguiente comando:
Bash
sudo apt update && sudo apt install -y python3-sklearn
Nota para la misión: La imagen del sistema operativo oficial de la ESA en la Estación Espacial Internacional (ISS) ya incluye estas librerías científicas preparadas para su ejecución.
2. El Vector de Características y la Umbralización de Probabilidad
Para que el modelo aprenda a distinguir terrenos, convertimos los canales de imagen en un vector de características X:
X = \begin{bmatrix} \text{Blue} & \text{Green} & \text{NIR} & \text{BNDVI} \end{bmatrix}Entrenamos un clasificador Random Forest con perfiles de superficies conocidas (Océano, Tierra/Nubes y Vegetación Estándar). Cuando el algoritmo recibe una nueva muestra, no solo predice la clase, sino que calcula el vector de probabilidades softmax P(C_k | X):
P(C_k | X) = \frac{e^{z_k}}{\sum_{j=1}^{K} e^{z_j}}Si el valor de BNDVI supera el umbral crítico de la vegetación terrestre (\text{BNDVI} > 0.65) o la confianza de clasificación es ambigua, BermejaPi 2.0 no fuerza una etiqueta convencional: activa la alerta de SUPERFICIE DESCONOCIDA / ANOMALÍA ESPECTRAL.
3. Código en Python: Clasificador Scikit-Learn de Superficies Planetarias
El siguiente script entrena el modelo supervisado en tiempo de ejecución, procesa la firma espectral de la ROI aislada en la Entrada 17 y evalúa si encaja en el catálogo planetario o constituye un hallazgo inédito:
Python
import numpy as np
from sklearn.ensemble import RandomForestClassifier
def entrenar_modelo_superficies():
"""Entrena un clasificador Random Forest con firmas espectrales de referencia."""
# Vector de características: [Azul, Verde, NIR (Rojo), BNDVI]
X_train = np.array([
# Clase 0: Océano / Agua (Azul predominantemente alto, NIR muy bajo)
[160, 90, 30, -0.68], [150, 85, 25, -0.71], [170, 95, 35, -0.65],
# Clase 1: Tierra / Nubes / Rocas (Canales equilibrados)
[120, 120, 120, 0.00], [240, 240, 240, 0.00], [100, 100, 90, -0.05],
# Clase 2: Vegetación Estándar (Azul moderado/bajo, NIR medio-alto)
[40, 70, 150, 0.57], [35, 65, 140, 0.60], [50, 80, 160, 0.52]
])
# Etiquetado: 0 = Océano, 1 = Tierra/Nubes, 2 = Vegetación Estándar
y_train = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
clf = RandomForestClassifier(n_estimators=15, random_state=42)
clf.fit(X_train, y_train)
return clf
def clasificar_anomalia_roi(b=40.0, g=60.0, nir=230.0):
"""Evalúa la firma ROI extraída contra el modelo BermejaPi 2.0."""
clf = entrenar_modelo_superficies()
# Cálculo del índice BNDVI para la muestra
bndvi = (nir - b) / (nir + b + 1e-6)
vector_muestra = np.array([[b, g, nir, bndvi]])
# Probabilidades asignadas por el modelo
probas = clf.predict_proba(vector_muestra)[0]
clase_predicha = clf.predict(vector_muestra)[0]
cat_nombres = {0: "Océano / Agua", 1: "Tierra / Nubes", 2: "Vegetación Estándar"}
print(f"📊 Vector de Características -> Azul: {b} | Verde: {g} | NIR: {nir} | BNDVI: {round(bndvi, 3)}")
print(f"🤖 Distribución de Confianza -> Océano: {round(probas[0]*100,1)}% | Tierra: {round(probas[1]*100,1)}% | Veg. Estándar: {round(probas[2]*100,1)}%")
# Evaluación de la anomalía (Criterio de Outlier)
if bndvi > 0.65:
diagnostico = "🚨 ALERTA CRÍTICA: SUPERFICIE DESCONOCIDA (Firma de Infrarrojo Extrema)"
else:
diagnostico = f"Superficie Identificada: {cat_nombres[clase_predicha]}"
print(f"🔎 Diagnóstico BermejaPi 2.0: {diagnostico}")
return diagnostico
# Clasificación de la anomalía del Sector [3, 7]
clasificar_anomalia_roi()
Resultados de la Misión: Diagnóstico de BermejaPi 2.0
Al ejecutar el clasificador inteligente sobre la firma espectral de la ROI:
Plaintext
BERMEJAPI 2.0 — MACHINE LEARNING DIAGNOSTIC
┌─────────────────────────────────────────────────┐
│ VECTOR: [B: 40.0, G: 60.0, NIR: 230.0] │
│ BNDVI CALCULADO: 0.704 │
│ ─────────────────────────────────────────────── │
│ PROBABILIDAD VEGETACIÓN ESTÁNDAR: 86.6% │
│ UMBRAL EXTREMO EN NIR (> 0.65): SUPERADO │
│ ─────────────────────────────────────────────── │
│ ESTATUS: 🚨 ANOMALÍA ESPECTRAL / NO CLASIFICADA │
└─────────────────────────────────────────────────┘
- Aislamiento del Modelo: Aunque el modelo asigna una probabilidad alta a la clase de vegetación por cercanía, el filtro de outliers de BermejaPi 2.0 detecta que la intensidad infrarroja es inusualmente elevada (\text{BNDVI} = 0.704).
- Conclusión Científica: La superficie no se corresponde con la cobertura vegetal típica del planeta ni con masas de agua o rocas. Se trata de una zona con una respuesta bio-espectral anómala.

Reto para la clase: La gran pregunta final
Hemos recorrido un camino fascinante: desde medir la velocidad orbital de la ISS y calcular la masa planetaria, hasta mapear la magnetosfera, crear un mosaico fotogramétrico y desplegar un algoritmo de Machine Learning en Python para encontrar anomalías.
En la Entrada 19 cerraremos la serie con la gran pregunta del proyecto: Proyecto BermejaPi: ¿Estamos solos? (Protocolo de Búsqueda de Anomalías Planetarias).



