Table of Contents |
---|
Introducción
Partiendo de datos de Diabetes vamos , vas 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 Vas a utilizar:
File Repository sobre MinIO para guardar el conjunto de datos original. Cargaremos Cargarás 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 Python escalable que usando el modelo pueda predecir la progresión de la enfermedad.
Dataset
The information of the diabetes dataset is the following.
----------------
Ten baseline variables, age, sex, body mass index, average blood
pressure, and six blood serum measurements were obtained for each of n =
442 diabetes patients, as well as the response of interest, a
quantitative measure of disease progression one year after baseline.
Data Set Characteristics:
:Number of Instances: 442
:Number of Attributes: First 10 columns are numeric predictive values
:Target: Column 11 is a quantitative measure of disease progression one year after baseline
:Attribute InformationLa 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 (en inglés):
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
Note: Each of these 10 feature variables have been mean centered and scaled by the standard deviation times `n_samples` (i.e. the sum of squares of each column totals 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 de la fuente:
https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html
For more information seePara más información, véase:
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, vas a obtener el archivo de esta fuente: https://www4.stat.ncsu.edu/~boos/var.select/diabetes.tab.txt
We’re going to create an “Entity in Historical Database” from this file so we’ll go to this option:
...
We’ll fill the main information
...
And click in continue. Then, we need to fill all the columns of the file with the string format (this is because CSV file need to be loaded with this column type)
...
Finally we click on create button and our new entity will be created:
...
Also we can query this entity throw presto engine with the query tool:
...
Step 2: Create notebook for get data, train and log the experiment
First of all, we go to create a new notebook, we go to the Analytics Tools option and we click in the new notebook (+) button we type a name for it
...
Also we can import this file that contains the full notebook for this example (only we need to set the token param)Vas a crear una "Entidad en Base de Datos Histórica" a partir de este archivo así que debes ir a esta opción:
...
Rellena la información principal:
...
Y pulsa “Continuar”. A continuación, tendrás 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, pulsa el botón “Crear” y se creará tu nueva entidad:
...
También puedes 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, vas a crear un nuevo notebook. Dirígete a la opción Analytics Tools y pulsa en el botón nuevo notebook (+) y después escríbele un nombre.
...
También podemos importar este archivo que contiene el cuaderno completo para este ejemplo (sólo tienes que establecer el parámetro token).
View file | ||
---|---|---|
|
We have some explanatory paragraphs for the dataset but we’re going to the code section. First paragraph that we’re going to focus it’s the import one
...
We load many libraries and we set the base url for the MinIO repository. The next paragrah is going to be the parameter paragraph in order to set variables that can come from outside
...
To get the filepath we can go to the File Section
...
Then to MinIO
...
And in the next page we can get the filepath
...
The token will be some X-OP-APIKey token that can access to the file.
Next paragraph 3 paragraphs will load the csv file itself that we token and filepath of the previous section, read it as csv with the column of the dataset (we need to include the columns in the read_csv function) and we show the loaded content
...
Now that we have out file as pandas dataframe we can split the data into train a test sets
...
Split also this datasets into X and Y datasets for input params and expected output
...
And run the ElasticNet training with this data and get in lr the output model
...
Finally, we evaluate some metric for the output of the prediction
...
Step 3: Log training and model data in MLFlow
The notebook module is integrated with MLFlow tracking serve so, the only thing that we need to do in the notebook is import the necessary “MLFlow” lib and use the MLFlow tracking functions. That will be do in the import libs section
...
The connection params and enviroment variables are already done so now we can log out params in MLFlow directly like thisTienes algunos párrafos explicativos para el conjunto de datos, pero ve a la sección de código.
El primer párrafo que vas a enfocar es el de importación.
...
Carga muchas librerías y establece 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 puedes ir a la sección My Files:
...
Luego a MinIO:
...
Y en la siguiente página puedes obtener la ruta del archivo:
...
El token será algún token X-OP-APIKey que pueda acceder al fichero.
A continuación, en tres apartados, carga el propio fichero csv y el filepath del apartado anterior, léelo como csv con la columna del dataset (necesitamos incluir las columnas en la función read_csv) y muestra el contenido cargado:
...
Ahora que tienes tu archivo como pandas dataframe, puedes dividir los datos en conjuntos de entrenamiento y prueba:
...
Divide también estos conjuntos de datos en conjuntos de datos X e Y para los parámetros de entrada y los resultados esperados:
...
Y ejecuta el entrenamiento de ElasticNet con estos datos y obtenga en lr el modelo de salida:
...
Por último, evalúa alguna métrica para el resultado de la predicción.
Paso 3: Registrar los datos de entrenamiento y del modelo en MLFlow
El Notebook Engine está integrado con el servicio de seguimiento de MLFlow, por lo que lo único que tienes 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 puedes registrar los parámetros en MLFlow directamente de esta manera:
...
Code Block | ||
---|---|---|
| ||
%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() |
This is standard code for tracking an experiment in MLFlow. We include everything inside Este es el código estándar para el seguimiento de un experimento en MLFlow. Incluye todo dentro de “with mlflow.start_run()“ to start a new experiment. The other functions arepara iniciar un nuevo experimento.
Las otras funciones son:
mlflow.set_tag("mlflow.runName", ...)
→(optional) for setting a run name of the experiment. If we don’t use this we will only have an autogenerated id, the experiment IDopcional) para establecer un nombre de ejecución del experimento. Si no usas esto. sólo tendrás un id autogenerado, el ID del experimento.mlflow.log_param(...)
→ log a param input for the experimentregistra un parámetro de entrada para el experimento.mlflow.log_metric(...)
→ log an output metric for the experimentregistra una métrica de salida para el experimento.mlflow.sklearn.log_model(lr, "model")
→ log and save the trained model with all necessary metadata files
If we execute this paragraph we’re going to have an output like this. The log process finished ok.
...
If we go to the Models Manager UI in controlpanel:
...
We can see the experiment execution with all the log params, metrics and the files:
...
Clicking in the experiment open the detail page:
...
And, at the end of the page, we can review all the files for this experiment and the model itself
...
registra y guarda el modelo entrenado con todos los archivos de metadatos necesarios.
Si ejecutas este párrafo, tendrás una salida como esta. El proceso de registro ha terminado bien.
...
Si vas a la interfaz de usuario del Gestor de Modelos en el Control Panel:
...
Podrás 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) is important because we’re going to use it for publising the model in the next step. This is the reference that we need to pick up the model in the MLFlow and do some evaluations with it.
We can also register the in order to label it, version it and have it outside of the experiment, we can do it with the code or we can use the register button on the right side:
And if we go to the model tab we can see it and working with it
...
Step 4: Create a Serverless python function that eval data against the MLFlow model
With previous generated model we’re going to create a deploy a python function that, with an simple or multiple input, can get a prediction using the model.
First step is going to the Serverless Applications menú
...
Then we’re going to create (with the + button) a new application and we’re going to fill all the necessary inputs
...
We can create a new repository or use an existing one. In any case, we’re going to have a new application like this
...
Then we can go to “View It” button and then the functions tab
...
Next step it’s to create or use and existing serverless function, we click on “Create Function” and we’re going to create three files.
First of all, we select the main branch on the right side:
...
Then we’re going to create (here or in the git repository from outside) the 3 files:
requeriments.txt → libraries that out model need to be executed. In this case we’re going to have thesees importante porque lo vas a utilizar para publicar el modelo en el siguiente paso. Ésta es la referencia que necesitas para recoger el modelo en el MLFlow y hacer algunas evaluaciones con él.
También puedes registrarlo con el fin de etiquetarlo, versionarlo y tenerlo fuera del experimento. Puedes hacerlo con el código o puedes utilizar el botón de registro en el lado derecho:
...
Y si vas a la pestaña modelo, puedes 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, vas 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 vas a crear (con el botón +) una nueva aplicación y vas a rellenar todas las entradas necesarias:
...
Puedes crear un nuevo repositorio o utilizar uno existente. En cualquier caso, vas a tener una nueva aplicación como esta:
...
Luego puedes 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. Haz clic en "Create Function" y vas a crear tres archivos.
En primer lugar, selecciona la rama principal en el lado derecho:
...
Luego vas a crear (aquí o en el repositorio Git con un editor externo) los tres archivos:
requirements.txt → librerías que necesita tu modelo para ejecutarse. En este caso, vas 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 → the project metadata need for the serverless function. The content will belos metadatos del proyecto necesarios para la función sin servidor. El contenido será:
...
Code Block | ||
---|---|---|
| ||
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 |
It’s important the Es importante el triggers.source config for having the endpoint for this function, the name and runtimefunc.py → the content of the evalution function itself. We need to load libraries for eval the model, MLFlow itself and fdk for the endpoint. We also use an enviroment variable for the parametric input of the host, experiment and tokenpara 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í. Tienes que cargar las bibliotecas para evaluar el modelo, MLFlow y fdk para el punto final.
También utilizarás una variable de entorno para la entrada paramétrica del host, experimento y token.
...
Code Block | ||
---|---|---|
| ||
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"} ) |
We can save everything and deploy our function with the rocket buttonPuedes guardar todo y desplegar tu función con el botón Rocket:
...
The final step is to put the enviroment variables for the model with the buttonEl último paso es poner las variables de entorno para el modelo con el botón:
...
Now we can test out model with the Rest API with postman for example sending an array of json with the input:
...
Or we can create a dashboard model evaluator that use this endpoint with some provided input
...
Paso 5: Evaluación del modelo
Ahora puedes probar el modelo con la API REST con Postman por ejemplo enviando un array de JSON con la entrada:
...
O puedes crear un evaluador de modelo en el Dashboard Engine que utilice este punto final con alguna entrada proporcionada:
...
O puedes evaluar este modelo en un flujo de datos en batch o en streaming en el DataFlow con el componente evaluador correspondiente:
...