Montar el taller: entorno, datos crudos y Random Forest con las manos
Lunes 21 de septiembre a Sabado 26 de septiembre · 6 días · 21.0 h
Objetivo de la semana: Terminar el sábado sabiendo ejecutar un Random Forest completo sobre tus propios datos y con las seis fuentes del roadmap ya normalizadas a EPSG:32717.
Crear el esqueleto del pipeline y el entorno de Python
1.0 h Tyrone- Crear
Metodologia/pipeline/con las subcarpetasdatos/,datos/normalizado/,scripts/,salidas/,figuras/yqgis/. - Crear el entorno virtual e instalar geopandas, rasterio, rasterstats, scikit-learn, pandas, numpy, matplotlib, seaborn, scipy, joblib y openpyxl.
- Congelar las versiones en
requirements.txt(la reproducibilidad es parte de la metodología y el tribunal la pregunta).
Metodologia/pipeline/requirements.txt y el árbol de carpetas creado.
El comando de comprobación imprime las versiones de geopandas, rasterio y scikit-learn sin ningún error de importación.
py -m venv .venv && .venv\Scripts\activate && pip install geopandas rasterio rasterstats scikit-learn pandas matplotlib seaborn scipy joblib openpyxl && pip freeze > requirements.txt
Sesión RF 1 - Ver el algoritmo correr de punta a punta
1.5 h Tyrone- Ejecutar tal cual
Metodologia/Random Forest/ejemplo_random_forest.pyy comparar la salida consalida_ejemplo.txt: deben coincidir (semilla fija). - Tocar tres cosas de una en una y anotar qué pasa:
N = 200yN = 5000;random_state = 7;n_estimators = 5. - Localizar en el código las cuatro líneas que importan:
train_test_split,RandomForestClassifier(...),.fit(X_train, y_train)y.predict(X_test). - Escribir cinco líneas en
bitacora_rf.md: qué hace cada una de esas cuatro líneas.
Metodologia/pipeline/bitacora_rf.md con la sesión 1 anotada.
Puedes explicar de memoria, sin mirar el código, qué son X, y, fit y predict, y por qué el resultado no cambia entre dos ejecuciones seguidas.
python "Metodologia/Random Forest/ejemplo_random_forest.py"
Para estudiar README_Random_Forest.md, secciones 1 a 4 (Metodologia/Random Forest/)
1.1 Inventariar las seis fuentes de datos
1.0 h Tyrone- Abrir una por una las seis fuentes que ya tienes en el repositorio y anotar en una tabla: nombre, ruta real, formato, CRS declarado, número de entidades, fecha del dato, institución y licencia.
- Comprobar el CRS de cada capa con geopandas (no confiar en el nombre del archivo).
- Marcar en la tabla cuáles están en EPSG:32717 y cuáles habrá que reproyectar.
pipeline/salidas/inventario_fuentes.csv con ocho columnas y seis filas.
Las seis fuentes del diagrama (mapas 4G, radiobases, topografía, población, infraestructura y suelo) tienen ruta real verificada y CRS comprobado con código.
python -c "import geopandas as gpd; g=gpd.read_file(r'ruta.shp'); print(g.crs, len(g), g.columns.tolist())"
1.2 Extraer las tablas de población del PDOT
2.0 h Tyrone- Localizar en
Metodologia/Poblacion El Valle/PDOT-EL-Valle_completo.pdflas tablas 4-50 y 4-51 (población por comunidad) y anotar el número de página. - Extraer el texto con
pdftotext -layoutacotado a esas páginas y limpiarlo a CSV. - Verificar que la suma de las comunidades cuadra con el total parroquial que declara el propio PDOT; si no cuadra, anotar la diferencia y su causa.
- Dejar constancia del año del censo o proyección, porque esa fecha irá en la memoria.
pipeline/datos/poblacion_comunidades.csv con columnas comunidad, población, anio, fuente.
La suma de la columna población difiere menos del 1 % del total parroquial del PDOT, y el número de comunidades coincide con el de la tabla original.
pdftotext -layout -f 120 -l 124 "PDOT-EL-Valle_completo.pdf" poblacion.txt
Sesión RF 2 - Métricas: por qué la exactitud engaña
1.5 h Tyrone- En el ejemplo sintético, forzar que solo el 10 % de las celdas sean 'adecuadas' (así será tu caso real) y volver a entrenar.
- Imprimir la matriz de confusión y anotar los cuatro números: VP, FP, VN, FN.
- Calcular a mano, con calculadora, precisión, recall y F1 a partir de esos cuatro números, y comprobar que coinciden con los de
classification_report. - Responder por escrito: en esta tesis, ¿qué error duele más, un falso positivo (recomendar un sitio malo) o un falso negativo (no recomendar un sitio bueno)?
Bitácora RF sesión 2 con la matriz, el cálculo a mano y la respuesta escrita.
Sabes señalar en la matriz cuál casilla es un falso negativo y explicar en una frase por qué la exactitud puede ser del 90 % con un modelo inservible.
from sklearn.metrics import confusion_matrix, classification_report
Para estudiar README_Random_Forest.md, sección de evaluación; popup 3.5 del roadmap (/roadmap -> bloque 'Evaluar con el 30 % de prueba')
1.2 Convertir la población en capa de puntos
1.0 h Tyrone- Unir el CSV del PDOT con las coordenadas que levanto Freddy.
- Revisar las comunidades que Freddy marcó en rojo y resolverlas con el mapa del PDOT.
- Exportar a
comunidades_el_valle.gpkgen EPSG:32717.
pipeline/datos/comunidades_el_valle.gpkg (puntos con población).
Todos los puntos caen dentro del límite de El Valle y ninguna comunidad quedó sin coordenada.
gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lon, df.lat), crs=4326).to_crs(32717).to_file('comunidades_el_valle.gpkg')
1.3 Extraer las radiobases 4G de las tres operadoras
1.0 h Tyrone- Leer las carpetas
Ubicaciones de Radiobase/CONECEL,/OTECELy/CNT. - Quedarse solo con los registros de tecnología 4G/LTE y armar una tabla única con operador, lat, lon, altura de antena, azimut y banda si existen.
- Recortar a El Valle más un buffer de 5 km (las radiobases de fuera también cubren dentro, y eso importa para
dist_rb4g_km).
pipeline/datos/radiobases_4g.gpkg con el campo operador.
El conteo por operador cuadra con el archivo original de ARCOTEL y todos los puntos caen dentro del bbox de El Valle ampliado 5 km.
Sesión RF 3 - Las perillas del bosque
1.5 h Tyrone- Sobre el ejemplo, barrer
n_estimatorsen 5, 25, 100 y 500 y anotar el F1 de cada uno. - Barrer
max_depthen 2, 5, 10 y None, ymin_samples_leafen 1, 5 y 20. - Graficar F1 frente a cada perilla y guardar la figura.
- Escribir la conclusión práctica: cuál perilla movió más el resultado y cuál casi nada.
pipeline/figuras/rf_hiperparámetros_demo.png + conclusión en la bitácora.
Puedes decir, sin dudar, cuál de las tres perillas controla el sobreajuste y cuál solo hace el cálculo más lento.
for n in [5,25,100,500]: RandomForestClassifier(n_estimators=n, random_state=42)
Para estudiar Popup 3.3 del roadmap, 'Ajustar los hiperparámetros' (/roadmap -> Etapa 3)
1.3 Depurar duplicados y sectores
2.0 h Tyrone- Detectar torres repetidas: varios registros a menos de 25 m son sectores de la misma estación, no estaciones distintas.
- Agrupar por cercanía y dejar una fila por emplazamiento con un campo
n_sectores. - Contar cuántos emplazamientos 4G quedan dentro de El Valle. Anotar el número: con esos emplazamientos se calibran los umbrales del etiquetado (riesgo R2).
radiobases_4g.gpkg depurado + conteo de emplazamientos dentro de la parroquia.
No quedan dos puntos a menos de 25 m y el número de emplazamientos dentro de El Valle está escrito en la bitácora.
gdf.geometry.buffer(25).unary_union # o sklearn.cluster.DBSCAN(eps=25, min_samples=1)
Sesión RF 4 - Sobreajuste: verlo, no solo entenderlo
1.5 h Tyrone- Entrenar el ejemplo con
max_depth=Nonee imprimir el F1 en entrenamiento y en prueba. Anotar la diferencia. - Repetir con
max_depth=3. Anotar de nuevo. - Hacer lo mismo con un solo árbol (
n_estimators=1) y con 500. - Escribir la regla práctica que acabas de comprobar: cuando train sube y test baja, el modelo esta memorizando.
Tabla de 4 filas (train F1 / test F1) en la bitácora.
Puedes mostrar con números propios por qué un árbol solo no sirve y el bosque sí.
modelo.score(X_train, y_train) vs modelo.score(X_test, y_test)
Reunión 1 con el director
1.0 h Los dos- Presentar este cronograma y pedir que valide el plazo del 6 de noviembre.
- Validar el alcance completo: las 3 mallas de celdas, un modelo por malla.
- Plantear la decisión pendiente: qué significa exactamente 'buen sitio' (criterio de etiquetado). Pedir que la respuesta llegue antes del 14 de octubre.
- Acordar que en cada reunión se enseña un producto, no un avance verbal.
Acta de una página en Documentos/actas/2026-09-25.md.
El acta tiene la lista de acuerdos y la fecha límite de la decisión de etiquetado.
1.4 Revisar las seis capas en QGIS
2.5 h Tyrone- Crear el proyecto
pipeline/qgis/el_valle.qgzcon el CRS fijado a EPSG:32717. - Cargar las seis capas y mirarlas superpuestas sobre el límite de la parroquia.
- Anotar los tres defectos clasicos: capas desplazadas (CRS mal declarado), geometrías inválidas y huecos de cobertura donde debería haber dato.
- Dejar la lista de defectos escrita; mañana se corrigen.
pipeline/qgis/el_valle.qgz + salidas/defectos_capas.md.
Las seis capas se ven alineadas sobre el límite y la lista de defectos está escrita con el nombre de la capa afectada.
1.4 Corregir lo detectado
1.0 h Tyrone- Reparar geometrías inválidas (Vectorial > Herramientas de geometría > Corregir).
- Recortar todas las capas al límite de El Valle más 2 km.
- Revisar el DEM: huecos, valores absurdos y unidades (metros).
Capas corregidas en datos/normalizado/.
gdf.is_valid.all() devuelve True para todas las capas vectoriales y el DEM no tiene celdas con valores fuera del rango 2300-3400 m.
1.5 Escribir 01_normalizar.py
1.0 h
Tyrone
- Un script que lea cada fuente cruda, la reproyecte a EPSG:32717, valide la geometría y la guarde en
datos/normalizado/. - Nada de pasos manuales: si hubo un arreglo a mano en QGIS, se traduce a código.
- Que imprima un resumen por capa: entidades, CRS, extensión.
pipeline/scripts/01_normalizar.py.
Borrando datos/normalizado/ y ejecutando el script, todo se regenera idéntico sin tocar QGIS.
python scripts/01_normalizar.py
Sesión RF 5 - Guardar, cargar y no perder la reproducibilidad
1.5 h Tyrone- Guardar el modelo del ejemplo con
joblib.dumpy volver a cargarlo en otro script. - Comprobar que el modelo cargado predice exactamente lo mismo.
- Montar el mismo flujo dentro de un
Pipelinede scikit-learn. - Anotar la regla: toda semilla se fija y se escribe en la memoria.
pipeline/scripts/demo_joblib.py + nota en la bitácora.
Dos ejecuciones distintas del script dan exactamente la misma predicción para la misma celda.
import joblib; joblib.dump(modelo, 'modelo.pkl'); joblib.load('modelo.pkl')
En paralelo, Freddy
Tareas guiadas y verificables que corren aparte: no descuentan de las 3.5 h diarias de la línea principal.
Instalar Radio Mobile y cargar el terreno de El Valle
3 hDescargar Radio Mobile 11.6.x, instalar en Windows, bajar los mosaicos SRTM de 1 arcosegundo que cubren -3.05/-2.80 lat y -79.05/-78.85 lon, y configurar la carpeta de terreno en Options > Internet > SRTM. Centrar un mapa de 20x20 km en El Valle.
Captura del mapa de El Valle con relieve visible + carpeta SRTM con los .hgt.
Se abre un mapa de 20x20 km centrado en El Valle y el perfil de terreno entre dos puntos cualesquiera muestra altitudes entre 2400 y 3300 m.
Georreferenciar las comunidades del PDOT
4 hCon la lista de comunidades que te pase Tyrone, buscar cada centro poblado en Google Maps / OSM, copiar lat-lon en grados decimales y pegarla en la columna correspondiente de la hoja. Si una comunidad no aparece, marcarla en rojo y seguir con la siguiente.
Hoja poblacion_comunidades.csv con las columnas lat y lon llenas.
Todas las filas tienen coordenadas o están marcadas en rojo; ninguna queda en blanco sin marcar, y todas las coordenadas caen dentro del rectángulo de El Valle.