From 844c10ab48124ac3d6d5e72f0b6e5b00c38ad7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20Acu=C3=B1a?= Date: Mon, 18 May 2026 22:04:30 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20README=20de=20ra=C3=ADz=20por=20parte?= =?UTF-8?q?=20(9=20partes)=20con=20narrativa=20e=20=C3=ADndice=20de=20clas?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cada `classes/parte-N/` ahora tiene su propio README con: - De qué trata la parte (narrativa rica, no solo un listado) - Problemas concretos que resuelve - Resultados de aprendizaje al cierre - Estructura temática agrupada por subbloques - Índice completo de clases con links a cada README de clase - Navegación al programa, índice, parte anterior y siguiente El README raíz y `classes/README.md` ahora enlazan a los 9 README de parte desde una tabla, para que se pueda navegar el currículo en tres niveles: programa → parte → clase. Generación automatizada en `scripts/generate_part_readmes.py` para que los índices de clase se mantengan en sync si cambian nombres/cantidades. --- README.md | 24 +- classes/README.md | 35 +- classes/parte-0-prerrequisitos/README.md | 97 ++++ .../README.md | 96 ++++ classes/parte-2-deep-learning/README.md | 110 ++++ .../parte-3-estadistica-inferencial/README.md | 61 +++ classes/parte-4-mlops/README.md | 63 +++ classes/parte-5-ingenieria-de-datos/README.md | 54 ++ .../README.md | 52 ++ .../README.md | 51 ++ classes/parte-8-capstones/README.md | 48 ++ scripts/generate_part_readmes.py | 479 ++++++++++++++++++ 12 files changed, 1149 insertions(+), 21 deletions(-) create mode 100644 classes/parte-0-prerrequisitos/README.md create mode 100644 classes/parte-1-machine-learning-clasico/README.md create mode 100644 classes/parte-2-deep-learning/README.md create mode 100644 classes/parte-3-estadistica-inferencial/README.md create mode 100644 classes/parte-4-mlops/README.md create mode 100644 classes/parte-5-ingenieria-de-datos/README.md create mode 100644 classes/parte-6-sistemas-de-recomendacion/README.md create mode 100644 classes/parte-7-etica-fairness-privacidad/README.md create mode 100644 classes/parte-8-capstones/README.md create mode 100644 scripts/generate_part_readmes.py diff --git a/README.md b/README.md index 1480a203..c84f00c0 100644 --- a/README.md +++ b/README.md @@ -63,17 +63,19 @@ Integra currículo modular extenso, laboratorio interactivo local, portal del al ### 🗺️ Las 9 partes del currículo -| # | Parte | Clases | Foco | -|---|---|---|---| -| 0️⃣ | Prerrequisitos | 46 | Python aplicado, NumPy, pandas, visualización, SQL, NoSQL, APIs | -| 1️⃣ | ML clásico | 43 | Regresión, clasificación, ensembles, no supervisado | -| 2️⃣ | Deep Learning | 56 | Keras, TF, CNN, RNN, Transformers, RL, despliegue | -| 3️⃣ | Estadística inferencial | 13 | Hipótesis, A/B testing, inferencia causal, Bayes | -| 4️⃣ | MLOps | 14 | Docker, CI/CD, MLflow, monitoreo, interpretabilidad | -| 5️⃣ | Ingeniería de datos | 8 | Spark, Airflow, lakehouses, streaming | -| 6️⃣ | Recomendadores | 7 | Filtrado colaborativo, factorización, secuenciales | -| 7️⃣ | Ética, fairness, privacidad | 6 | Sesgo, explicabilidad, marcos normativos | -| 8️⃣ | Capstones | 4 | Proyectos integradores end-to-end | +Cada parte tiene su **propio README** con narrativa completa: de qué trata, qué problemas resuelve, resultados de aprendizaje, estructura temática y enlaces a las clases. + +| # | Parte | Clases | Foco | README | +|---|---|---:|---|---| +| 0️⃣ | Prerrequisitos | 46 | Python aplicado, NumPy, pandas, visualización, SQL, NoSQL, APIs | [📘 leer](classes/parte-0-prerrequisitos/README.md) | +| 1️⃣ | ML clásico | 43 | Regresión, clasificación, ensembles, no supervisado | [📘 leer](classes/parte-1-machine-learning-clasico/README.md) | +| 2️⃣ | Deep Learning | 56 | Keras, TF, CNN, RNN, Transformers, RL, despliegue | [📘 leer](classes/parte-2-deep-learning/README.md) | +| 3️⃣ | Estadística inferencial | 13 | Hipótesis, A/B testing, inferencia causal, Bayes | [📘 leer](classes/parte-3-estadistica-inferencial/README.md) | +| 4️⃣ | MLOps | 14 | Docker, CI/CD, MLflow, monitoreo, interpretabilidad | [📘 leer](classes/parte-4-mlops/README.md) | +| 5️⃣ | Ingeniería de datos | 8 | Spark, Airflow, lakehouses, streaming | [📘 leer](classes/parte-5-ingenieria-de-datos/README.md) | +| 6️⃣ | Recomendadores | 7 | Filtrado colaborativo, factorización, secuenciales | [📘 leer](classes/parte-6-sistemas-de-recomendacion/README.md) | +| 7️⃣ | Ética, fairness, privacidad | 6 | Sesgo, explicabilidad, marcos normativos | [📘 leer](classes/parte-7-etica-fairness-privacidad/README.md) | +| 8️⃣ | Capstones | 4 | Proyectos integradores end-to-end | [📘 leer](classes/parte-8-capstones/README.md) | ### 🚧 Trabajo pendiente diff --git a/classes/README.md b/classes/README.md index 36376ce0..d87dba55 100644 --- a/classes/README.md +++ b/classes/README.md @@ -1,9 +1,24 @@ # Índice del currículo -Total: 197 clases en 9 partes. +**197 clases · 9 partes.** Cada parte tiene su propio README con la narrativa completa (de qué trata, qué problemas resuelve, resultados de aprendizaje, estructura temática y prerrequisitos). +| Parte | Tema | Clases | README de la parte | +|---|---|---:|---| +| 0 | Prerrequisitos: Python, NumPy, pandas, visualización, SQL, APIs | 46 | [📘 leer parte 0](parte-0-prerrequisitos/README.md) | +| 1 | Machine Learning clásico | 43 | [📘 leer parte 1](parte-1-machine-learning-clasico/README.md) | +| 2 | Deep Learning (Keras, TF, Transformers, RL, despliegue) | 56 | [📘 leer parte 2](parte-2-deep-learning/README.md) | +| 3 | Estadística inferencial y causal | 13 | [📘 leer parte 3](parte-3-estadistica-inferencial/README.md) | +| 4 | MLOps en producción | 14 | [📘 leer parte 4](parte-4-mlops/README.md) | +| 5 | Ingeniería de datos | 8 | [📘 leer parte 5](parte-5-ingenieria-de-datos/README.md) | +| 6 | Sistemas de recomendación | 7 | [📘 leer parte 6](parte-6-sistemas-de-recomendacion/README.md) | +| 7 | Ética, fairness, privacidad | 6 | [📘 leer parte 7](parte-7-etica-fairness-privacidad/README.md) | +| 8 | Capstones | 4 | [📘 leer parte 8](parte-8-capstones/README.md) | -## Parte 0-prerrequisitos +--- + +A continuación, el índice plano de las 197 clases. Si buscas la narrativa de una parte, entra a su README (columna de arriba). + +## [Parte 0 — Prerrequisitos](parte-0-prerrequisitos/README.md) - [001 — Instalación de Python 3.12+ y entornos virtuales (venv, uv, conda)](parte-0-prerrequisitos/001-instalacion-de-python-3-12-y-entornos-virtuales-venv-uv-conda/README.md) - [002 — Jupyter y JupyterLab: kernels, magics, debugging, profiling](parte-0-prerrequisitos/002-jupyter-y-jupyterlab-kernels-magics-debugging-profiling/README.md) @@ -52,7 +67,7 @@ Total: 197 clases en 9 partes. - [045 — APIs REST con requests](parte-0-prerrequisitos/045-apis-rest-con-requests/README.md) - [046 — Web scraping con BeautifulSoup](parte-0-prerrequisitos/046-web-scraping-con-beautifulsoup/README.md) -## Parte 1-machine-learning-clasico +## [Parte 1 — Machine Learning Clásico](parte-1-machine-learning-clasico/README.md) - [047 — Panorama del ML: tipos, batch vs online, instance vs model-based](parte-1-machine-learning-clasico/047-panorama-del-ml-tipos-batch-vs-online-instance-vs-model-based/README.md) - [048 — Desafíos del ML: overfitting, underfitting, datos insuficientes](parte-1-machine-learning-clasico/048-desafios-del-ml-overfitting-underfitting-datos-insuficientes/README.md) @@ -98,7 +113,7 @@ Total: 197 clases en 9 partes. - [088 — Gaussian Mixture Models](parte-1-machine-learning-clasico/088-gaussian-mixture-models/README.md) - [089 — Detección de anomalías: Isolation Forest, LOF, One-Class SVM](parte-1-machine-learning-clasico/089-deteccion-de-anomalias-isolation-forest-lof-one-class-svm/README.md) -## Parte 2-deep-learning +## [Parte 2 — Deep Learning](parte-2-deep-learning/README.md) - [090 — Perceptrón, MLP y backpropagation](parte-2-deep-learning/090-perceptron-mlp-y-backpropagation/README.md) - [091 — Regresión y clasificación con MLP](parte-2-deep-learning/091-regresion-y-clasificacion-con-mlp/README.md) @@ -157,7 +172,7 @@ Total: 197 clases en 9 partes. - [144 — Entrenamiento multi-dispositivo, tf.distribute](parte-2-deep-learning/144-entrenamiento-multi-dispositivo-tf-distribute/README.md) - [145 — Entrenamiento a escala con Vertex AI](parte-2-deep-learning/145-entrenamiento-a-escala-con-vertex-ai/README.md) -## Parte 3-estadistica-inferencial +## [Parte 3 — Estadística Inferencial](parte-3-estadistica-inferencial/README.md) - [146 — Distribuciones: normal, binomial, Poisson, exponencial](parte-3-estadistica-inferencial/146-distribuciones-normal-binomial-poisson-exponencial/README.md) - [147 — Test t (una muestra, dos muestras, pareado)](parte-3-estadistica-inferencial/147-test-t-una-muestra-dos-muestras-pareado/README.md) @@ -173,7 +188,7 @@ Total: 197 clases en 9 partes. - [157 — Uplift modeling, DiD (difference-in-differences)](parte-3-estadistica-inferencial/157-uplift-modeling-did-difference-in-differences/README.md) - [158 — Bayes intro: priors, posterior, MCMC con PyMC](parte-3-estadistica-inferencial/158-bayes-intro-priors-posterior-mcmc-con-pymc/README.md) -## Parte 4-mlops +## [Parte 4 — MLOps](parte-4-mlops/README.md) - [159 — Versionado de datos con DVC](parte-4-mlops/159-versionado-de-datos-con-dvc/README.md) - [160 — Versionado de modelos y experimentos con MLflow](parte-4-mlops/160-versionado-de-modelos-y-experimentos-con-mlflow/README.md) @@ -190,7 +205,7 @@ Total: 197 clases en 9 partes. - [171 — Testing de datos: Great Expectations, Deequ](parte-4-mlops/171-testing-de-datos-great-expectations-deequ/README.md) - [172 — Testing de modelos: invariance, behavioral tests](parte-4-mlops/172-testing-de-modelos-invariance-behavioral-tests/README.md) -## Parte 5-ingenieria-de-datos +## [Parte 5 — Ingeniería de Datos](parte-5-ingenieria-de-datos/README.md) - [173 — Pipelines ETL/ELT con Airflow](parte-5-ingenieria-de-datos/173-pipelines-etl-elt-con-airflow/README.md) - [174 — Pipelines con Prefect o Dagster](parte-5-ingenieria-de-datos/174-pipelines-con-prefect-o-dagster/README.md) @@ -201,7 +216,7 @@ Total: 197 clases en 9 partes. - [179 — Formatos columnares: Parquet, Avro](parte-5-ingenieria-de-datos/179-formatos-columnares-parquet-avro/README.md) - [180 — Modelado dimensional (star/snowflake schemas)](parte-5-ingenieria-de-datos/180-modelado-dimensional-star-snowflake-schemas/README.md) -## Parte 6-sistemas-de-recomendacion +## [Parte 6 — Sistemas de Recomendación](parte-6-sistemas-de-recomendacion/README.md) - [181 — Filtrado colaborativo user-based e item-based](parte-6-sistemas-de-recomendacion/181-filtrado-colaborativo-user-based-e-item-based/README.md) - [182 — Factorización de matrices: SVD, ALS](parte-6-sistemas-de-recomendacion/182-factorizacion-de-matrices-svd-als/README.md) @@ -211,7 +226,7 @@ Total: 197 clases en 9 partes. - [186 — Cold-start problem](parte-6-sistemas-de-recomendacion/186-cold-start-problem/README.md) - [187 — Librerías: LightFM, Implicit, Surprise](parte-6-sistemas-de-recomendacion/187-librerias-lightfm-implicit-surprise/README.md) -## Parte 7-etica-fairness-privacidad +## [Parte 7 — Ética, Fairness y Privacidad](parte-7-etica-fairness-privacidad/README.md) - [188 — Tipos de sesgo algorítmico y orígenes](parte-7-etica-fairness-privacidad/188-tipos-de-sesgo-algoritmico-y-origenes/README.md) - [189 — Métricas de fairness: demographic parity, equalized odds, calibration](parte-7-etica-fairness-privacidad/189-metricas-de-fairness-demographic-parity-equalized-odds-calibration/README.md) @@ -220,7 +235,7 @@ Total: 197 clases en 9 partes. - [192 — GDPR y AI Act (EU)](parte-7-etica-fairness-privacidad/192-gdpr-y-ai-act-eu/README.md) - [193 — Reproducibilidad: seeds, lock files, versionado de datasets](parte-7-etica-fairness-privacidad/193-reproducibilidad-seeds-lock-files-versionado-de-datasets/README.md) -## Parte 8-capstones +## [Parte 8 — Capstones](parte-8-capstones/README.md) - [194 — Capstone 1: problema tabular end-to-end (EDA, modelo, API, dashboard)](parte-8-capstones/194-capstone-1-problema-tabular-end-to-end-eda-modelo-api-dashboard/README.md) - [195 — Capstone 2: NLP o series de tiempo end-to-end](parte-8-capstones/195-capstone-2-nlp-o-series-de-tiempo-end-to-end/README.md) diff --git a/classes/parte-0-prerrequisitos/README.md b/classes/parte-0-prerrequisitos/README.md new file mode 100644 index 00000000..41971478 --- /dev/null +++ b/classes/parte-0-prerrequisitos/README.md @@ -0,0 +1,97 @@ +# Parte 0 — Prerrequisitos: Python + NumPy + pandas + visualización + SQL + APIs + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏭️ Parte siguiente](../parte-1-machine-learning-clasico/README.md) + +**46 clases** · ~10–12 semanas a ritmo moderado + +**Fuente principal:** **VanderPlas** ([*Python Data Science Handbook*](https://jakevdp.github.io/PythonDataScienceHandbook/)) — secuencia y énfasis en NumPy, pandas y matplotlib. + +--- + +## 🎯 ¿De qué trata esta parte? + +Esta parte construye **toda la base técnica** que el resto del programa da por sentada. No es "introducción a Python" — es el conjunto mínimo de herramientas con las que un data scientist trabaja a diario: el lenguaje, los entornos reproducibles, el control de versiones, el stack numérico (NumPy / pandas), la visualización (matplotlib / seaborn / plotly), el acceso a datos (SQL, NoSQL, APIs, scraping) y la disciplina de proyecto (logging, type hints, manejo de errores, estructura cookiecutter). + +El recorrido es deliberadamente extenso porque cada laguna acá se convierte en deuda invisible que aparece después en Parte 1 (ML clásico) y Parte 2 (Deep Learning). Quien complete bien esta parte puede leer cualquier notebook profesional, reproducirlo, modificarlo y debuggearlo. + +## 🧩 Problemas que resuelve + +- Configurar un entorno Python aislado y reproducible (venv / uv / conda) sin colisiones de dependencias. +- Manipular datasets tabulares de tamaño medio (cientos de miles de filas) sin caer en bucles ni código lento. +- Limpiar, transformar y unir datos sucios usando pandas (faltantes, tipos, formatos, joins, groupby). +- Producir gráficos publicables (no solo `df.plot()`) con matplotlib + seaborn, incluyendo mapas geográficos. +- Consultar bases relacionales con SQL avanzado (CTEs, window functions) y conectarlas desde Python. +- Acceder a datos externos vía APIs REST y, cuando no hay API, mediante web scraping responsable. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Levantar un proyecto nuevo con estructura reproducible, dependencias fijadas y `pre-commit` en menos de 10 minutos. +- Escribir código NumPy/pandas vectorizado (sin loops) y justificar por qué es más rápido. +- Diseñar visualizaciones efectivas que comuniquen una conclusión, no solo "que se vean lindas". +- Escribir consultas SQL no triviales (window functions, CTEs recursivas) y traducirlas a pandas y viceversa. +- Extraer datos de una API o sitio web y dejarlos listos para análisis, manejando paginación y rate-limiting. + +## 🗺️ Estructura temática + +- **Setup y reproducibilidad** — clases 001–005 — instalación, Jupyter, Git/GitHub, estructura de proyecto, editor. +- **Python para data science** — clases 006–013 — tipos, comprehensions, funciones, OOP, pathlib, logging, type hints. +- **NumPy (8 clases)** — clases 014–021 — creación, ufuncs, agregaciones, broadcasting, masks, álgebra lineal, aleatoriedad. +- **pandas (11 clases)** — clases 022–032 — Series/DataFrame, indexación, joins, groupby, pivot, strings, series de tiempo. +- **Visualización** — clases 033–040 — matplotlib en profundidad, seaborn, visualización geográfica. +- **SQL** — clases 041–043 — desde fundamentos a window functions y conexión desde Python. +- **Acceso a datos externos** — clases 044–046 — MongoDB, APIs REST, web scraping con BeautifulSoup. + +## 📚 Índice de clases (46) + +- [001 — Instalación de Python 3.12+ y entornos virtuales (venv, uv, conda)](001-instalacion-de-python-3-12-y-entornos-virtuales-venv-uv-conda/README.md) +- [002 — Jupyter y JupyterLab: kernels, magics, debugging, profiling](002-jupyter-y-jupyterlab-kernels-magics-debugging-profiling/README.md) +- [003 — Git y GitHub para data scientists](003-git-y-github-para-data-scientists/README.md) +- [004 — Estructura reproducible de proyecto (cookiecutter-data-science)](004-estructura-reproducible-de-proyecto-cookiecutter-data-science/README.md) +- [005 — VS Code / Cursor para Python y Jupyter](005-vs-code-cursor-para-python-y-jupyter/README.md) +- [006 — Python: tipos, estructuras, control de flujo](006-python-tipos-estructuras-control-de-flujo/README.md) +- [007 — Comprehensions y generadores](007-comprehensions-y-generadores/README.md) +- [008 — Funciones, args, kwargs, lambdas, closures](008-funciones-args-kwargs-lambdas-closures/README.md) +- [009 — Manejo de excepciones y context managers](009-manejo-de-excepciones-y-context-managers/README.md) +- [010 — OOP básico, dataclasses, herencia](010-oop-basico-dataclasses-herencia/README.md) +- [011 — pathlib, lectura y escritura de archivos](011-pathlib-lectura-y-escritura-de-archivos/README.md) +- [012 — Logging](012-logging/README.md) +- [013 — Type hints y mypy](013-type-hints-y-mypy/README.md) +- [014 — NumPy: tipos, creación, atributos](014-numpy-tipos-creacion-atributos/README.md) +- [015 — NumPy: ufuncs y vectorización](015-numpy-ufuncs-y-vectorizacion/README.md) +- [016 — NumPy: agregaciones](016-numpy-agregaciones/README.md) +- [017 — NumPy: broadcasting](017-numpy-broadcasting/README.md) +- [018 — NumPy: boolean masks y fancy indexing](018-numpy-boolean-masks-y-fancy-indexing/README.md) +- [019 — NumPy: ordenamiento y búsqueda](019-numpy-ordenamiento-y-busqueda/README.md) +- [020 — NumPy: álgebra lineal con numpy.linalg](020-numpy-algebra-lineal-con-numpy-linalg/README.md) +- [021 — NumPy: aleatoriedad y semillas](021-numpy-aleatoriedad-y-semillas/README.md) +- [022 — Pandas: Series y DataFrame](022-pandas-series-y-dataframe/README.md) +- [023 — Pandas: indexación (loc, iloc, at, iat)](023-pandas-indexacion-loc-iloc-at-iat/README.md) +- [024 — Pandas: operaciones y alineación](024-pandas-operaciones-y-alineacion/README.md) +- [025 — Pandas: datos faltantes](025-pandas-datos-faltantes/README.md) +- [026 — Pandas: MultiIndex](026-pandas-multiindex/README.md) +- [027 — Pandas: concat, merge, join](027-pandas-concat-merge-join/README.md) +- [028 — Pandas: groupby (split-apply-combine)](028-pandas-groupby-split-apply-combine/README.md) +- [029 — Pandas: pivot tables y crosstab](029-pandas-pivot-tables-y-crosstab/README.md) +- [030 — Pandas: operaciones vectorizadas sobre strings](030-pandas-operaciones-vectorizadas-sobre-strings/README.md) +- [031 — Pandas: series de tiempo, resampling, rolling](031-pandas-series-de-tiempo-resampling-rolling/README.md) +- [032 — Pandas: eval y query](032-pandas-eval-y-query/README.md) +- [033 — Matplotlib: anatomía figura/axes](033-matplotlib-anatomia-figura-axes/README.md) +- [034 — Matplotlib: line, scatter, bar, histogram, boxplot](034-matplotlib-line-scatter-bar-histogram-boxplot/README.md) +- [035 — Matplotlib: subplots y gridspec](035-matplotlib-subplots-y-gridspec/README.md) +- [036 — Matplotlib: legends, colorbars, ticks, anotaciones](036-matplotlib-legends-colorbars-ticks-anotaciones/README.md) +- [037 — Matplotlib: stylesheets](037-matplotlib-stylesheets/README.md) +- [038 — Matplotlib: 3D plotting](038-matplotlib-3d-plotting/README.md) +- [039 — Seaborn: distribuciones, relaciones, categóricas, facetas](039-seaborn-distribuciones-relaciones-categoricas-facetas/README.md) +- [040 — Visualización geográfica (Plotly / folium)](040-visualizacion-geografica-plotly-folium/README.md) +- [041 — SQL fundamental: SELECT, WHERE, JOIN, GROUP BY, HAVING](041-sql-fundamental-select-where-join-group-by-having/README.md) +- [042 — SQL avanzado: CTEs, window functions, subqueries correlacionadas](042-sql-avanzado-ctes-window-functions-subqueries-correlacionadas/README.md) +- [043 — SQL desde Python: sqlite3, SQLAlchemy, DuckDB](043-sql-desde-python-sqlite3-sqlalchemy-duckdb/README.md) +- [044 — NoSQL: MongoDB con pymongo](044-nosql-mongodb-con-pymongo/README.md) +- [045 — APIs REST con requests](045-apis-rest-con-requests/README.md) +- [046 — Web scraping con BeautifulSoup](046-web-scraping-con-beautifulsoup/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏭️ Parte siguiente](../parte-1-machine-learning-clasico/README.md) diff --git a/classes/parte-1-machine-learning-clasico/README.md b/classes/parte-1-machine-learning-clasico/README.md new file mode 100644 index 00000000..7873c6da --- /dev/null +++ b/classes/parte-1-machine-learning-clasico/README.md @@ -0,0 +1,96 @@ +# Parte 1 — Machine Learning Clásico + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-0-prerrequisitos/README.md) · [⏭️ Parte siguiente](../parte-2-deep-learning/README.md) + +**43 clases** · ~10 semanas + +**Fuente principal:** **Géron** ([*Hands-On Machine Learning*, 3ª ed.](https://www.oreilly.com/library/view/hands-on-machine-learning/9781098125967/)) — estructura completa de los capítulos 1–9. + +--- + +## 🎯 ¿De qué trata esta parte? + +El **70 % del trabajo real de un data scientist** ocurre acá: regresión, clasificación, árboles, ensembles, reducción de dimensionalidad y clustering — sobre datos tabulares, con scikit-learn. Es la parte que más empleabilidad da, porque la mayoría de los problemas de negocio se resuelven con un Random Forest o un XGBoost bien evaluado, **no** con una red neuronal. + +El recorrido sigue *Hands-On ML* de Géron: arranca con un proyecto end-to-end (CRISP-DM) que atraviesa todo el ciclo (exploración → preparación → modelo → evaluación → tuning → deployment), y luego desmenuza cada familia de modelos con la matemática suficiente para elegir bien hiperparámetros, no solo para usar `.fit()`. Incluye una unidad fuerte de **métricas** (confusion matrix, ROC, precision/recall tradeoff) porque elegir mal la métrica es la causa #1 de modelos que "funcionan en validación y mueren en producción". + +## 🧩 Problemas que resuelve + +- Plantear un problema de ML desde cero: entender el negocio, definir métrica, dividir train/test sin leakage. +- Construir pipelines completos de preprocesamiento + modelo que se puedan serializar y reusar. +- Elegir entre regresión lineal, logística, SVM, árboles o ensembles con criterio (no por moda). +- Diagnosticar overfitting/underfitting con curvas de aprendizaje y aplicar la regularización correcta. +- Hacer hyperparameter tuning eficiente (Grid Search, Randomized Search) sin sobreajustar al test set. +- Reducir dimensionalidad para visualizar (t-SNE, UMAP) o para acelerar entrenamiento (PCA). +- Detectar anomalías en datasets sin etiquetas (Isolation Forest, LOF, One-Class SVM). + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Llevar un problema tabular nuevo desde dataset crudo hasta modelo evaluado en menos de un día de trabajo. +- Justificar por escrito por qué se eligió un modelo sobre otro (interpretabilidad, datos, métrica, latencia). +- Construir un ensemble (bagging, boosting o stacking) y explicar la mejora sobre el baseline. +- Aplicar correctamente PCA / t-SNE / UMAP para EDA y para preprocesamiento. +- Identificar y corregir las 5 causas más comunes de data leakage. + +## 🗺️ Estructura temática + +- **Fundamentos y proyecto end-to-end** — clases 047–054 — panorama del ML, desafíos, validación, proyecto completo, CRISP-DM. +- **Clasificación y métricas** — clases 055–060 — MNIST, confusion matrix, precision/recall, ROC, multiclase, análisis de errores. +- **Modelos lineales** — clases 061–067 — regresión lineal, gradient descent, polinomial, learning curves, regularización, logística. +- **SVM** — clases 068–070 — lineal, kernel, regresión. +- **Árboles** — clases 071–073 — entrenamiento, regularización, regresión. +- **Ensembles** — clases 074–080 — voting, bagging, Random Forest, feature importance, boosting (AdaBoost, GBM, XGBoost, LightGBM, CatBoost), stacking. +- **Reducción de dimensionalidad** — clases 081–084 — maldición de la dimensionalidad, PCA, LLE, MDS/Isomap/t-SNE/UMAP/LDA. +- **Clustering y detección de anomalías** — clases 085–089 — K-Means, DBSCAN, jerárquico, GMM, Isolation Forest, LOF. + +## 📚 Índice de clases (43) + +- [047 — Panorama del ML: tipos, batch vs online, instance vs model-based](047-panorama-del-ml-tipos-batch-vs-online-instance-vs-model-based/README.md) +- [048 — Desafíos del ML: overfitting, underfitting, datos insuficientes](048-desafios-del-ml-overfitting-underfitting-datos-insuficientes/README.md) +- [049 — Testing, validación, hyperparameter tuning, no free lunch theorem](049-testing-validacion-hyperparameter-tuning-no-free-lunch-theorem/README.md) +- [050 — Proyecto end-to-end: visión, datos, exploración, preparación](050-proyecto-end-to-end-vision-datos-exploracion-preparacion/README.md) +- [051 — Selección y entrenamiento de modelo](051-seleccion-y-entrenamiento-de-modelo/README.md) +- [052 — Fine-tuning (Grid Search, Randomized Search)](052-fine-tuning-grid-search-randomized-search/README.md) +- [053 — Launch, monitoreo y mantenimiento](053-launch-monitoreo-y-mantenimiento/README.md) +- [054 — CRISP-DM como framework metodológico](054-crisp-dm-como-framework-metodologico/README.md) +- [055 — Clasificación binaria con MNIST](055-clasificacion-binaria-con-mnist/README.md) +- [056 — Métricas: confusion matrix, precision, recall, F1](056-metricas-confusion-matrix-precision-recall-f1/README.md) +- [057 — Precision/recall tradeoff](057-precision-recall-tradeoff/README.md) +- [058 — Curva ROC y AUC](058-curva-roc-y-auc/README.md) +- [059 — Clasificación multiclase, multilabel, multioutput](059-clasificacion-multiclase-multilabel-multioutput/README.md) +- [060 — Análisis de errores](060-analisis-de-errores/README.md) +- [061 — Regresión lineal: ecuación normal vs Gradient Descent](061-regresion-lineal-ecuacion-normal-vs-gradient-descent/README.md) +- [062 — Gradient Descent: batch, stochastic, mini-batch](062-gradient-descent-batch-stochastic-mini-batch/README.md) +- [063 — Regresión polinomial](063-regresion-polinomial/README.md) +- [064 — Curvas de aprendizaje (bias/variance)](064-curvas-de-aprendizaje-bias-variance/README.md) +- [065 — Regularización: Ridge, Lasso, Elastic Net](065-regularizacion-ridge-lasso-elastic-net/README.md) +- [066 — Early stopping](066-early-stopping/README.md) +- [067 — Regresión logística (binaria y softmax)](067-regresion-logistica-binaria-y-softmax/README.md) +- [068 — SVM lineal](068-svm-lineal/README.md) +- [069 — SVM no lineal (kernel polinomial, RBF)](069-svm-no-lineal-kernel-polinomial-rbf/README.md) +- [070 — SVM para regresión](070-svm-para-regresion/README.md) +- [071 — Árboles de decisión: entrenamiento, visualización, CART](071-arboles-de-decision-entrenamiento-visualizacion-cart/README.md) +- [072 — Regularización de árboles](072-regularizacion-de-arboles/README.md) +- [073 — Regresión con árboles](073-regresion-con-arboles/README.md) +- [074 — Voting classifiers (hard/soft)](074-voting-classifiers-hard-soft/README.md) +- [075 — Bagging y Pasting](075-bagging-y-pasting/README.md) +- [076 — Random Forests y Extra-Trees](076-random-forests-y-extra-trees/README.md) +- [077 — Feature importance](077-feature-importance/README.md) +- [078 — Boosting: AdaBoost, Gradient Boosting](078-boosting-adaboost-gradient-boosting/README.md) +- [079 — XGBoost, LightGBM, CatBoost](079-xgboost-lightgbm-catboost/README.md) +- [080 — Stacking](080-stacking/README.md) +- [081 — Maldición de la dimensionalidad](081-maldicion-de-la-dimensionalidad/README.md) +- [082 — PCA: proyección, varianza explicada, incremental, randomized, kernel](082-pca-proyeccion-varianza-explicada-incremental-randomized-kernel/README.md) +- [083 — LLE](083-lle/README.md) +- [084 — MDS, Isomap, t-SNE, UMAP, LDA](084-mds-isomap-t-sne-umap-lda/README.md) +- [085 — Clustering K-Means (selección de k, mini-batch)](085-clustering-k-means-seleccion-de-k-mini-batch/README.md) +- [086 — DBSCAN](086-dbscan/README.md) +- [087 — Clustering: agglomerative, BIRCH, mean-shift, affinity propagation, spectral](087-clustering-agglomerative-birch-mean-shift-affinity-propagation-spectra/README.md) +- [088 — Gaussian Mixture Models](088-gaussian-mixture-models/README.md) +- [089 — Detección de anomalías: Isolation Forest, LOF, One-Class SVM](089-deteccion-de-anomalias-isolation-forest-lof-one-class-svm/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-0-prerrequisitos/README.md) · [⏭️ Parte siguiente](../parte-2-deep-learning/README.md) diff --git a/classes/parte-2-deep-learning/README.md b/classes/parte-2-deep-learning/README.md new file mode 100644 index 00000000..de146c7e --- /dev/null +++ b/classes/parte-2-deep-learning/README.md @@ -0,0 +1,110 @@ +# Parte 2 — Deep Learning — Keras, TensorFlow, Transformers, RL y Despliegue + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-1-machine-learning-clasico/README.md) · [⏭️ Parte siguiente](../parte-3-estadistica-inferencial/README.md) + +**56 clases** · ~13–14 semanas + +**Fuente principal:** **Géron** ([*Hands-On ML*, 3ª ed.](https://www.oreilly.com/library/view/hands-on-machine-learning/9781098125967/)) — capítulos 10–19, con incorporación de LLMs modernos, RAG y modelos de difusión. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte **más extensa** del programa. Cubre Deep Learning desde el perceptrón hasta los modelos generativos modernos (Transformers, LLMs, difusión) y reinforcement learning. El énfasis está en **entender qué hace cada bloque** (no solo en copiar `model.fit`): por qué BatchNorm acelera la convergencia, qué hace Adam que no hace SGD, cuándo conviene una CNN vs una ViT, por qué un Transformer dejó obsoletas a las RNN para secuencias largas. + +Está organizada en bloques: **fundamentos** (MLPs, optimización, regularización), **ingeniería con TensorFlow/Keras** (custom layers, tf.data, TFRecord), **visión por computadora** (CNNs y arquitecturas modernas), **secuencias** (RNN, LSTM, atención, Transformers, LLMs, RAG), **generativos** (autoencoders, VAE, GAN, difusión), **reinforcement learning** y **despliegue a producción** (TF Serving, Vertex AI, TF Lite, TensorFlow.js, multi-GPU). + +## 🧩 Problemas que resuelve + +- Entrenar una red neuronal desde cero (MLP) y explicar la matemática del backpropagation. +- Diagnosticar y resolver vanishing/exploding gradients con inicialización, BatchNorm y activaciones modernas. +- Hacer transfer learning con CNNs preentrenadas para visión o con LLMs para texto. +- Construir un pipeline de datos eficiente con tf.data + TFRecord para entrenar sobre datasets que no caben en RAM. +- Implementar arquitecturas modernas: ResNet, EfficientNet, ViT, BERT, GPT, modelos de difusión. +- Usar Hugging Face Transformers para tareas reales (clasificación, NER, generación, embeddings). +- Construir un sistema RAG básico sobre documentos propios. +- Desplegar un modelo entrenado a producción (TF Serving + gRPC, Vertex AI, TF Lite móvil, navegador con TF.js). + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Entrenar y serializar un modelo de visión que supere baseline en un dataset propio. +- Hacer fine-tuning de un Transformer pequeño para clasificación o generación. +- Construir un mini-RAG con embeddings + retriever + LLM sobre un corpus de ~1000 documentos. +- Servir un modelo entrenado vía API en una GPU y medir su latencia. +- Explicar el tradeoff entrenamiento/serving para CNN vs ViT vs LLM para un caso concreto. + +## 🗺️ Estructura temática + +- **Fundamentos de redes neuronales** — clases 090–095 — perceptrón, MLP, backprop, Keras (Sequential, Functional, Subclassing), Keras Tuner. +- **Entrenamiento de redes profundas** — clases 096–104 — gradientes, inicialización, activaciones, normalización, optimizadores, schedules, regularización. +- **TensorFlow avanzado** — clases 105–112 — tensores, custom layers/loops, autograph, tf.data, TFRecord, preprocessing layers, TFDS. +- **Visión por computadora** — clases 113–117 — convoluciones, pooling, arquitecturas CNN modernas, transfer learning, detección/segmentación. +- **Secuencias y NLP** — clases 118–129 — RNN, LSTM, GRU, 1D CNN, char-RNN, sentimiento, encoder-decoder, atención, Transformers, BERT/GPT, Hugging Face, LLMs, RAG. +- **Modelos generativos** — clases 130–133 — autoencoders, VAE, GAN, difusión. +- **Reinforcement Learning** — clases 134–138 — Gymnasium, policy gradients, MDPs, Q-learning, DQN, PPO/SAC. +- **Despliegue y escala** — clases 139–145 — TF Serving, Vertex AI, TF Lite, TensorFlow.js, GPU, tf.distribute, entrenamiento a escala. + +## 📚 Índice de clases (56) + +- [090 — Perceptrón, MLP y backpropagation](090-perceptron-mlp-y-backpropagation/README.md) +- [091 — Regresión y clasificación con MLP](091-regresion-y-clasificacion-con-mlp/README.md) +- [092 — Keras Sequential API](092-keras-sequential-api/README.md) +- [093 — Keras Functional API y Subclassing](093-keras-functional-api-y-subclassing/README.md) +- [094 — Callbacks, TensorBoard, guardar/restaurar modelos](094-callbacks-tensorboard-guardar-restaurar-modelos/README.md) +- [095 — Keras Tuner](095-keras-tuner/README.md) +- [096 — Vanishing/exploding gradients](096-vanishing-exploding-gradients/README.md) +- [097 — Inicialización (Glorot, He)](097-inicializacion-glorot-he/README.md) +- [098 — Activaciones: ReLU, ELU, GELU, Swish, Mish](098-activaciones-relu-elu-gelu-swish-mish/README.md) +- [099 — Batch Normalization, Layer Normalization](099-batch-normalization-layer-normalization/README.md) +- [100 — Gradient clipping](100-gradient-clipping/README.md) +- [101 — Transfer learning, unsupervised pretraining](101-transfer-learning-unsupervised-pretraining/README.md) +- [102 — Optimizadores: Momentum, Nesterov, AdaGrad, RMSProp, Adam, AdamW](102-optimizadores-momentum-nesterov-adagrad-rmsprop-adam-adamw/README.md) +- [103 — Learning rate scheduling](103-learning-rate-scheduling/README.md) +- [104 — Regularización: L1/L2, dropout, max-norm, MC dropout](104-regularizacion-l1-l2-dropout-max-norm-mc-dropout/README.md) +- [105 — TensorFlow: tensores, variables, operaciones](105-tensorflow-tensores-variables-operaciones/README.md) +- [106 — Losses, métricas, capas, modelos custom](106-losses-metricas-capas-modelos-custom/README.md) +- [107 — Funciones y grafos (autograph)](107-funciones-y-grafos-autograph/README.md) +- [108 — Custom training loops](108-custom-training-loops/README.md) +- [109 — tf.data API](109-tf-data-api/README.md) +- [110 — TFRecord](110-tfrecord/README.md) +- [111 — Keras preprocessing layers](111-keras-preprocessing-layers/README.md) +- [112 — TensorFlow Datasets (TFDS)](112-tensorflow-datasets-tfds/README.md) +- [113 — Capas convolucionales, filtros, feature maps](113-capas-convolucionales-filtros-feature-maps/README.md) +- [114 — Pooling](114-pooling/README.md) +- [115 — Arquitecturas CNN: LeNet, AlexNet, VGG, GoogLeNet, ResNet, Xception, SENet, EfficientNet](115-arquitecturas-cnn-lenet-alexnet-vgg-googlenet-resnet-xception-senet-ef/README.md) +- [116 — Transfer learning con CNNs preentrenadas](116-transfer-learning-con-cnns-preentrenadas/README.md) +- [117 — Localización, detección (YOLO, Faster R-CNN), segmentación semántica](117-localizacion-deteccion-yolo-faster-r-cnn-segmentacion-semantica/README.md) +- [118 — RNNs: neuronas recurrentes, BPTT](118-rnns-neuronas-recurrentes-bptt/README.md) +- [119 — Forecasting de series con RNN](119-forecasting-de-series-con-rnn/README.md) +- [120 — LSTM, GRU](120-lstm-gru/README.md) +- [121 — 1D CNNs y WaveNet](121-1d-cnns-y-wavenet/README.md) +- [122 — Generación de texto char-RNN](122-generacion-de-texto-char-rnn/README.md) +- [123 — Análisis de sentimiento](123-analisis-de-sentimiento/README.md) +- [124 — Encoder-Decoder para traducción](124-encoder-decoder-para-traduccion/README.md) +- [125 — Mecanismos de atención](125-mecanismos-de-atencion/README.md) +- [126 — Transformers: arquitectura, BERT, GPT](126-transformers-arquitectura-bert-gpt/README.md) +- [127 — Hugging Face Transformers (uso práctico)](127-hugging-face-transformers-uso-practico/README.md) +- [128 — LLMs aplicados: fine-tuning, prompting](128-llms-aplicados-fine-tuning-prompting/README.md) +- [129 — RAG básico y embeddings](129-rag-basico-y-embeddings/README.md) +- [130 — Autoencoders: undercomplete, stacked, denoising, sparse](130-autoencoders-undercomplete-stacked-denoising-sparse/README.md) +- [131 — Variational Autoencoders (VAE)](131-variational-autoencoders-vae/README.md) +- [132 — GANs: DCGAN, Progressive GAN, StyleGAN](132-gans-dcgan-progressive-gan-stylegan/README.md) +- [133 — Modelos de difusión (DDPM, score-based)](133-modelos-de-difusion-ddpm-score-based/README.md) +- [134 — RL: aprendizaje por recompensa, OpenAI Gymnasium](134-rl-aprendizaje-por-recompensa-openai-gymnasium/README.md) +- [135 — Policy gradients](135-policy-gradients/README.md) +- [136 — Markov Decision Processes](136-markov-decision-processes/README.md) +- [137 — TD Learning, Q-Learning, Deep Q-Networks](137-td-learning-q-learning-deep-q-networks/README.md) +- [138 — RL moderno: A3C, PPO, SAC (vista general)](138-rl-moderno-a3c-ppo-sac-vista-general/README.md) +- [139 — TF Serving + gRPC](139-tf-serving-grpc/README.md) +- [140 — Despliegue en Vertex AI](140-despliegue-en-vertex-ai/README.md) +- [141 — TF Lite (mobile/embedded)](141-tf-lite-mobile-embedded/README.md) +- [142 — TensorFlow.js (navegador)](142-tensorflow-js-navegador/README.md) +- [143 — Aceleración con GPU](143-aceleracion-con-gpu/README.md) +- [144 — Entrenamiento multi-dispositivo, tf.distribute](144-entrenamiento-multi-dispositivo-tf-distribute/README.md) +- [145 — Entrenamiento a escala con Vertex AI](145-entrenamiento-a-escala-con-vertex-ai/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-1-machine-learning-clasico/README.md) · [⏭️ Parte siguiente](../parte-3-estadistica-inferencial/README.md) diff --git a/classes/parte-3-estadistica-inferencial/README.md b/classes/parte-3-estadistica-inferencial/README.md new file mode 100644 index 00000000..c9ddc41f --- /dev/null +++ b/classes/parte-3-estadistica-inferencial/README.md @@ -0,0 +1,61 @@ +# Parte 3 — Estadística Inferencial y Causal + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-2-deep-learning/README.md) · [⏭️ Parte siguiente](../parte-4-mlops/README.md) + +**13 clases** · ~4 semanas (puede intercalarse con Parte 1) + +**Fuente principal:** **ISLP** ([*Statistical Learning with Python*](https://www.statlearning.com/)) — rigor matemático en tests, intervalos y diseño experimental. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte que separa al data scientist del "sklearn user". Cubre **inferencia estadística** (tests, intervalos, bootstrap), **diseño de experimentos** (A/B testing real, no solo `p < 0.05`) e **inferencia causal** (DAGs, confounders, instrumentos, DiD, uplift) — herramientas que se usan a diario para responder preguntas tipo "¿esto que cambiamos en el producto realmente movió la métrica?" o "¿este coeficiente significa lo que creo que significa?". + +Se intercala bien con la Parte 1 porque la mayoría de los problemas de evaluación de modelos (comparar dos clasificadores, decidir si una mejora es real) son problemas estadísticos disfrazados. Incluye una introducción a estadística bayesiana con PyMC para abrir la puerta a inferencia con incertidumbre explícita. + +## 🧩 Problemas que resuelve + +- Decidir si una diferencia observada es estadísticamente significativa o ruido. +- Diseñar un A/B test con tamaño de muestra y poder estadístico correctos, no a ojo. +- Aplicar el test correcto según los supuestos del dato (paramétrico vs no paramétrico, pareado vs independiente). +- Corregir comparaciones múltiples (Bonferroni, FDR) para no inflar el falso positivo. +- Estimar incertidumbre con bootstrap cuando los supuestos clásicos no aplican. +- Identificar confounders en un DAG y elegir la estrategia causal correcta (control, IV, DiD, uplift). +- Hacer una inferencia bayesiana básica con MCMC en PyMC. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Diseñar y analizar un A/B test end-to-end, incluyendo poder estadístico y corrección por múltiples métricas. +- Aplicar bootstrap para construir intervalos de confianza no paramétricos sobre cualquier estimador. +- Dibujar el DAG de un problema de negocio y justificar qué variables controlar. +- Implementar un modelo bayesiano simple en PyMC e interpretar el posterior. + +## 🗺️ Estructura temática + +- **Tests clásicos** — clases 146–151 — distribuciones, t-test, chi-cuadrado, ANOVA, no paramétricos, comparaciones múltiples. +- **Estimación e incertidumbre** — clases 152–153 — intervalos de confianza, bootstrap, permutation tests. +- **Experimentación y causalidad** — clases 154–157 — A/B testing, diseño experimental, inferencia causal con DAGs, uplift / DiD. +- **Inferencia bayesiana** — clase 158 — priors, posterior, MCMC con PyMC. + +## 📚 Índice de clases (13) + +- [146 — Distribuciones: normal, binomial, Poisson, exponencial](146-distribuciones-normal-binomial-poisson-exponencial/README.md) +- [147 — Test t (una muestra, dos muestras, pareado)](147-test-t-una-muestra-dos-muestras-pareado/README.md) +- [148 — Test chi-cuadrado de independencia y bondad de ajuste](148-test-chi-cuadrado-de-independencia-y-bondad-de-ajuste/README.md) +- [149 — ANOVA (one-way, two-way)](149-anova-one-way-two-way/README.md) +- [150 — Tests no paramétricos: Mann-Whitney, Wilcoxon, Kruskal-Wallis](150-tests-no-parametricos-mann-whitney-wilcoxon-kruskal-wallis/README.md) +- [151 — Corrección de comparaciones múltiples (Bonferroni, FDR)](151-correccion-de-comparaciones-multiples-bonferroni-fdr/README.md) +- [152 — Intervalos de confianza](152-intervalos-de-confianza/README.md) +- [153 — Bootstrap y permutation tests](153-bootstrap-y-permutation-tests/README.md) +- [154 — A/B testing: tamaño de muestra, poder estadístico](154-a-b-testing-tamano-de-muestra-poder-estadistico/README.md) +- [155 — Diseño experimental](155-diseno-experimental/README.md) +- [156 — Inferencia causal: DAGs, confounders, instrumentos](156-inferencia-causal-dags-confounders-instrumentos/README.md) +- [157 — Uplift modeling, DiD (difference-in-differences)](157-uplift-modeling-did-difference-in-differences/README.md) +- [158 — Bayes intro: priors, posterior, MCMC con PyMC](158-bayes-intro-priors-posterior-mcmc-con-pymc/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-2-deep-learning/README.md) · [⏭️ Parte siguiente](../parte-4-mlops/README.md) diff --git a/classes/parte-4-mlops/README.md b/classes/parte-4-mlops/README.md new file mode 100644 index 00000000..f2b9e880 --- /dev/null +++ b/classes/parte-4-mlops/README.md @@ -0,0 +1,63 @@ +# Parte 4 — MLOps — Modelos en Producción + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-3-estadistica-inferencial/README.md) · [⏭️ Parte siguiente](../parte-5-ingenieria-de-datos/README.md) + +**14 clases** · ~4–5 semanas + +**Fuente principal:** **Huyen** ([*Designing Machine Learning Systems*](https://www.oreilly.com/library/view/designing-machine-learning/9781098107956/)) — el manual de cabecera para MLOps moderno. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte que convierte un notebook que entrena bien en un **sistema que funciona en producción 24/7**. Cubre versionado (de datos, modelos y experimentos), packaging (Docker), serving (FastAPI, Kubernetes, serverless), monitoreo (data drift, model drift) y los rituales que evitan que el modelo se degrade silenciosamente (reentrenamiento programado, shadow deployment, canary releases). + +Incluye una unidad fuerte de **interpretabilidad** (SHAP, LIME, PDP, ICE) porque ningún modelo va a producción sin alguien preguntando "¿por qué dijo eso?", y otra de **testing** (datos con Great Expectations, modelos con tests de invariancia) porque en ML el bug habitual no es un crash sino un drift silencioso. + +## 🧩 Problemas que resuelve + +- Versionar datasets pesados con DVC y modelos/experimentos con MLflow. +- Empaquetar un modelo entrenado en un contenedor Docker reproducible. +- Servir el modelo como API (FastAPI) y escalar con Kubernetes o serverless. +- Detectar data drift y model drift antes de que el negocio reclame. +- Hacer despliegues seguros (shadow, canary) para evitar romper producción. +- Explicar predicciones individuales y globales con SHAP / LIME / PDP / ICE. +- Validar entradas con Great Expectations antes de que lleguen al modelo. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Tomar un modelo entrenado y publicarlo como API monitoreada en producción en menos de un día. +- Diseñar un pipeline CI/CD que reentrene y redesplíegue automáticamente cuando llega data nueva. +- Configurar alertas de drift que avisen *antes* de que la métrica de negocio caiga. +- Generar un reporte de interpretabilidad para stakeholders no técnicos. + +## 🗺️ Estructura temática + +- **Versionado** — clases 159–161 — DVC para datos, MLflow para modelos/experimentos, Feast como feature store. +- **CI/CD y packaging** — clases 162–164 — GitHub Actions para ML, Docker, FastAPI. +- **Escala y serving** — clases 165–166 — Kubernetes, serverless (AWS Lambda / GCP Functions). +- **Monitoreo y operación** — clases 167–169 — data/model drift, reentrenamiento programado, shadow/canary. +- **Interpretabilidad y testing** — clases 170–172 — SHAP/LIME/PDP/ICE, testing de datos, testing de modelos. + +## 📚 Índice de clases (14) + +- [159 — Versionado de datos con DVC](159-versionado-de-datos-con-dvc/README.md) +- [160 — Versionado de modelos y experimentos con MLflow](160-versionado-de-modelos-y-experimentos-con-mlflow/README.md) +- [161 — Feature stores (Feast)](161-feature-stores-feast/README.md) +- [162 — CI/CD para ML con GitHub Actions](162-ci-cd-para-ml-con-github-actions/README.md) +- [163 — Docker para empaquetar modelos](163-docker-para-empaquetar-modelos/README.md) +- [164 — APIs con FastAPI sirviendo modelos](164-apis-con-fastapi-sirviendo-modelos/README.md) +- [165 — Kubernetes para servir modelos a escala](165-kubernetes-para-servir-modelos-a-escala/README.md) +- [166 — Serverless ML: AWS Lambda, GCP Cloud Functions](166-serverless-ml-aws-lambda-gcp-cloud-functions/README.md) +- [167 — Monitoreo: data drift, model drift, alertas](167-monitoreo-data-drift-model-drift-alertas/README.md) +- [168 — Reentrenamiento programado](168-reentrenamiento-programado/README.md) +- [169 — Shadow deployment y canary releases](169-shadow-deployment-y-canary-releases/README.md) +- [170 — Interpretabilidad: SHAP, LIME, PDP, ICE](170-interpretabilidad-shap-lime-pdp-ice/README.md) +- [171 — Testing de datos: Great Expectations, Deequ](171-testing-de-datos-great-expectations-deequ/README.md) +- [172 — Testing de modelos: invariance, behavioral tests](172-testing-de-modelos-invariance-behavioral-tests/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-3-estadistica-inferencial/README.md) · [⏭️ Parte siguiente](../parte-5-ingenieria-de-datos/README.md) diff --git a/classes/parte-5-ingenieria-de-datos/README.md b/classes/parte-5-ingenieria-de-datos/README.md new file mode 100644 index 00000000..6bd281b3 --- /dev/null +++ b/classes/parte-5-ingenieria-de-datos/README.md @@ -0,0 +1,54 @@ +# Parte 5 — Ingeniería de Datos + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-4-mlops/README.md) · [⏭️ Parte siguiente](../parte-6-sistemas-de-recomendacion/README.md) + +**8 clases** · ~3 semanas + +**Fuente principal:** Complementaria — fundamentos prácticos de data engineering necesarios para alimentar pipelines de ML a escala. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte que enseña a **mover y transformar datos a escala**, más allá de lo que pandas aguanta. Cubre orquestación (Airflow, Prefect, Dagster), procesamiento distribuido (PySpark, Polars), almacenamiento analítico (BigQuery, Snowflake, DuckDB), streaming (Kafka, Kinesis), formatos columnares (Parquet, Avro) y modelado dimensional (star/snowflake schemas). + +Es la parte donde el data scientist deja de pedirle datos al equipo de data engineering y empieza a moverlos él mismo cuando es necesario. No reemplaza a un data engineer senior, pero sí cubre el 80 % de los casos donde el bottleneck era "esto no cabe en memoria" o "este pipeline corre 8 horas y falla a la mitad". + +## 🧩 Problemas que resuelve + +- Orquestar un pipeline de N pasos con dependencias, retries y observabilidad. +- Procesar datasets de TBs con PySpark o de GBs con Polars sin cargarlos en RAM. +- Consultar un data warehouse moderno (BigQuery, Snowflake, DuckDB local) desde Python. +- Consumir un stream de eventos en tiempo real (Kafka / Kinesis). +- Elegir el formato de almacenamiento correcto (Parquet vs Avro vs CSV) según el patrón de lectura. +- Diseñar un modelo dimensional (star schema) para BI y para features de ML. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Convertir un script `pandas` que tomaba horas en un pipeline Airflow/Prefect con Polars o PySpark. +- Migrar un workflow desde CSV a Parquet y medir la mejora en tiempo y espacio. +- Diseñar un star schema para un caso de negocio dado. + +## 🗺️ Estructura temática + +- **Orquestación** — clases 173–174 — Airflow, Prefect, Dagster. +- **Procesamiento distribuido y moderno** — clases 175–176 — PySpark, Polars. +- **Data warehouses y streaming** — clases 177–178 — BigQuery / Snowflake / DuckDB, Kafka / Kinesis. +- **Formatos y modelado** — clases 179–180 — Parquet/Avro, modelado dimensional. + +## 📚 Índice de clases (8) + +- [173 — Pipelines ETL/ELT con Airflow](173-pipelines-etl-elt-con-airflow/README.md) +- [174 — Pipelines con Prefect o Dagster](174-pipelines-con-prefect-o-dagster/README.md) +- [175 — PySpark para datasets grandes](175-pyspark-para-datasets-grandes/README.md) +- [176 — Polars como alternativa moderna](176-polars-como-alternativa-moderna/README.md) +- [177 — Data warehouses: BigQuery, Snowflake, DuckDB](177-data-warehouses-bigquery-snowflake-duckdb/README.md) +- [178 — Streaming intro: Kafka, Kinesis](178-streaming-intro-kafka-kinesis/README.md) +- [179 — Formatos columnares: Parquet, Avro](179-formatos-columnares-parquet-avro/README.md) +- [180 — Modelado dimensional (star/snowflake schemas)](180-modelado-dimensional-star-snowflake-schemas/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-4-mlops/README.md) · [⏭️ Parte siguiente](../parte-6-sistemas-de-recomendacion/README.md) diff --git a/classes/parte-6-sistemas-de-recomendacion/README.md b/classes/parte-6-sistemas-de-recomendacion/README.md new file mode 100644 index 00000000..b9670290 --- /dev/null +++ b/classes/parte-6-sistemas-de-recomendacion/README.md @@ -0,0 +1,52 @@ +# Parte 6 — Sistemas de Recomendación + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-5-ingenieria-de-datos/README.md) · [⏭️ Parte siguiente](../parte-7-etica-fairness-privacidad/README.md) + +**7 clases** · ~2–3 semanas + +**Fuente principal:** Complementaria — combinación de filtrado colaborativo clásico y enfoques modernos basados en embeddings. + +--- + +## 🎯 ¿De qué trata esta parte? + +Una unidad especializada en una de las aplicaciones de ML con más impacto comercial directo: **recomendar el siguiente producto, video, canción o contenido**. Cubre los dos enfoques clásicos (filtrado colaborativo y content-based), su unión en sistemas **híbridos**, y la matemática detrás (factorización de matrices: SVD, ALS). + +También cubre las **métricas correctas** (MAP@k, NDCG, recall@k — no accuracy) y el problema del **cold-start** (usuarios o items nuevos sin historial), que es donde mueren la mayoría de los recomendadores en su primer mes en producción. Termina con un tour por las librerías que se usan en la práctica (LightFM, Implicit, Surprise). + +## 🧩 Problemas que resuelve + +- Construir un recomendador user-based o item-based desde una matriz usuario-item dispersa. +- Aplicar factorización de matrices (SVD / ALS) para llegar a recomendaciones escalables. +- Combinar señales colaborativas y de contenido en un recomendador híbrido. +- Evaluar un recomendador con la métrica correcta (no con accuracy ni RMSE de rating). +- Mitigar el cold-start con estrategias basadas en contenido o popularidad. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Entrenar y evaluar un recomendador end-to-end con LightFM o Implicit sobre un dataset real (MovieLens o similar). +- Reportar la calidad del recomendador con MAP@k y NDCG, no con accuracy. +- Diseñar una estrategia explícita para usuarios y items nuevos. + +## 🗺️ Estructura temática + +- **Filtrado colaborativo** — clases 181–182 — user-based, item-based, factorización de matrices (SVD, ALS). +- **Content-based e híbridos** — clases 183–184 — content-based, recomendadores híbridos. +- **Evaluación y cold-start** — clases 185–186 — métricas MAP@k / NDCG / recall@k, cold-start problem. +- **Tooling** — clase 187 — LightFM, Implicit, Surprise. + +## 📚 Índice de clases (7) + +- [181 — Filtrado colaborativo user-based e item-based](181-filtrado-colaborativo-user-based-e-item-based/README.md) +- [182 — Factorización de matrices: SVD, ALS](182-factorizacion-de-matrices-svd-als/README.md) +- [183 — Content-based filtering](183-content-based-filtering/README.md) +- [184 — Recomendadores híbridos](184-recomendadores-hibridos/README.md) +- [185 — Métricas: MAP@k, NDCG, recall@k](185-metricas-map-k-ndcg-recall-k/README.md) +- [186 — Cold-start problem](186-cold-start-problem/README.md) +- [187 — Librerías: LightFM, Implicit, Surprise](187-librerias-lightfm-implicit-surprise/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-5-ingenieria-de-datos/README.md) · [⏭️ Parte siguiente](../parte-7-etica-fairness-privacidad/README.md) diff --git a/classes/parte-7-etica-fairness-privacidad/README.md b/classes/parte-7-etica-fairness-privacidad/README.md new file mode 100644 index 00000000..ab4f6203 --- /dev/null +++ b/classes/parte-7-etica-fairness-privacidad/README.md @@ -0,0 +1,51 @@ +# Parte 7 — Ética, Fairness y Privacidad + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-6-sistemas-de-recomendacion/README.md) · [⏭️ Parte siguiente](../parte-8-capstones/README.md) + +**6 clases** · ~2 semanas + +**Fuente principal:** **Barocas / Hardt / Narayanan** ([*Fairness and Machine Learning*](https://fairmlbook.org/)) — el texto de referencia académico para fairness algorítmica. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte que ningún currículo serio puede omitir en 2026: cómo construir sistemas de ML que **no discriminen, no filtren datos personales y sean reproducibles**. Cubre los tipos y orígenes del sesgo algorítmico, las **métricas formales de fairness** (demographic parity, equalized odds, calibration — y por qué son matemáticamente incompatibles entre sí), técnicas modernas como **privacidad diferencial** y **federated learning**, y el marco regulatorio actual (GDPR, AI Act europeo). + +Cierra con una clase sobre **reproducibilidad** (seeds, lock files, versionado de datasets) que es prerrequisito de cualquier discusión seria sobre fairness: si no se puede reproducir, no se puede auditar. + +## 🧩 Problemas que resuelve + +- Identificar los tipos y fuentes de sesgo en un dataset y en un modelo entrenado. +- Medir fairness con las métricas correctas y explicar por qué no se pueden cumplir todas a la vez. +- Aplicar privacidad diferencial básica para publicar estadísticas sin filtrar individuos. +- Entender cuándo federated learning es la solución correcta (y cuándo es overkill). +- Cumplir requisitos básicos de GDPR y AI Act en un proyecto de ML. +- Hacer un experimento reproducible bit-a-bit. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Auditar un modelo clasificador por demographic parity y equalized odds, y reportar trade-offs. +- Documentar un dataset y un modelo con un datasheet / model card. +- Producir un experimento que cualquiera puede reproducir desde el repo en menos de 30 minutos. + +## 🗺️ Estructura temática + +- **Sesgo y fairness** — clases 188–189 — tipos de sesgo, métricas de fairness. +- **Privacidad** — clases 190–191 — privacidad diferencial, federated learning. +- **Regulación y reproducibilidad** — clases 192–193 — GDPR / AI Act, reproducibilidad práctica. + +## 📚 Índice de clases (6) + +- [188 — Tipos de sesgo algorítmico y orígenes](188-tipos-de-sesgo-algoritmico-y-origenes/README.md) +- [189 — Métricas de fairness: demographic parity, equalized odds, calibration](189-metricas-de-fairness-demographic-parity-equalized-odds-calibration/README.md) +- [190 — Privacidad diferencial (intro)](190-privacidad-diferencial-intro/README.md) +- [191 — Federated learning (intro)](191-federated-learning-intro/README.md) +- [192 — GDPR y AI Act (EU)](192-gdpr-y-ai-act-eu/README.md) +- [193 — Reproducibilidad: seeds, lock files, versionado de datasets](193-reproducibilidad-seeds-lock-files-versionado-de-datasets/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-6-sistemas-de-recomendacion/README.md) · [⏭️ Parte siguiente](../parte-8-capstones/README.md) diff --git a/classes/parte-8-capstones/README.md b/classes/parte-8-capstones/README.md new file mode 100644 index 00000000..9cdab42b --- /dev/null +++ b/classes/parte-8-capstones/README.md @@ -0,0 +1,48 @@ +# Parte 8 — Capstones — Proyectos Integradores + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-7-etica-fairness-privacidad/README.md) + +**4 clases** · proyectos largos · ~4–6 semanas + +**Fuente principal:** Síntesis — el estudiante demuestra dominio integrando todo lo aprendido en tres proyectos completos y un portafolio público. + +--- + +## 🎯 ¿De qué trata esta parte? + +La parte final del programa, donde no se aprende contenido nuevo: se **integra todo** en tres proyectos end-to-end y un portafolio público en GitHub Pages. Cada capstone cubre un dominio distinto (tabular, NLP/series, visión) para forzar al estudiante a demostrar versatilidad, y todos los proyectos deben llegar hasta el **deployment** (API, dashboard, app) — no se aceptan notebooks aislados. + +El capstone final (la "clase 197") no es código sino **comunicación**: armar un portafolio público navegable, una presentación de 10 minutos por proyecto y un README técnico que un reclutador o colega pueda entender. Es el entregable que se usa para buscar trabajo o para evaluar el programa entero. + +## 🧩 Problemas que resuelve + +- Demostrar que se puede llevar un problema desde dataset crudo hasta sistema en producción sin asistencia. +- Integrar las tres partes técnicas duras del programa: ML clásico (P1), DL (P2) y MLOps (P4). +- Comunicar resultados técnicos a audiencias no técnicas. +- Construir un portafolio público creíble para postular a trabajos de data scientist / ML engineer. + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +- Tres proyectos completos publicados en GitHub con README, demo desplegada y documentación reproducible. +- Un portafolio público en GitHub Pages que sirva como CV técnico. +- Tres presentaciones de 10 minutos (una por capstone) listas para entrevistas. + +## 🗺️ Estructura temática + +- **Capstone 1 — Tabular** — clase 194 — problema tabular end-to-end (EDA, modelo, API, dashboard). +- **Capstone 2 — NLP o series** — clase 195 — NLP o time-series end-to-end. +- **Capstone 3 — Visión** — clase 196 — visión por computadora con transfer learning. +- **Portafolio público** — clase 197 — GitHub Pages, presentación, README técnico. + +## 📚 Índice de clases (4) + +- [194 — Capstone 1: problema tabular end-to-end (EDA, modelo, API, dashboard)](194-capstone-1-problema-tabular-end-to-end-eda-modelo-api-dashboard/README.md) +- [195 — Capstone 2: NLP o series de tiempo end-to-end](195-capstone-2-nlp-o-series-de-tiempo-end-to-end/README.md) +- [196 — Capstone 3: visión por computadora con transfer learning](196-capstone-3-vision-por-computadora-con-transfer-learning/README.md) +- [197 — Portafolio público en GitHub Pages y presentación](197-portafolio-publico-en-github-pages-y-presentacion/README.md) + +--- + +> [⬅️ Volver al programa](../../README.md) · [📚 Índice completo](../README.md) · [⏮️ Parte anterior](../parte-7-etica-fairness-privacidad/README.md) diff --git a/scripts/generate_part_readmes.py b/scripts/generate_part_readmes.py new file mode 100644 index 00000000..e0b17c4e --- /dev/null +++ b/scripts/generate_part_readmes.py @@ -0,0 +1,479 @@ +"""Genera README.md raíz para cada parte del currículo. + +Cada README contiene: +- Narrativa rica (de qué trata, qué problemas resuelve, resultados de aprendizaje) +- Estructura temática de la parte +- Índice completo de clases con links +- Navegación de regreso al programa y entre partes +""" + +from __future__ import annotations + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +CLASSES = ROOT / "classes" + +# Metadata por parte: título visible, fuente, narrativa. +PARTS = { + "parte-0-prerrequisitos": { + "num": 0, + "titulo": "Prerrequisitos: Python + NumPy + pandas + visualización + SQL + APIs", + "fuente": "**VanderPlas** ([*Python Data Science Handbook*](https://jakevdp.github.io/PythonDataScienceHandbook/)) — secuencia y énfasis en NumPy, pandas y matplotlib.", + "duracion_estimada": "~10–12 semanas a ritmo moderado", + "trata": ( + "Esta parte construye **toda la base técnica** que el resto del programa da por sentada. " + "No es \"introducción a Python\" — es el conjunto mínimo de herramientas con las que un data " + "scientist trabaja a diario: el lenguaje, los entornos reproducibles, el control de versiones, " + "el stack numérico (NumPy / pandas), la visualización (matplotlib / seaborn / plotly), " + "el acceso a datos (SQL, NoSQL, APIs, scraping) y la disciplina de proyecto (logging, " + "type hints, manejo de errores, estructura cookiecutter).\n\n" + "El recorrido es deliberadamente extenso porque cada laguna acá se convierte en deuda invisible " + "que aparece después en Parte 1 (ML clásico) y Parte 2 (Deep Learning). Quien complete bien " + "esta parte puede leer cualquier notebook profesional, reproducirlo, modificarlo y debuggearlo." + ), + "resuelve": [ + "Configurar un entorno Python aislado y reproducible (venv / uv / conda) sin colisiones de dependencias.", + "Manipular datasets tabulares de tamaño medio (cientos de miles de filas) sin caer en bucles ni código lento.", + "Limpiar, transformar y unir datos sucios usando pandas (faltantes, tipos, formatos, joins, groupby).", + "Producir gráficos publicables (no solo `df.plot()`) con matplotlib + seaborn, incluyendo mapas geográficos.", + "Consultar bases relacionales con SQL avanzado (CTEs, window functions) y conectarlas desde Python.", + "Acceder a datos externos vía APIs REST y, cuando no hay API, mediante web scraping responsable.", + ], + "resultados": [ + "Levantar un proyecto nuevo con estructura reproducible, dependencias fijadas y `pre-commit` en menos de 10 minutos.", + "Escribir código NumPy/pandas vectorizado (sin loops) y justificar por qué es más rápido.", + "Diseñar visualizaciones efectivas que comuniquen una conclusión, no solo \"que se vean lindas\".", + "Escribir consultas SQL no triviales (window functions, CTEs recursivas) y traducirlas a pandas y viceversa.", + "Extraer datos de una API o sitio web y dejarlos listos para análisis, manejando paginación y rate-limiting.", + ], + "estructura": [ + ("Setup y reproducibilidad", "clases 001–005 — instalación, Jupyter, Git/GitHub, estructura de proyecto, editor."), + ("Python para data science", "clases 006–013 — tipos, comprehensions, funciones, OOP, pathlib, logging, type hints."), + ("NumPy (8 clases)", "clases 014–021 — creación, ufuncs, agregaciones, broadcasting, masks, álgebra lineal, aleatoriedad."), + ("pandas (11 clases)", "clases 022–032 — Series/DataFrame, indexación, joins, groupby, pivot, strings, series de tiempo."), + ("Visualización", "clases 033–040 — matplotlib en profundidad, seaborn, visualización geográfica."), + ("SQL", "clases 041–043 — desde fundamentos a window functions y conexión desde Python."), + ("Acceso a datos externos", "clases 044–046 — MongoDB, APIs REST, web scraping con BeautifulSoup."), + ], + "prev": None, + "next": "parte-1-machine-learning-clasico", + }, + "parte-1-machine-learning-clasico": { + "num": 1, + "titulo": "Machine Learning Clásico", + "fuente": "**Géron** ([*Hands-On Machine Learning*, 3ª ed.](https://www.oreilly.com/library/view/hands-on-machine-learning/9781098125967/)) — estructura completa de los capítulos 1–9.", + "duracion_estimada": "~10 semanas", + "trata": ( + "El **70 % del trabajo real de un data scientist** ocurre acá: regresión, clasificación, árboles, " + "ensembles, reducción de dimensionalidad y clustering — sobre datos tabulares, con scikit-learn. " + "Es la parte que más empleabilidad da, porque la mayoría de los problemas de negocio se resuelven " + "con un Random Forest o un XGBoost bien evaluado, **no** con una red neuronal.\n\n" + "El recorrido sigue *Hands-On ML* de Géron: arranca con un proyecto end-to-end (CRISP-DM) que " + "atraviesa todo el ciclo (exploración → preparación → modelo → evaluación → tuning → " + "deployment), y luego desmenuza cada familia de modelos con la matemática suficiente para " + "elegir bien hiperparámetros, no solo para usar `.fit()`. Incluye una unidad fuerte de " + "**métricas** (confusion matrix, ROC, precision/recall tradeoff) porque elegir mal la métrica " + "es la causa #1 de modelos que \"funcionan en validación y mueren en producción\"." + ), + "resuelve": [ + "Plantear un problema de ML desde cero: entender el negocio, definir métrica, dividir train/test sin leakage.", + "Construir pipelines completos de preprocesamiento + modelo que se puedan serializar y reusar.", + "Elegir entre regresión lineal, logística, SVM, árboles o ensembles con criterio (no por moda).", + "Diagnosticar overfitting/underfitting con curvas de aprendizaje y aplicar la regularización correcta.", + "Hacer hyperparameter tuning eficiente (Grid Search, Randomized Search) sin sobreajustar al test set.", + "Reducir dimensionalidad para visualizar (t-SNE, UMAP) o para acelerar entrenamiento (PCA).", + "Detectar anomalías en datasets sin etiquetas (Isolation Forest, LOF, One-Class SVM).", + ], + "resultados": [ + "Llevar un problema tabular nuevo desde dataset crudo hasta modelo evaluado en menos de un día de trabajo.", + "Justificar por escrito por qué se eligió un modelo sobre otro (interpretabilidad, datos, métrica, latencia).", + "Construir un ensemble (bagging, boosting o stacking) y explicar la mejora sobre el baseline.", + "Aplicar correctamente PCA / t-SNE / UMAP para EDA y para preprocesamiento.", + "Identificar y corregir las 5 causas más comunes de data leakage.", + ], + "estructura": [ + ("Fundamentos y proyecto end-to-end", "clases 047–054 — panorama del ML, desafíos, validación, proyecto completo, CRISP-DM."), + ("Clasificación y métricas", "clases 055–060 — MNIST, confusion matrix, precision/recall, ROC, multiclase, análisis de errores."), + ("Modelos lineales", "clases 061–067 — regresión lineal, gradient descent, polinomial, learning curves, regularización, logística."), + ("SVM", "clases 068–070 — lineal, kernel, regresión."), + ("Árboles", "clases 071–073 — entrenamiento, regularización, regresión."), + ("Ensembles", "clases 074–080 — voting, bagging, Random Forest, feature importance, boosting (AdaBoost, GBM, XGBoost, LightGBM, CatBoost), stacking."), + ("Reducción de dimensionalidad", "clases 081–084 — maldición de la dimensionalidad, PCA, LLE, MDS/Isomap/t-SNE/UMAP/LDA."), + ("Clustering y detección de anomalías", "clases 085–089 — K-Means, DBSCAN, jerárquico, GMM, Isolation Forest, LOF."), + ], + "prev": "parte-0-prerrequisitos", + "next": "parte-2-deep-learning", + }, + "parte-2-deep-learning": { + "num": 2, + "titulo": "Deep Learning — Keras, TensorFlow, Transformers, RL y Despliegue", + "fuente": "**Géron** ([*Hands-On ML*, 3ª ed.](https://www.oreilly.com/library/view/hands-on-machine-learning/9781098125967/)) — capítulos 10–19, con incorporación de LLMs modernos, RAG y modelos de difusión.", + "duracion_estimada": "~13–14 semanas", + "trata": ( + "La parte **más extensa** del programa. Cubre Deep Learning desde el perceptrón hasta los " + "modelos generativos modernos (Transformers, LLMs, difusión) y reinforcement learning. " + "El énfasis está en **entender qué hace cada bloque** (no solo en copiar `model.fit`): por qué " + "BatchNorm acelera la convergencia, qué hace Adam que no hace SGD, cuándo conviene una CNN " + "vs una ViT, por qué un Transformer dejó obsoletas a las RNN para secuencias largas.\n\n" + "Está organizada en bloques: **fundamentos** (MLPs, optimización, regularización), " + "**ingeniería con TensorFlow/Keras** (custom layers, tf.data, TFRecord), **visión por " + "computadora** (CNNs y arquitecturas modernas), **secuencias** (RNN, LSTM, atención, " + "Transformers, LLMs, RAG), **generativos** (autoencoders, VAE, GAN, difusión), " + "**reinforcement learning** y **despliegue a producción** (TF Serving, Vertex AI, TF Lite, " + "TensorFlow.js, multi-GPU)." + ), + "resuelve": [ + "Entrenar una red neuronal desde cero (MLP) y explicar la matemática del backpropagation.", + "Diagnosticar y resolver vanishing/exploding gradients con inicialización, BatchNorm y activaciones modernas.", + "Hacer transfer learning con CNNs preentrenadas para visión o con LLMs para texto.", + "Construir un pipeline de datos eficiente con tf.data + TFRecord para entrenar sobre datasets que no caben en RAM.", + "Implementar arquitecturas modernas: ResNet, EfficientNet, ViT, BERT, GPT, modelos de difusión.", + "Usar Hugging Face Transformers para tareas reales (clasificación, NER, generación, embeddings).", + "Construir un sistema RAG básico sobre documentos propios.", + "Desplegar un modelo entrenado a producción (TF Serving + gRPC, Vertex AI, TF Lite móvil, navegador con TF.js).", + ], + "resultados": [ + "Entrenar y serializar un modelo de visión que supere baseline en un dataset propio.", + "Hacer fine-tuning de un Transformer pequeño para clasificación o generación.", + "Construir un mini-RAG con embeddings + retriever + LLM sobre un corpus de ~1000 documentos.", + "Servir un modelo entrenado vía API en una GPU y medir su latencia.", + "Explicar el tradeoff entrenamiento/serving para CNN vs ViT vs LLM para un caso concreto.", + ], + "estructura": [ + ("Fundamentos de redes neuronales", "clases 090–095 — perceptrón, MLP, backprop, Keras (Sequential, Functional, Subclassing), Keras Tuner."), + ("Entrenamiento de redes profundas", "clases 096–104 — gradientes, inicialización, activaciones, normalización, optimizadores, schedules, regularización."), + ("TensorFlow avanzado", "clases 105–112 — tensores, custom layers/loops, autograph, tf.data, TFRecord, preprocessing layers, TFDS."), + ("Visión por computadora", "clases 113–117 — convoluciones, pooling, arquitecturas CNN modernas, transfer learning, detección/segmentación."), + ("Secuencias y NLP", "clases 118–129 — RNN, LSTM, GRU, 1D CNN, char-RNN, sentimiento, encoder-decoder, atención, Transformers, BERT/GPT, Hugging Face, LLMs, RAG."), + ("Modelos generativos", "clases 130–133 — autoencoders, VAE, GAN, difusión."), + ("Reinforcement Learning", "clases 134–138 — Gymnasium, policy gradients, MDPs, Q-learning, DQN, PPO/SAC."), + ("Despliegue y escala", "clases 139–145 — TF Serving, Vertex AI, TF Lite, TensorFlow.js, GPU, tf.distribute, entrenamiento a escala."), + ], + "prev": "parte-1-machine-learning-clasico", + "next": "parte-3-estadistica-inferencial", + }, + "parte-3-estadistica-inferencial": { + "num": 3, + "titulo": "Estadística Inferencial y Causal", + "fuente": "**ISLP** ([*Statistical Learning with Python*](https://www.statlearning.com/)) — rigor matemático en tests, intervalos y diseño experimental.", + "duracion_estimada": "~4 semanas (puede intercalarse con Parte 1)", + "trata": ( + "La parte que separa al data scientist del \"sklearn user\". Cubre **inferencia estadística** " + "(tests, intervalos, bootstrap), **diseño de experimentos** (A/B testing real, no solo " + "`p < 0.05`) e **inferencia causal** (DAGs, confounders, instrumentos, DiD, uplift) — " + "herramientas que se usan a diario para responder preguntas tipo \"¿esto que cambiamos en " + "el producto realmente movió la métrica?\" o \"¿este coeficiente significa lo que creo que " + "significa?\".\n\n" + "Se intercala bien con la Parte 1 porque la mayoría de los problemas de evaluación de " + "modelos (comparar dos clasificadores, decidir si una mejora es real) son problemas " + "estadísticos disfrazados. Incluye una introducción a estadística bayesiana con PyMC para " + "abrir la puerta a inferencia con incertidumbre explícita." + ), + "resuelve": [ + "Decidir si una diferencia observada es estadísticamente significativa o ruido.", + "Diseñar un A/B test con tamaño de muestra y poder estadístico correctos, no a ojo.", + "Aplicar el test correcto según los supuestos del dato (paramétrico vs no paramétrico, pareado vs independiente).", + "Corregir comparaciones múltiples (Bonferroni, FDR) para no inflar el falso positivo.", + "Estimar incertidumbre con bootstrap cuando los supuestos clásicos no aplican.", + "Identificar confounders en un DAG y elegir la estrategia causal correcta (control, IV, DiD, uplift).", + "Hacer una inferencia bayesiana básica con MCMC en PyMC.", + ], + "resultados": [ + "Diseñar y analizar un A/B test end-to-end, incluyendo poder estadístico y corrección por múltiples métricas.", + "Aplicar bootstrap para construir intervalos de confianza no paramétricos sobre cualquier estimador.", + "Dibujar el DAG de un problema de negocio y justificar qué variables controlar.", + "Implementar un modelo bayesiano simple en PyMC e interpretar el posterior.", + ], + "estructura": [ + ("Tests clásicos", "clases 146–151 — distribuciones, t-test, chi-cuadrado, ANOVA, no paramétricos, comparaciones múltiples."), + ("Estimación e incertidumbre", "clases 152–153 — intervalos de confianza, bootstrap, permutation tests."), + ("Experimentación y causalidad", "clases 154–157 — A/B testing, diseño experimental, inferencia causal con DAGs, uplift / DiD."), + ("Inferencia bayesiana", "clase 158 — priors, posterior, MCMC con PyMC."), + ], + "prev": "parte-2-deep-learning", + "next": "parte-4-mlops", + }, + "parte-4-mlops": { + "num": 4, + "titulo": "MLOps — Modelos en Producción", + "fuente": "**Huyen** ([*Designing Machine Learning Systems*](https://www.oreilly.com/library/view/designing-machine-learning/9781098107956/)) — el manual de cabecera para MLOps moderno.", + "duracion_estimada": "~4–5 semanas", + "trata": ( + "La parte que convierte un notebook que entrena bien en un **sistema que funciona en " + "producción 24/7**. Cubre versionado (de datos, modelos y experimentos), packaging " + "(Docker), serving (FastAPI, Kubernetes, serverless), monitoreo (data drift, model drift) " + "y los rituales que evitan que el modelo se degrade silenciosamente (reentrenamiento " + "programado, shadow deployment, canary releases).\n\n" + "Incluye una unidad fuerte de **interpretabilidad** (SHAP, LIME, PDP, ICE) porque ningún " + "modelo va a producción sin alguien preguntando \"¿por qué dijo eso?\", y otra de **testing** " + "(datos con Great Expectations, modelos con tests de invariancia) porque en ML el bug " + "habitual no es un crash sino un drift silencioso." + ), + "resuelve": [ + "Versionar datasets pesados con DVC y modelos/experimentos con MLflow.", + "Empaquetar un modelo entrenado en un contenedor Docker reproducible.", + "Servir el modelo como API (FastAPI) y escalar con Kubernetes o serverless.", + "Detectar data drift y model drift antes de que el negocio reclame.", + "Hacer despliegues seguros (shadow, canary) para evitar romper producción.", + "Explicar predicciones individuales y globales con SHAP / LIME / PDP / ICE.", + "Validar entradas con Great Expectations antes de que lleguen al modelo.", + ], + "resultados": [ + "Tomar un modelo entrenado y publicarlo como API monitoreada en producción en menos de un día.", + "Diseñar un pipeline CI/CD que reentrene y redesplíegue automáticamente cuando llega data nueva.", + "Configurar alertas de drift que avisen *antes* de que la métrica de negocio caiga.", + "Generar un reporte de interpretabilidad para stakeholders no técnicos.", + ], + "estructura": [ + ("Versionado", "clases 159–161 — DVC para datos, MLflow para modelos/experimentos, Feast como feature store."), + ("CI/CD y packaging", "clases 162–164 — GitHub Actions para ML, Docker, FastAPI."), + ("Escala y serving", "clases 165–166 — Kubernetes, serverless (AWS Lambda / GCP Functions)."), + ("Monitoreo y operación", "clases 167–169 — data/model drift, reentrenamiento programado, shadow/canary."), + ("Interpretabilidad y testing", "clases 170–172 — SHAP/LIME/PDP/ICE, testing de datos, testing de modelos."), + ], + "prev": "parte-3-estadistica-inferencial", + "next": "parte-5-ingenieria-de-datos", + }, + "parte-5-ingenieria-de-datos": { + "num": 5, + "titulo": "Ingeniería de Datos", + "fuente": "Complementaria — fundamentos prácticos de data engineering necesarios para alimentar pipelines de ML a escala.", + "duracion_estimada": "~3 semanas", + "trata": ( + "La parte que enseña a **mover y transformar datos a escala**, más allá de lo que pandas " + "aguanta. Cubre orquestación (Airflow, Prefect, Dagster), procesamiento distribuido " + "(PySpark, Polars), almacenamiento analítico (BigQuery, Snowflake, DuckDB), streaming " + "(Kafka, Kinesis), formatos columnares (Parquet, Avro) y modelado dimensional " + "(star/snowflake schemas).\n\n" + "Es la parte donde el data scientist deja de pedirle datos al equipo de data engineering " + "y empieza a moverlos él mismo cuando es necesario. No reemplaza a un data engineer " + "senior, pero sí cubre el 80 % de los casos donde el bottleneck era \"esto no cabe en " + "memoria\" o \"este pipeline corre 8 horas y falla a la mitad\"." + ), + "resuelve": [ + "Orquestar un pipeline de N pasos con dependencias, retries y observabilidad.", + "Procesar datasets de TBs con PySpark o de GBs con Polars sin cargarlos en RAM.", + "Consultar un data warehouse moderno (BigQuery, Snowflake, DuckDB local) desde Python.", + "Consumir un stream de eventos en tiempo real (Kafka / Kinesis).", + "Elegir el formato de almacenamiento correcto (Parquet vs Avro vs CSV) según el patrón de lectura.", + "Diseñar un modelo dimensional (star schema) para BI y para features de ML.", + ], + "resultados": [ + "Convertir un script `pandas` que tomaba horas en un pipeline Airflow/Prefect con Polars o PySpark.", + "Migrar un workflow desde CSV a Parquet y medir la mejora en tiempo y espacio.", + "Diseñar un star schema para un caso de negocio dado.", + ], + "estructura": [ + ("Orquestación", "clases 173–174 — Airflow, Prefect, Dagster."), + ("Procesamiento distribuido y moderno", "clases 175–176 — PySpark, Polars."), + ("Data warehouses y streaming", "clases 177–178 — BigQuery / Snowflake / DuckDB, Kafka / Kinesis."), + ("Formatos y modelado", "clases 179–180 — Parquet/Avro, modelado dimensional."), + ], + "prev": "parte-4-mlops", + "next": "parte-6-sistemas-de-recomendacion", + }, + "parte-6-sistemas-de-recomendacion": { + "num": 6, + "titulo": "Sistemas de Recomendación", + "fuente": "Complementaria — combinación de filtrado colaborativo clásico y enfoques modernos basados en embeddings.", + "duracion_estimada": "~2–3 semanas", + "trata": ( + "Una unidad especializada en una de las aplicaciones de ML con más impacto comercial " + "directo: **recomendar el siguiente producto, video, canción o contenido**. Cubre los dos " + "enfoques clásicos (filtrado colaborativo y content-based), su unión en sistemas " + "**híbridos**, y la matemática detrás (factorización de matrices: SVD, ALS).\n\n" + "También cubre las **métricas correctas** (MAP@k, NDCG, recall@k — no accuracy) y el " + "problema del **cold-start** (usuarios o items nuevos sin historial), que es donde mueren " + "la mayoría de los recomendadores en su primer mes en producción. Termina con un tour " + "por las librerías que se usan en la práctica (LightFM, Implicit, Surprise)." + ), + "resuelve": [ + "Construir un recomendador user-based o item-based desde una matriz usuario-item dispersa.", + "Aplicar factorización de matrices (SVD / ALS) para llegar a recomendaciones escalables.", + "Combinar señales colaborativas y de contenido en un recomendador híbrido.", + "Evaluar un recomendador con la métrica correcta (no con accuracy ni RMSE de rating).", + "Mitigar el cold-start con estrategias basadas en contenido o popularidad.", + ], + "resultados": [ + "Entrenar y evaluar un recomendador end-to-end con LightFM o Implicit sobre un dataset real (MovieLens o similar).", + "Reportar la calidad del recomendador con MAP@k y NDCG, no con accuracy.", + "Diseñar una estrategia explícita para usuarios y items nuevos.", + ], + "estructura": [ + ("Filtrado colaborativo", "clases 181–182 — user-based, item-based, factorización de matrices (SVD, ALS)."), + ("Content-based e híbridos", "clases 183–184 — content-based, recomendadores híbridos."), + ("Evaluación y cold-start", "clases 185–186 — métricas MAP@k / NDCG / recall@k, cold-start problem."), + ("Tooling", "clase 187 — LightFM, Implicit, Surprise."), + ], + "prev": "parte-5-ingenieria-de-datos", + "next": "parte-7-etica-fairness-privacidad", + }, + "parte-7-etica-fairness-privacidad": { + "num": 7, + "titulo": "Ética, Fairness y Privacidad", + "fuente": "**Barocas / Hardt / Narayanan** ([*Fairness and Machine Learning*](https://fairmlbook.org/)) — el texto de referencia académico para fairness algorítmica.", + "duracion_estimada": "~2 semanas", + "trata": ( + "La parte que ningún currículo serio puede omitir en 2026: cómo construir sistemas de ML " + "que **no discriminen, no filtren datos personales y sean reproducibles**. Cubre los " + "tipos y orígenes del sesgo algorítmico, las **métricas formales de fairness** " + "(demographic parity, equalized odds, calibration — y por qué son matemáticamente " + "incompatibles entre sí), técnicas modernas como **privacidad diferencial** y " + "**federated learning**, y el marco regulatorio actual (GDPR, AI Act europeo).\n\n" + "Cierra con una clase sobre **reproducibilidad** (seeds, lock files, versionado de " + "datasets) que es prerrequisito de cualquier discusión seria sobre fairness: si no se " + "puede reproducir, no se puede auditar." + ), + "resuelve": [ + "Identificar los tipos y fuentes de sesgo en un dataset y en un modelo entrenado.", + "Medir fairness con las métricas correctas y explicar por qué no se pueden cumplir todas a la vez.", + "Aplicar privacidad diferencial básica para publicar estadísticas sin filtrar individuos.", + "Entender cuándo federated learning es la solución correcta (y cuándo es overkill).", + "Cumplir requisitos básicos de GDPR y AI Act en un proyecto de ML.", + "Hacer un experimento reproducible bit-a-bit.", + ], + "resultados": [ + "Auditar un modelo clasificador por demographic parity y equalized odds, y reportar trade-offs.", + "Documentar un dataset y un modelo con un datasheet / model card.", + "Producir un experimento que cualquiera puede reproducir desde el repo en menos de 30 minutos.", + ], + "estructura": [ + ("Sesgo y fairness", "clases 188–189 — tipos de sesgo, métricas de fairness."), + ("Privacidad", "clases 190–191 — privacidad diferencial, federated learning."), + ("Regulación y reproducibilidad", "clases 192–193 — GDPR / AI Act, reproducibilidad práctica."), + ], + "prev": "parte-6-sistemas-de-recomendacion", + "next": "parte-8-capstones", + }, + "parte-8-capstones": { + "num": 8, + "titulo": "Capstones — Proyectos Integradores", + "fuente": "Síntesis — el estudiante demuestra dominio integrando todo lo aprendido en tres proyectos completos y un portafolio público.", + "duracion_estimada": "proyectos largos · ~4–6 semanas", + "trata": ( + "La parte final del programa, donde no se aprende contenido nuevo: se **integra todo** " + "en tres proyectos end-to-end y un portafolio público en GitHub Pages. Cada capstone " + "cubre un dominio distinto (tabular, NLP/series, visión) para forzar al estudiante a " + "demostrar versatilidad, y todos los proyectos deben llegar hasta el **deployment** " + "(API, dashboard, app) — no se aceptan notebooks aislados.\n\n" + "El capstone final (la \"clase 197\") no es código sino **comunicación**: armar un " + "portafolio público navegable, una presentación de 10 minutos por proyecto y un README " + "técnico que un reclutador o colega pueda entender. Es el entregable que se usa para " + "buscar trabajo o para evaluar el programa entero." + ), + "resuelve": [ + "Demostrar que se puede llevar un problema desde dataset crudo hasta sistema en producción sin asistencia.", + "Integrar las tres partes técnicas duras del programa: ML clásico (P1), DL (P2) y MLOps (P4).", + "Comunicar resultados técnicos a audiencias no técnicas.", + "Construir un portafolio público creíble para postular a trabajos de data scientist / ML engineer.", + ], + "resultados": [ + "Tres proyectos completos publicados en GitHub con README, demo desplegada y documentación reproducible.", + "Un portafolio público en GitHub Pages que sirva como CV técnico.", + "Tres presentaciones de 10 minutos (una por capstone) listas para entrevistas.", + ], + "estructura": [ + ("Capstone 1 — Tabular", "clase 194 — problema tabular end-to-end (EDA, modelo, API, dashboard)."), + ("Capstone 2 — NLP o series", "clase 195 — NLP o time-series end-to-end."), + ("Capstone 3 — Visión", "clase 196 — visión por computadora con transfer learning."), + ("Portafolio público", "clase 197 — GitHub Pages, presentación, README técnico."), + ], + "prev": "parte-7-etica-fairness-privacidad", + "next": None, + }, +} + + +def class_human_title(class_dir: Path) -> str: + """Lee el título de la clase desde su README.md (primera línea con `#`).""" + readme = class_dir / "README.md" + if readme.exists(): + with readme.open(encoding="utf-8") as f: + for line in f: + m = re.match(r"^#\s+Clase\s+(\d+)\s*[—–-]\s*(.+?)\s*$", line) + if m: + return f"{m.group(1)} — {m.group(2)}" + # Fallback: slug → texto + name = class_dir.name + num, _, rest = name.partition("-") + return f"{num} — {rest.replace('-', ' ').capitalize()}" + + +def build_index(part_dir: Path) -> str: + classes = sorted(d for d in part_dir.iterdir() if d.is_dir() and re.match(r"^\d{3}-", d.name)) + lines = [] + for c in classes: + title = class_human_title(c) + lines.append(f"- [{title}]({c.name}/README.md)") + return "\n".join(lines) + + +def part_readme(slug: str, meta: dict) -> str: + part_dir = CLASSES / slug + n_classes = sum(1 for d in part_dir.iterdir() if d.is_dir() and re.match(r"^\d{3}-", d.name)) + + nav_links = ["[⬅️ Volver al programa](../../README.md)", "[📚 Índice completo](../README.md)"] + if meta["prev"]: + nav_links.append(f"[⏮️ Parte anterior](../{meta['prev']}/README.md)") + if meta["next"]: + nav_links.append(f"[⏭️ Parte siguiente](../{meta['next']}/README.md)") + nav = " · ".join(nav_links) + + resuelve_md = "\n".join(f"- {x}" for x in meta["resuelve"]) + resultados_md = "\n".join(f"- {x}" for x in meta["resultados"]) + estructura_md = "\n".join(f"- **{titulo}** — {detalle}" for titulo, detalle in meta["estructura"]) + indice_md = build_index(part_dir) + + return f"""# Parte {meta["num"]} — {meta["titulo"]} + +> {nav} + +**{n_classes} clases** · {meta["duracion_estimada"]} + +**Fuente principal:** {meta["fuente"]} + +--- + +## 🎯 ¿De qué trata esta parte? + +{meta["trata"]} + +## 🧩 Problemas que resuelve + +{resuelve_md} + +## 🎓 Resultados de aprendizaje + +Al finalizar esta parte, el estudiante podrá: + +{resultados_md} + +## 🗺️ Estructura temática + +{estructura_md} + +## 📚 Índice de clases ({n_classes}) + +{indice_md} + +--- + +> {nav} +""" + + +def main() -> None: + for slug, meta in PARTS.items(): + part_dir = CLASSES / slug + if not part_dir.exists(): + print(f"SKIP missing: {slug}") + continue + readme = part_dir / "README.md" + readme.write_text(part_readme(slug, meta), encoding="utf-8") + print(f"wrote {readme.relative_to(ROOT)}") + + +if __name__ == "__main__": + main()