Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

Introducción

Partiendo de datos de Diabetes vamos a generar el modelo correspondiente que prediga una medida cuantitativa de progresión de la enfermedad un año después de la línea base. Vamos a utilizar

  • File Repository sobre MinIO para guardar el conjunto de datos original. Cargaremos el archivo utilizando el módulo Create Entity in Historical Database

  • Notebooks para tener un proceso paramétrico para obtener los datos de MinIO, entrenar y generar el modelo y registrar todo en MLFlow

  • Gestor de Modelos (MLFlow) para registrar todos los experimentos del cuaderno y guardar el modelo y otros archivos para el entrenamiento.

  • Módulo Serverless para crear una función python escalable que usando el modelo pueda predecir la progresión de la enfermedad.

Dataset

La información del conjunto de datos sobre diabetes es la siguiente.


 Se obtuvieron diez variables de base, edad, sexo, índice de masa corporal, presión y seis mediciones de suero sanguíneo para cada uno de los 442 pacientes diabéticos, así como la respuesta de interés, una medida cuantitativa de la progresión de la enfermedad un año después de la línea de base.

Características del dataset:

  • Número de instancias: 44

  • Número de atributos: Las 10 primeras columnas son valores predictivos numéricos

  • Target: La columna 11 es una medida cuantitativa de la progresión de la enfermedad un año después de la línea de base

Información sobre atributos:

  • age     age in years

  • sex

  • bmi     body mass index

  • bp      average blood pressure

  • s1      tc, total serum cholesterol

  • s2      ldl, low-density lipoproteins

  • s3      hdl, high-density lipoproteins

  • s4      tch, total cholesterol / HDL

  • s5      ltg, possibly log of serum triglycerides level

  • s6      glu, blood sugar level

Nota: Cada una de estas 10 variables de características se ha centrado en la media y se ha escalado por la desviación estándar multiplicada por n_muestras (es decir, la suma de cuadrados de cada columna suma 1).

Source URL:

https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html

For more information see:

Bradley Efron, Trevor Hastie, Iain Johnstone and Robert Tibshirani (2004) "Least Angle Regression," Annals of Statistics (with discussion), 407-499.

(https://web.stanford.edu/~hastie/Papers/LARS/LeastAngle_2002.pdf)'

Paso 1: Cargar datos en la plataforma MinIO

Desde el enlace vamos a obtener el archivo de esta fuente https://www4.stat.ncsu.edu/~boos/var.select/diabetes.tab.txt

Vamos a crear una "Entidad en Base de Datos Histórica" a partir de este archivo así que iremos a esta opción:

Rellenaremos la información principal

Y pulsar en continuar. A continuación, tenemos que rellenar todas las columnas del archivo con el formato de cadena (esto es porque el archivo CSV necesita ser cargado con este tipo de columna)

Finalmente pulsamos el botón crear y se creará nuestra nueva entidad:

También podemos consultar esta entidad en SQL a través de Presto con el Query Tool

Paso 2: Crear libreta para obtener datos, entrenar y registrar el experimento

En primer lugar, vamos a crear un nuevo notebook, nos dirigimos a la opción Analytics Tools y pulsamos en el botón nuevo notebook (+) le escribimos un nombre

También podemos importar este archivo que contiene el cuaderno completo para este ejemplo (sólo tenemos que establecer el parámetro token)

Tenemos algunos párrafos explicativos para el conjunto de datos, pero vamos a la sección de código.

El primer párrafo que vamos a enfocar es el de importación

Cargamos muchas librerías y establecemos la url base para el repositorio MinIO. El siguiente párrafo va a ser el párrafo de parámetros con el fin de establecer variables que pueden venir de fuera

Para obtener la ruta del archivo podemos ir a la sección My Files:

Luego a MinIO

Y en la siguiente página podemos obtener la ruta del archivo

El token será algún token X-OP-APIKey que pueda acceder al fichero.

A continuación en 3 apartados cargaremos el propio fichero csv y el filepath del apartado anterior, lo leemos como csv con la columna del dataset (necesitamos incluir las columnas en la función read_csv) y mostramos el contenido cargado:

Ahora que tenemos nuestro archivo como pandas dataframe podemos dividir los datos en conjuntos de entrenamiento y prueba:

Divida también estos conjuntos de datos en conjuntos de datos X e Y para los parámetros de entrada y los resultados esperados:

Y ejecute el entrenamiento de ElasticNet con estos datos y obtenga en lr el modelo de salida

Por último, evaluamos alguna métrica para el resultado de la predicción:

Paso 3: Registrar los datos de entrenamiento y del modelo en MLFlow

El Notebook Engineestá integrado con el servicio de seguimiento de MLFlow, por lo que lo único que tenemos que hacer en el cuaderno es importar la librería "MLFlow" necesaria y utilizar las funciones de seguimiento de MLFlow. Eso se hará en la sección de librerías de importación

Los parámetros de conexión y las variables de entorno ya están hechos, así que ahora podemos registrar los parámetros en MLFlow directamente de esta manera

%python

with mlflow.start_run():
    mlflow.set_tag("mlflow.runName", "DiabetesModelGenerator")
    mlflow.log_param("alpha", alpha)
    mlflow.log_param("l1_ratio", l1_ratio)
    mlflow.log_metric("rmse", rmse)
    mlflow.log_metric("r2", r2)
    mlflow.log_metric("mae", mae)
    mlflow.sklearn.log_model(lr, "model")
    mlflow.end_run()

Este es el código estándar para el seguimiento de un experimento en MLFlow. Incluimos todo dentro de “with mlflow.start_run()“ para iniciar un nuevo experimento.

Las otras funciones son:

  • mlflow.set_tag("mlflow.runName", ...) →(opcional) para establecer un nombre de ejecución del experimento. Si no usamos esto sólo tendremos un id autogenerado, el ID del experimento

  • mlflow.log_param(...) → registrar una parámetro de entrada para el experimento

  • mlflow.log_metric(...) → registrar una métrica de salida para el experimento

  • mlflow.sklearn.log_model(lr, "model") → registra y guarda el modelo entrenado con todos los archivos de metadatos necesarios

Si ejecutamos este párrafo vamos a tener una salida como esta. El proceso de registro ha terminado bien.

Si vamos a la interfaz de usuario del Gestor de Modelos en el Control Panel:

Podemos ver la ejecución del experimento con todos los parámetros de registro, las métricas y los archivos:

Al hacer clic en el experimento, se abre la página de detalles:

Y, al final de la página, podemos revisar todos los archivos de este experimento y el propio modelo

El run id de la derecha (runs:/859953c3a0dd4596bd15d864e91081ab/model) es importante porque lo vamos a utilizar para publicar el modelo en el siguiente paso. Esta es la referencia que necesitamos para recoger el modelo en el MLFlow y hacer algunas evaluaciones con él.

También podemos registrar el con el fin de etiquetarlo, versionarlo y tenerlo fuera del experimento, podemos hacerlo con el código o podemos utilizar el botón de registro en el lado derecho:

Y si vamos a la pestaña modelo podemos verlo y trabajar con él

Paso 4: Crear una función Serverless en Python que evalúe los datos contra el modelo MLFlow

Con el modelo generado anteriormente vamos a crear una función Python que, con una entrada simple o múltiple, pueda obtener una predicción usando el modelo.

El primer paso es ir al menú Serverless Applications

A continuación vamos a crear (con el botón +) una nueva aplicación y vamos a rellenar todas las entradas necesarias

Podemos crear un nuevo repositorio o utilizar uno existente. En cualquier caso, vamos a tener una nueva aplicación como esta:

Luego podemos ir al botón "Ver" y luego a la pestaña de funciones

El siguiente paso es crear o utilizar una función serverless existente, hacemos clic en "Create Function" y vamos a crear tres archivos.

En primer lugar, seleccionamos la rama principal en el lado derecho:

Luego vamos a crear (aquí o en el repositorio git con un editor externo) los 3 archivos:

requirements.txt → librerías que necesita nuestro modelo para ejecutarse. En este caso vamos a tener estos:

fdk
protobuf==3.20.*
numpy==1.23.4
mlflow==1.19.0
mlflow-onesaitplatform-plugin==0.2.11
scikit-learn

func.yaml → los metadatos del proyecto necesarios para la función sin servidor. El contenido será:

schema_version: 20180708
name: diabetes-predictor
version: 0.1.1
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256
triggers:
- name: endpoint
  type: http
  source: /diabetes-predictor

Es importante el triggers.source config para tener el endpoint para esta función, el nombre y el tiempo de ejecución

func.py →el contenido de la función de evaluación en sí. Tenemos que cargar las bibliotecas para evaluar el modelo, MLFlow y fdk para el punto final.

También utilizamos una variable de entorno para la entrada paramétrica del host, experimento y token

import io
import json
import logging
import os
os.environ["HOME"] = "/tmp"
import random
import mlflow

from fdk import response

host = os.environ['HOST']
token = os.environ['TOKEN']
experimentid = os.environ['EXPERIMENTID']

tracking_uri = "https://" + host + "/controlpanel/modelsmanager"
model_uri = "onesait-platform://" + token +  "@" + host + "/0/" + experimentid + "/artifacts/model"
global pyfunc_predictor

mlflow.set_tracking_uri(tracking_uri)
pyfunc_predictor = mlflow.pyfunc.load_model(model_uri=model_uri)
logging.getLogger().info("Diabetes Progression Predictor ready")

def handler(ctx, data: io.BytesIO = None):
    try:
        logging.getLogger().info("Try")
        answer = []
        json_obj = json.loads(data.getvalue())
        logging.getLogger().info("json_obj")
        logging.getLogger().info(str(json_obj))
        if isinstance(json_obj, list):
            logging.getLogger().info("isinstance")
            answer = []
            values = []
            inputvector = []
            for input in json_obj:
                logging.getLogger().info("for")
                logging.getLogger().info("input: " + str(input))
                inputvector = [ input['age'], input['sex'], input['bmi'], input['bp'], input['s1'], input['s2'], input['s3'], input['s4'], input['s5'], input['s6']]
                values.append(inputvector)
                
            predict = pyfunc_predictor.predict(values)
            answer = predict.tolist()
            logging.getLogger().info("prediction")
        else:
            answer = "input object is not an array of objects:" + str(json_obj)
            logging.getLogger().error('error isinstance(json_obj, list):' + isinstance(json_obj, list))
            raise Exception(answer)
    except (Exception, ValueError) as ex:

        logging.getLogger().error('error parsing json payload: ' + str(ex))

    logging.getLogger().info("Inside Python ML function")
    return response.Response(
        ctx, response_data=json.dumps(answer),
        headers={"Content-Type": "application/json"}
    )


Podemos guardar todo y desplegar nuestra función con el botón Rocket:

El último paso es poner las variables de entorno para el modelo con el botón:

Paso 5: Evaluación del modelo

Ahora podemos probar el modelo con la API Rest con postman por ejemplo enviando un array de json con la entrada:

O podemos crear un evaluador de modelo en el Dashboard Engine que utilice este punto final con alguna entrada proporcionada

O podemos evaluar este modelo en un flujo de datos en batch o en streaming en el DataFlow con el componente evaluador correspondiente

  • No labels