¡Hola a todos! Hoy me emociona guiarlos a través de un proyecto completo de Machine Learning, desde el entrenamiento de un modelo simple hasta su despliegue como una API web con Docker. La idea es que al final de este artículo, tengas una comprensión clara y práctica de cómo llevar tus modelos de ML del entorno local a un entorno productivo.
Introducción
En el mundo actual, la capacidad de desplegar modelos de Machine Learning de manera eficiente es tan crucial como su desarrollo. Un modelo, por muy preciso que sea, no es verdaderamente útil hasta que puede ser accedido y utilizado por otras aplicaciones o servicios. En esta guía, mi objetivo es mostrarte cómo puedes lograr esto paso a paso, utilizando herramientas populares y efectivas como Scikit-learn para el modelo, Flask para la API web y Docker para la contenerización.
Vamos a empezar con la selección de un dataset, entrenaremos un modelo de clasificación simple, lo encapsularemos en una API web y finalmente, lo empaquetaremos todo en un contenedor Docker. ¡Prepárate para aprender un montón!
Metodología
Mi enfoque en este tutorial se basa en la practicidad. He dividido el proceso en etapas claras y manejables para que puedas seguirme sin problemas. Aquí está el plan:
- Selección del Dataset: Elegiré un dataset público y fácil de usar.
- Entrenamiento del Modelo: Desarrollaré un script Python para entrenar y guardar un modelo de Machine Learning.
- Creación de la API Web: Construiré una aplicación web básica con Flask para servir las predicciones del modelo.
- Dockerización: Crear un Dockerfile para contenerizar la aplicación web.
- Esquema del Contenido del Artículo: Organizaré la estructura del blog para una lectura clara.
- Generación de Código: Proporcionaré todos los fragmentos de código necesarios.
- Redacción del Borrador: Escribiré el artículo integrando explicaciones y código.
- Instrucciones de Ejecución: Daré los comandos para construir y correr Docker.
- Ejemplo de Uso de la API: Demostraré cómo interactuar con la API.
- Revisión Final: Aseguraré la coherencia y claridad del artículo.
Paso 0 y 1: Selección y Entrenamiento del Modelo con Python
Para esta guía, he optado por el famoso dataset Iris de Scikit-learn. Es un clásico en Machine Learning para problemas de clasificación y es perfecto para este tipo de demostraciones por su simplicidad y fácil acceso.
Ahora, procedamos a entrenar un modelo de Regresión Logística y guardarlo para su posterior uso. Para ello, he creado un script llamado train_model.py
.
Códigos
train_model.py
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
import pickle
# 1. Cargar el dataset de Iris
iris = load_iris()
X = iris.data
y = iris.target
# Crear un DataFrame para mejor visualización (opcional, pero útil para entender los datos)
df = pd.DataFrame(X, columns=iris.feature_names)
df['species'] = iris.target_names[y]
print("Dataset Iris cargado. Primeras 5 filas:")
print(df.head())
# 2. Entrenar un modelo de Machine Learning simple (Regresión Logística)
model = LogisticRegression(max_iter=200) # Aumentamos max_iter para asegurar convergencia
model.fit(X, y)
print("\nModelo de Regresión Logística entrenado exitosamente.")
# 3. Guardar el modelo entrenado en un archivo
filename = 'model.pkl'
pickle.dump(model, open(filename, 'wb'))
print(f"\nModelo guardado como '{filename}'.")
Este script carga el dataset de Iris, entrena un modelo de Regresión Logística y luego lo guarda como model.pkl
. Este archivo model.pkl
será el corazón de nuestra aplicación web.
Paso 2: Creación de la Aplicación Web con Flask
El siguiente paso es crear una API web simple utilizando Flask. Esta API cargará nuestro modelo entrenado y expondrá un endpoint /predict
que aceptará datos de entrada, hará una predicción y devolverá el resultado en formato JSON. He nombrado a este archivo app.py
.
app.py
import pickle
from flask import Flask, request, jsonify
import numpy as np
# 1. Cargar el modelo entrenado
model = pickle.load(open('model.pkl', 'rb'))
# Inicializar la aplicación Flask
app = Flask(__name__)
# 2. Definir un endpoint para predicciones
@app.route('/predict', methods=['POST'])
def predict():
try:
data = request.get_json(force=True) # Obtener los datos JSON de la solicitud
# Los datos deben ser una lista de 4 números flotantes, por ejemplo:
# {"features": [5.1, 3.5, 1.4, 0.2]}
features = np.array(data['features']).reshape(1, -1) # Convertir a array de numpy y redimensionar
# Realizar la predicción
prediction = model.predict(features)
prediction_proba = model.predict_proba(features).tolist() # Probabilidades de cada clase
# Mapear la predicción numérica a las especies de Iris
# En el dataset Iris, 0=setosa, 1=versicolor, 2=virginica
iris_species = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
predicted_species = iris_species[prediction[0]]
# Retornar la predicción en formato JSON
return jsonify({
'prediction': predicted_species,
'prediction_raw': int(prediction[0]),
'probabilities': prediction_proba
})
except Exception as e:
return jsonify({'error': str(e)}), 400
# Para ejecutar la aplicación localmente
if __name__ == '__main__':
# Usamos host='0.0.0.0' para que sea accesible desde fuera del contenedor Docker
app.run(host='0.0.0.0', port=5000)
Este script crea una aplicación Flask que escucha en el puerto 5000. El endpoint /predict
espera un JSON con una clave features
que contenga una lista de cuatro números (las características de la flor de Iris). Luego, usa el modelo cargado para predecir la especie de Iris y devuelve la predicción junto con las probabilidades.
Paso 3: Dockerización de la Aplicación Web
Para hacer nuestra aplicación portable y fácil de desplegar, la vamos a contenerizar con Docker. Esto implica crear un archivo requirements.txt
con todas las dependencias y un Dockerfile
que describa cómo construir la imagen Docker.
requirements.txt
flask==2.3.3
scikit-learn==1.3.0
numpy==1.26.0
gunicorn==21.2.0
Dockerfile
# Usamos una imagen base de Python oficial
FROM python:3.9-slim-buster
# Establecer el directorio de trabajo dentro del contenedor
WORKDIR /app
# Copiar el archivo de requisitos e instalar las dependencias
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar los archivos de la aplicación
COPY . .
# Exponer el puerto en el que la aplicación Flask se ejecutará
EXPOSE 5000
# Comando para ejecutar la aplicación usando Gunicorn
# Gunicorn es un servidor WSGI de Python que es más robusto para producción que el servidor de desarrollo de Flask
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
El Dockerfile
se encarga de todo: desde instalar Python y las dependencias hasta copiar nuestros archivos y definir cómo se ejecutará la aplicación dentro del contenedor. Usamos Gunicorn, un servidor WSGI robusto, para manejar las solicitudes de nuestra API en producción.
Paso 7: Instrucciones para Construir y Ejecutar la Imagen Docker
Con el Dockerfile
y el resto de los archivos listos, ahora puedo mostrarte cómo construir la imagen Docker y ejecutar el contenedor localmente. Asegúrate de tener Docker instalado en tu máquina.
Construir la imagen Docker
Abre tu terminal en el directorio donde tienes train_model.py
, app.py
, requirements.txt
y Dockerfile
. Primero, ejecuta el script de entrenamiento para generar model.pkl
:
python train_model.py
Una vez que tengas model.pkl
, construye la imagen Docker con el siguiente comando:
docker build -t iris-prediction-api .
Este comando construye una imagen llamada iris-prediction-api
a partir de los archivos en el directorio actual.
Ejecutar el contenedor Docker
Una vez que la imagen se ha construido, puedes ejecutar el contenedor:
docker run -p 5000:5000 iris-prediction-api
Esto mapea el puerto 5000 de tu máquina local al puerto 5000 del contenedor, permitiéndote acceder a la API.
Paso 8: Ejemplo de Uso de la API (Cliente de Prueba)
Para demostrar que nuestra API funciona correctamente, puedo usar un script Python simple o curl
para interactuar con ella. Voy a mostrarte cómo hacerlo con curl
y con un script Python.
Usando cURL
Abre una nueva terminal (mientras el contenedor Docker se está ejecutando en la otra) y ejecuta el siguiente comando:
curl -X POST -H "Content-Type: application/json" -d "{\"features\": [5.1, 3.5, 1.4, 0.2]}" http://localhost:5000/predict
Deberías recibir una respuesta JSON similar a esta:
{"prediction": "setosa", "prediction_raw": 0, "probabilities": [[0.97..., 0.02..., 0.00...]]}
Usando un Script Python (test_api.py)
También puedes crear un pequeño script Python para probar la API. Guarda el siguiente código como test_api.py
:
test_api.py
import requests
import json
# URL de tu API local
url = 'http://localhost:5000/predict'
# Datos de entrada para la predicción (ejemplo de una flor Iris setosa)
data = {'features': [5.1, 3.5, 1.4, 0.2]}
# Realizar la solicitud POST
response = requests.post(url, json=data)
# Imprimir la respuesta
print(f"Status Code: {response.status_code}")
print(f"Response JSON: {json.dumps(response.json(), indent=4)}")
# Otro ejemplo (Iris versicolor)
data_versicolor = {'features': [6.0, 2.7, 4.0, 1.0]}
response_versicolor = requests.post(url, json=data_versicolor)
print(f"\nStatus Code (Versicolor): {response_versicolor.status_code}")
print(f"Response JSON (Versicolor): {json.dumps(response_versicolor.json(), indent=4)}")
# Otro ejemplo (Iris virginica)
data_virginica = {'features': [6.3, 3.3, 6.0, 2.5]}
response_virginica = requests.post(url, json=data_virginica)
print(f"\nStatus Code (Virginica): {response_virginica.status_code}")
print(f"Response JSON (Virginica): {json.dumps(response_virginica.json(), indent=4)}")
Ejecuta este script con python test_api.py
y verás las predicciones de la API.
Conclusiones
Hemos recorrido un camino fascinante, desde un modelo de Machine Learning simple hasta una API web funcional y dockerizada. Hemos visto cómo:
- Preparar un modelo de ML y guardarlo.
- Construir una API RESTful básica con Flask.
- Empaquetar la aplicación en un contenedor Docker para facilitar su despliegue y portabilidad.
- Interactuar con la API para obtener predicciones.
Este flujo de trabajo es fundamental en el desarrollo moderno de aplicaciones de Machine Learning y te proporciona una base sólida para proyectos más complejos. La capacidad de desplegar tus modelos es lo que realmente los trae a la vida y permite que otros los utilicen. Espero que esta guía te haya sido de gran utilidad y te inspire a seguir explorando el emocionante mundo del MLOps.
Recuerda que siempre siempre vas a aprender un bit a la vez!
Promoción
Si te ha gustado este contenido y quieres profundizar mucho más en el mundo de la Ciencia de Datos, te invito a conocer mi curso completo de Ciencia de Datos con Python y R. En él, aprenderás desde los fundamentos hasta técnicas avanzadas, con proyectos prácticos que te prepararán para el mercado laboral. ¡Haz clic en el enlace y empieza tu viaje hoy mismo!