Un pipeline completo sobre California Housing — 20,640 viviendas, nueve modelos, 180 experimentos registrados. El resultado interesante no fue el error más bajo, sino descubrir cuáles de las mejoras eran reales y cuáles solo lo parecían.
El dataset trae ocho variables por distrito censal de California — ingreso medio, antigüedad, habitaciones, población, coordenadas — y el precio medio de la vivienda. El objetivo es predecir ese precio. Es el problema con el que arranca el libro de Géron, y su virtud es que todas las trampas del oficio caben en él.
Lo que sigue no es un recorrido por los modelos. Es lo que cambió de opinión durante el proceso: cuatro hallazgos que contradijeron lo que parecía obvio al empezar.
Cada punto es uno de los 4,128 distritos del conjunto de prueba — casas que el modelo nunca vio al entrenar. El color indica si subestimó o sobreestimó el precio. Filtra y las métricas de abajo se recalculan sobre el subconjunto.
El proyecto usaba fetch_california_housing de scikit-learn. Al comparar contra
el CSV original del libro apareció que la versión de la librería descarta la columna
ocean_proximity e imputa en silencio los 207 valores faltantes de
total_bedrooms.
Justo las dos cosas que el capítulo enseña a tratar — codificación de categóricas e imputación — eran las que la versión conveniente escondía. Cambiar a la fuente cruda también reveló que trae las filas en otro orden, así que con la misma semilla el conjunto de prueba cae en casas distintas: las métricas anteriores dejaron de ser comparables.
El escalado se aplicaba una vez sobre todo el conjunto de entrenamiento, antes de partirlo en
pliegues. Cada pliegue de validación se evaluaba entonces con estadísticas calculadas
incluyéndolo a él mismo. El cv_rmse salía optimista.
La corrección fue meter el preprocesamiento dentro del Pipeline, donde
scikit-learn lo reajusta en cada pliegue. La señal de que funcionó es sutil pero clara: antes
la validación cruzada reportaba un error menor que el del conjunto de prueba; ahora
reporta uno ligeramente mayor, que es lo que debe pasar.
Beneficio colateral: el artefacto guardado contiene el preprocesamiento. Quien lo carga le pasa datos crudos y funciona — no hay que replicar los pasos en producción, que es donde esto se rompe en la vida real.
Recuperada ocean_proximity, XGBoost la reportó como su variable
número uno por importancia — 0.61 contra 0.14 del ingreso medio. Parecía la
mejora grande del proyecto.
Midiendo con una ablación — mismo split, misma semilla, única diferencia la columna — resultó que mejora seis de siete modelos por márgenes mínimos, y que a XGBoost lo empeora.
La explicación: latitud y longitud ya estaban ahí. “Cerca del mar” era deducible de las coordenadas, solo que costaba varios cortes. Al recibirlo servido, el modelo lo usa de inmediato y reordena su ranking de importancia — pero la información no era nueva. Importancia alta no significa mejora predictiva cuando hay redundancia.
Un árbol solo puede partir el espacio con cortes rectangulares sobre latitud y longitud, así que aproximar “cerca de San Francisco” le cuesta muchos cortes y nunca queda fino. La solución del libro es un transformador propio: agrupar las coordenadas con K-means y reemplazar cada casa por su similitud a cada centro.
Fue el cambio que más rindió de todo el proyecto — más que cualquier ajuste de hiperparámetros. Y reordenó por completo la tabla: los métodos que promedian árboles independientes, que eran los más penalizados por tener que aproximar la geografía a mano, pasaron a ganarle a los de boosting.
Siguiendo la misma idea, se añadió otra variable geográfica: un k-vecinos sobre las coordenadas que responde “¿cuánto cuestan las casas de al lado?”. Su respuesta entra al modelo como una columna más.
En la primera versión su correlación con el precio era de 0.993. Una variable casi perfecta — y ahí estaba el problema: era demasiado buena.
El k-vecinos se había entrenado con las mismas casas sobre las que después predecía, así que cada casa aparecía entre sus propios vecinos. Estaba copiando la respuesta. Calculando la predicción de cada fila con un modelo que nunca la vio, la correlación cae a 0.845 — ese es su valor real.
Aun corregida, sigue siendo la segunda variable más útil del proyecto. Pero sin ese ajuste habría lucido espléndida durante el entrenamiento y se habría derrumbado en producción.
Un modelo del conjunto —SVR— tardaba más de veinte minutos y se excluyó de
la búsqueda. La razón anotada fue la que todo el mundo repite: “escala con el cuadrado
del número de filas”. Suena correcta y está en los libros.
Al medirla resultó falsa. El exponente real es n1.33 y un ajuste sobre el conjunto completo toma unos seis segundos. El tamaño de los datos nunca fue el problema.
El costo lo dominaba un solo hiperparámetro. Con el kernel polinómico y el parámetro de regularización en su valor más alto, el ajuste es 135 veces más lento que con la configuración barata. El espacio de búsqueda incluía justo esa esquina.
La decisión de excluirlo se sostiene —incluso ajustado se queda en 0.531 de error frente a 0.429— pero durante un tiempo el proyecto documentó una explicación inventada. La diferencia entre creer algo razonable y haberlo medido.
Con todo afinado, extra_trees quedó primero con 0.4063 de RMSE y XGBoost tercero
con 0.4291. Ordenar por esa columna y declarar un ganador es el reflejo natural. Es también un
error.
El RMSE sale de una muestra concreta de 4,128 casas. Con otras 4,128 habría dado distinto. El intervalo de confianza acota cuánto puede moverse — y cuando dos intervalos se traslapan, la diferencia cabe dentro del ruido del muestreo.
Si la precisión no distingue a los tres primeros, el desempate lo pone lo que sí se puede medir sin ambigüedad. Y ahí la diferencia no es sutil.
extra_trees crece 300 árboles sin límite de profundidad; XGBoost los poda a 7 niveles.
extra_trees pide 1.3 GB de memoria — no entra en ningún plan
gratuito ni en un servidor pequeño — y tarda trece veces más por petición. XGBoost ocupa
2.4 MB, cabe en cualquier lado y responde en 2.3 milisegundos.
Renunciar a 0.023 de RMSE que no se puede demostrar, a cambio de un modelo 293 veces más pequeño, no es una concesión. Es la decisión correcta, y es la que se toma en producción todos los días.