<jupyter_start><jupyter_text>Deep Dive Amazon SageMaker Studio _**Gradient Boosted Trees para predecir gastos familiares**_---En este demo se va a ver algunas características de Amazon SageMaker Studio. * [Amazon SageMaker Experiments](https://docs.aws.amazon.com/sagemaker/latest/dg/experiments.html)  * Administrar múltiples experimentos  * Experimentar con hiperparametros y visualizaciones* [Model hosting](https://docs.aws.amazon.com/sagemaker/latest/dg/how-it-works-hosting.html)  * Creación de endpoints para obtener predicciones* [SageMaker Model Monitor](https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor.html)  * Monitorear la calidad del modelo--- Contenido1. [Background](Background)   - Que es Amazon Sagemaker1. [Datos](Datos) - Preparar el dataset y subirlo a s31. [Entrenamiento](Entrenamiento) - Entrenar el modelo  - [Amazon SageMaker Experiments](Amazon-SageMaker-Experiments)1. [Despliegue](Despliegue)1. [Monitoreo](Monitoreo) --- Background Que es amazon sagemaker"Amazon SageMaker es un servicio completamente administrado que brinda a todos los científicos de datos y desarrolladores la capacidad de crear, entrenar e implementar modelos de aprendizaje automático de forma rápida. SageMaker elimina las tareas arduas de cada paso del proceso de aprendizaje automático para que sea más fácil crear modelos de alta calidad."https://aws.amazon.com/es/sagemaker/SageMaker brinda todos los componentes que se utilizan en el aprendizaje automático en un único conjunto de herramientas, de forma que la producción de los modelos es más rápida y requiere menos esfuerzo y costos.![image.png](attachment:image.png) Predecir gastos familiares con XGBoostEste notebook es una adaptación de [amazon-sagemaker-examples/aws_sagemaker_studio/getting_started/] (https://github.com/awslabs/amazon-sagemaker-examples.git). Se adapta el modelo implementado de gastos familiares para este demo --- DatosSe van a utilizar los datos con la cual se entreno el modelo de gastos familiares: processed_data.csv<jupyter_code>import sys
#!{sys.executable} -m pip install sagemaker -U
!{sys.executable} -m pip install -qU awscli boto3 "sagemaker>=1.71.0,<2.0.0"
!{sys.executable} -m pip install sagemaker-experiments

import io
import os
import sys
import time
import json
import boto3
import re
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
from IPython.display import display
from time import strftime, gmtime
from sklearn.model_selection import train_test_split

import sagemaker
from sagemaker import get_execution_role
from sagemaker.predictor import csv_serializer
from sagemaker.debugger import rule_configs, Rule, DebuggerHookConfig
from sagemaker.model_monitor import DataCaptureConfig, DatasetFormat, DefaultModelMonitor
from sagemaker.s3 import S3Uploader, S3Downloader
from smexperiments.experiment import Experiment
from smexperiments.trial import Trial
from smexperiments.trial_component import TrialComponent
from smexperiments.tracker import Tracker

print(sagemaker.__version__)
sess = boto3.Session()
sm = sess.client('sagemaker')
role = sagemaker.get_execution_role()
%pwd
local_data_path = "/root/demo-sagemaker/notebooks/data/processed_data.csv"
data = pd.read_csv(local_data_path)
pd.set_option('display.max_columns', 500)     # Make sure we can see all of the columns
pd.set_option('display.max_rows', 10)         # Keep the output on one page
data
account_id = sess.client('sts', region_name=sess.region_name).get_caller_identity()["Account"]
#artefactos de los componentes se almacenan en este key
bucket = 'lbk-analytics-dev'
prefix = 'sagemaker/demo'

df_model = data[['valor_gasto','edad','salario']]
df_model = df_model[~df_model['valor_gasto'].isnull()]
df_model['edad_salario'] = df_model['edad'] * df_model['salario']

train, test = train_test_split(df_model, test_size=0.4, random_state=42)
test, validate = train_test_split(test, test_size=0.5, random_state=42)

print("Rows df_model:{}".format(df_model.shape)) 
print("Rows train:{}".format(train.shape)) 
print("Rows test:{}".format(test.shape)) 
print("Rows validate:{}".format(validate.shape)) 

test_without_label = test.drop(columns=['valor_gasto'])
print("Rows test_without_label:{}".format(test_without_label.shape)) 

train.to_csv("/root/demo-sagemaker/notebooks/data/train.csv", sep=',', decimal='.', index=False, header=False)
validate.to_csv("/root/demo-sagemaker/notebooks/data/validate.csv", sep=',', decimal='.', index=False, header=False)
test.to_csv("/root/demo-sagemaker/notebooks/data/test.csv", sep=',', decimal='.', index=False, header=False)
test_without_label.to_csv("/root/demo-sagemaker/notebooks/data/test_without_label.csv", sep=',', decimal='.', index=False, header=False)


s3url = S3Uploader.upload('/root/demo-sagemaker/notebooks/data/train.csv', 's3://{}/{}/{}'.format(bucket, prefix,'data'))
print(s3url)

s3url = S3Uploader.upload('/root/demo-sagemaker/notebooks/data/validate.csv', 's3://{}/{}/{}'.format(bucket, prefix,'data'))
print(s3url)

s3url = S3Uploader.upload('/root/demo-sagemaker/notebooks/data/test.csv', 's3://{}/{}/{}'.format(bucket, prefix,'data'))
print(s3url)<jupyter_output>INFO:numexpr.utils:NumExpr defaulting to 2 threads.<jupyter_text>--- EntrenamientoSe va a usar la libreria XGBoost (gradient boosted decision trees), y se va a entrenar el modelo con la información que está en el bucket de S3.Se debe especificar la ubicación de el contenedor con el algoritmo XGBoost<jupyter_code>%pwd
#%ls /opt/conda/lib/p
#from sagemaker.amazon.amazon_estimator import get_image_uri
from sagemaker.amazon.amazon_estimator import get_image_uri
docker_image_name = get_image_uri(boto3.Session().region_name, 'xgboost', repo_version='1.0-1')<jupyter_output>WARNING:sagemaker.amazon.amazon_estimator:'get_image_uri' method will be deprecated in favor of 'ImageURIProvider' class in SageMaker Python SDK v2.<jupyter_text>Para realizar el entrenamiento con los archivos .csv que están el bucket de s3, se crea un s3_inputs<jupyter_code>s3_input_train = sagemaker.s3_input(s3_data='s3://{}/{}/data/train.csv'.format(bucket, prefix), content_type='csv')
s3_input_validation = sagemaker.s3_input(s3_data='s3://{}/{}/data/validate.csv'.format(bucket, prefix), content_type='csv')<jupyter_output>WARNING:sagemaker:'s3_input' class will be renamed to 'TrainingInput' in SageMaker Python SDK v2.
WARNING:sagemaker:'s3_input' class will be renamed to 'TrainingInput' in SageMaker Python SDK v2.<jupyter_text>--- Amazon SageMaker ExperimentsAmazon SageMaker Experiments permite monitorear el entrenamiento del modelo, organizar modelos relacionados, configurar los logs de los modelos, tunning de hiperparametros, revisión de versiones anteriores del modelo, y comparación de resultados entre modelos.Cada bloque de entrenamiento del modelo se llama "experiment trial", y estos bloques pueden ser comparados<jupyter_code>sess = sagemaker.session.Session()

create_date = strftime("%Y-%m-%d-%H-%M-%S", gmtime())

#family_expensives_experiment = Experiment.create(experiment_name="Experiment-family-expensives-xgboost-{}".format(create_date),
family_expensives_experiment = Experiment.create(experiment_name="Experiment-family-expensives-xgboost-v2",
                                              description="Using xgboost to predict family expensives", 
                                              sagemaker_boto_client=boto3.client('sagemaker'))
hyperparams = {"max_depth":20,
               "subsample":0.5,               
               "eta":0.2,
               "gamma":0.0,
               "min_child_weight":0.0,
               "silent":0,
               "max_delta_step":0.0,
               "colsample_bytree":1.0,
               "colsample_bylevel":1.0,
               "reg_alpha":0.0,
               "nthread":4,
               "scale_pos_weight":1.0,
               "base_score":0.5,
               "seed":1337,                              
               "num_round":10,
               "objective":'reg:squarederror'
}<jupyter_output><empty_output><jupyter_text>--- Trial 1Se va a utilizar el algoritmo XGBoost para entrenar y desplegar el modelo.- Se crea un estimador con los parametros basicos, como el tipo instancias para entrenar y la cantidad, ademas de la ruta de los artefactos generados de la ejecución del modelo.- Se crea un objeto `Trial` para asociar el experimento con el entrenamiento ejecutado.<jupyter_code>trial = Trial.create(trial_name="Trial-family-expensives-xgboost-v2-{}".format(strftime("%Y-%m-%d-%H-%M-%S", gmtime())), 
                     experiment_name=family_expensives_experiment.experiment_name,
                     sagemaker_boto_client=boto3.client('sagemaker'))

xgb = sagemaker.estimator.Estimator(image_name=docker_image_name,
                                    role=role,
                                    hyperparameters=hyperparams,
                                    train_instance_count=1, 
                                    train_instance_type='ml.m4.xlarge',
                                    output_path='s3://{}/{}/output'.format(bucket, prefix),
                                    base_job_name="demo-family-expensives-v2",
                                    sagemaker_session=sess)


xgb.fit({'train': s3_input_train,
         'validation': s3_input_validation}, 
        experiment_config={
            "ExperimentName": family_expensives_experiment.experiment_name, 
            "TrialName": trial.trial_name,
            "TrialComponentDisplayName": "Training",
        }
       )<jupyter_output>WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v2-2020-09-02-15-51-55-688<jupyter_text>--- Resultados TrialSe puede revisar las métricas, logs y graficas relacionadas a cada entrenamiento el el tab **Experiments** en Amazon SageMaker Studio. Para visualizar los Entrenamientos de los experimentos, se da doble click sobre el experimento. Adicional se pueden ver los entrenamientos de multiples experimentos seleccionadolos con Crtl, y con el menú contextual "Open in trial component list".Los componentes son ordenados de tal forma que el mejor modelo queda al inicio Información del trial y descarga de modelosSeleccionado el trial, se pueden ver la información del mismo, graficas, métricas y la ubicación en s3 del modelo. --- Modificando HiperparametrosSe va a variar el parámetro `min_child_weight`. Para cada valor se va a crear un `trial` diferente, para poder comparar los resultados en Amazon SageMaker Studio.<jupyter_code>min_child_weights = [1, 2, 4, 8, 10]

for weight in min_child_weights:
    hyperparams["min_child_weight"] = weight
    trial = Trial.create(trial_name="Trial-family-expensives-xgboost-v1-weight-{}-{}".format(weight,strftime("%Y-%m-%d-%H-%M-%S", gmtime())), 
                         experiment_name=family_expensives_experiment.experiment_name,
                         sagemaker_boto_client=boto3.client('sagemaker'))

    t_xgb = sagemaker.estimator.Estimator(image_name=docker_image_name,
                                          role=role,
                                          hyperparameters=hyperparams,
                                          train_instance_count=1, 
                                          train_instance_type='ml.m4.xlarge',
                                          output_path='s3://{}/{}/output'.format(bucket, prefix),
                                          base_job_name="demo-family-expensives-v1",
                                          sagemaker_session=sess)

    t_xgb.fit({'train': s3_input_train,
               'validation': s3_input_validation},
                wait=False,
                experiment_config={
                    "ExperimentName": family_expensives_experiment.experiment_name, 
                    "TrialName": trial.trial_name,
                    "TrialComponentDisplayName": "Training",
                }
               )<jupyter_output>WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v1-2020-09-02-16-00-37-117
WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v1-2020-09-02-16-00-37-409
WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v1-2020-09-02-16-00-39-870
WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v1-2020-09-02-16-00-40-210
WARNING:sagemaker.estimator:Parameter image_name will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating training-job with name: demo-family-expensives-v1-2020[...]<jupyter_text>--- Crear GráficosSeleccionando los `trial` que se quieren comparar, se elige **Add chart**. En el panel  **Chart Properties**: - **Data type** : `Summary Statistics`. - **Chart type**: `Scatter plot`. - **X axis** : `min_child_weight`. - **Y axis**: `validation:error_last` o `validation:error_avg`. - **Color**: `trialComponentName`. --- DespliegueUna vez esta entrenado el modelo, se va a hacer el despliegue a un endpoint. Para monitorear el modelo una vez este recibiendo peticiones, se van a agregar configuraciones para capturar la data que se esta enviando al endpoint.<jupyter_code>data_capture_prefix = '{}/datacapture'.format(prefix)

endpoint_name = "Endpoint-family-expensives-xgboost-v1-" + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
print("EndpointName = {}".format(endpoint_name))
xgb_predictor = xgb.deploy(initial_instance_count=1, 
                           instance_type='ml.m4.xlarge',
                           endpoint_name=endpoint_name,
                           data_capture_config=DataCaptureConfig(enable_capture=True,
                                                                 sampling_percentage=100,
                                                                 destination_s3_uri='s3://{}/{}'.format(bucket, data_capture_prefix)
                                                                )
                           )<jupyter_output>WARNING:sagemaker:Parameter image will be renamed to image_uri in SageMaker Python SDK v2.
INFO:sagemaker:Creating model with name: demo-family-expensives-v2-2020-09-02-15-51-55-688
INFO:sagemaker:Creating endpoint with name Endpoint-family-expensives-xgboost-v1-2020-09-02-16-11-46<jupyter_text>Invocar el modelo desplegadoComo el modelo ya se encuentra desplegado, se pueden hacer predicciones reales con el modelo a través de peticiones http POST. El primer paso a realizar es utilizar serializers y deserializers para convertir los datos de test en un arreglo de NumPy.<jupyter_code>xgb_predictor.content_type = 'text/csv'
xgb_predictor.serializer = csv_serializer
xgb_predictor.deserializer = None
print("Sending test traffic to the endpoint {}. \nPlease wait for a minute...".format(endpoint_name))

with open('/root/demo-sagemaker/notebooks/data/test_without_label.csv', 'r') as f:
    i = 0
    for row in f:
        payload = row.rstrip('\n')
        response = xgb_predictor.predict(data=payload)
        time.sleep(0.2)
        i += 1
        if i >30 :
            break<jupyter_output>Sending test traffic to the endpoint Endpoint-family-expensives-xgboost-v1-2020-09-02-16-11-46. 
Please wait for a minute...<jupyter_text>--- Verificar que la data se ha capturado en S3Se va a listar los archivos que fueron capturados y almacenados en bucket de s3. El path en el cual se guardan los archivos es el siguiente:`s3://{destination-bucket-prefix}/{endpoint-name}/{variant-name}/yyyy/mm/dd/hh/filename.jsonl`<jupyter_code>from time import sleep

current_endpoint_capture_prefix = '{}/{}'.format(data_capture_prefix, endpoint_name)
for _ in range(10): # wait up to a minute to see captures in S3
    capture_files = S3Downloader.list("s3://{}/{}".format(bucket, current_endpoint_capture_prefix))
    if capture_files:
        break
    sleep(5)

print("Found Data Capture Files:")
print(capture_files)<jupyter_output>Found Data Capture Files:
['s3://lbk-analytics-dev/sagemaker/demo/datacapture/Endpoint-family-expensives-xgboost-v1-2020-09-02-16-11-46/AllTraffic/2020/09/02/16/22-34-282-3169b4ae-f446-4b15-a8b3-66387034b109.jsonl']<jupyter_text>Toda la data capturada por el endpoint se guarda en un formato jsonl. A continuación se ve el ejemplo de un archivo capturado.<jupyter_code>capture_file = S3Downloader.read_file(capture_files[-1])

print("=====Single Data Capture====")
print(json.dumps(json.loads(capture_file.split('\n')[0]), indent=2)[:2000])<jupyter_output>=====Single Data Capture====
{
  "captureData": {
    "endpointInput": {
      "observedContentType": "text/csv",
      "mode": "INPUT",
      "data": "36,2500000,90000000",
      "encoding": "CSV"
    },
    "endpointOutput": {
      "observedContentType": "text/csv; charset=utf-8",
      "mode": "OUTPUT",
      "data": "607216.25",
      "encoding": "CSV"
    }
  },
  "eventMetadata": {
    "eventId": "db8d30cb-15ef-449c-9b82-0bfb8e831415",
    "inferenceTime": "2020-09-02T16:22:34Z"
  },
  "eventVersion": "0"
}<jupyter_text>Cada request es capturado en una linea del archivo jsonl. La linea contiene el input y el output del modelo. --- MonitoreoAmazon SageMaker Model Monitor permite monitorear y evaluar la data procesada por los endpoint. Funciona así:1. Se tiene que crear una linea base para comparar contra el trafico en tiempo real 2. Cuando la linea base esta lista, se puede evaluar continuamente el trafico contra la linea base. 3. Se puede enviar trafico sintético para activar las alarmas del monitoreo.**Este proceso se puede demorar mas de 1 hora porque el pool mas corto de monitoreo es una hora, se va a mostrar resultados obtenidos con otro modelo de forma previa**  Linea base y monitoreo continuo 1. Sugerencias con el dataset de la linea base (training)Generalmente, la data de training es un buen dataset para la linea base Se debe tener en cuenta que el datase de training y el dataset de inferencia deben coincidir (Deben tener el mismo numero de features y el tipo de dato de cada una debe corresponder).Se va a utilizar el dataset de training, pero con los nombres de las columnas para tener el nombre descriptivo las features.<jupyter_code>train.to_csv("/root/demo-sagemaker/notebooks/data/training-dataset-with-header.csv", sep=',', decimal='.', index=False, header=True)

baseline_prefix = prefix + '/baselining_v1'
baseline_data_prefix = baseline_prefix + '/data'
baseline_results_prefix = baseline_prefix + '/results'

baseline_data_uri = 's3://{}/{}'.format(bucket,baseline_data_prefix)
baseline_results_uri = 's3://{}/{}'.format(bucket, baseline_results_prefix)
print('Baseline data uri: {}'.format(baseline_data_uri))
print('Baseline results uri: {}'.format(baseline_results_uri))
baseline_data_path = S3Uploader.upload("/root/demo-sagemaker/notebooks/data/training-dataset-with-header.csv", baseline_data_uri)<jupyter_output>Baseline data uri: s3://lbk-analytics-dev/sagemaker/demo/baselining_v1/data
Baseline results uri: s3://lbk-analytics-dev/sagemaker/demo/baselining_v1/results<jupyter_text>Crear un baselining job  con el dataset de entrenamientoTeniendo la data lista en S3, se va a iniciar el job de la linea base.<jupyter_code>my_default_monitor = DefaultModelMonitor(role=role,
                                         instance_count=1,
                                         instance_type='ml.m5.xlarge',
                                         volume_size_in_gb=20,
                                         max_runtime_in_seconds=3600,
                                        )

baseline_job = my_default_monitor.suggest_baseline(baseline_dataset=baseline_data_path,
                                                   dataset_format=DatasetFormat.csv(header=True),
                                                   output_s3_uri=baseline_results_uri,
                                                   wait=True
)<jupyter_output><empty_output><jupyter_text>Cuando el job sea creado, se puede explorar la ruta de `baseline_results_uri` para ver que archivos son persistidos.<jupyter_code>print("Found Files:")
S3Downloader.list("s3://{}/{}".format(bucket, baseline_results_prefix))<jupyter_output>Found Files:<jupyter_text>Se tiene el archivo `constraints.json` que tiene la información del los constraints sugeridos. Ademas se tiene el archivo `statistics.json` que tiene la información estadística sobre los datos en la linea base.<jupyter_code>baseline_job = my_default_monitor.latest_baselining_job
schema_df = pd.io.json.json_normalize(baseline_job.baseline_statistics().body_dict["features"])
schema_df.head(10)
constraints_df = pd.io.json.json_normalize(baseline_job.suggested_constraints().body_dict["features"])
constraints_df.head(10)<jupyter_output>WARNING:sagemaker:Parameter 'session' will be renamed to 'sagemaker_session' in SageMaker Python SDK v2.
/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:1: FutureWarning: pandas.io.json.json_normalize is deprecated, use pandas.json_normalize instead
  """Entry point for launching an IPython kernel.<jupyter_text>2. Analizando las capturas subsecuentes para temas de calidad de datosCon el dataset de la linea base, constraints y estadísticas, se va a monitorear y analizar la data enviada al endpoint. Create a scheduleSe va a crear un monitoring schedule para el endpoint. El schedule especifica la periodicidad en que se va a ejecutar un nuevo trabajo de procesamiento para comparar los resultados con la linea base.<jupyter_code># First, copy over some test scripts to the S3 bucket so that they can be used for pre and post processing
code_prefix = '{}/code'.format(prefix)
#pre_processor_script = S3Uploader.upload("/root/demo-sagemaker/notebooks/preprocessor.py", 's3://{}/{}'.format(bucket,code_prefix))
s3_code_postprocessor_uri = S3Uploader.upload("/root/demo-sagemaker/notebooks/postprocessor.py", 's3://{}/{}'.format(bucket,code_prefix))<jupyter_output><empty_output><jupyter_text>Se va a crear el model monitoring schedule para el Endpoint creado anteriormente, con los recursos de la linea base (constraints y statistics) que fueron generados anteriormente.<jupyter_code>from sagemaker.model_monitor import CronExpressionGenerator
from time import gmtime, strftime

reports_prefix = '{}/reports'.format(prefix)
s3_report_path = 's3://{}/{}'.format(bucket,reports_prefix)

mon_schedule_name = 'demo-family-expensives-xgboost-model-schedule-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
my_default_monitor.create_monitoring_schedule(monitor_schedule_name=mon_schedule_name,
                                              endpoint_input=xgb_predictor.endpoint,
                                              #record_preprocessor_script=pre_processor_script,
                                              post_analytics_processor_script=s3_code_postprocessor_uri,
                                              output_s3_uri=s3_report_path,
                                              statistics=my_default_monitor.baseline_statistics(),
                                              constraints=my_default_monitor.suggested_constraints(),
                                              schedule_cron_expression=CronExpressionGenerator.hourly(),
                                              enable_cloudwatch_metrics=True,
                                             )<jupyter_output>WARNING:sagemaker:Parameter 'session' will be renamed to 'sagemaker_session' in SageMaker Python SDK v2.
WARNING:sagemaker:Parameter 'session' will be renamed to 'sagemaker_session' in SageMaker Python SDK v2.
INFO:sagemaker:Creating monitoring schedule name demo-xgboost-customer-churn-model-schedule-2020-08-26-16-13-37.<jupyter_text>3. Generación de traficoEl siguiente bloque genera trafico al endpoint de forma automática.  Si no hay trafico, el monitoreo de los jobs no se podra ejecutar.La siguiente celda se tiene que detener manualmente.<jupyter_code>from threading import Thread

runtime_client = boto3.client('runtime.sagemaker')

# (just repeating code from above for convenience/ able to run this section independently)
def invoke_endpoint(ep_name, file_name, runtime_client):
    with open(file_name, 'r') as f:
        i=0
        for row in f:
            payload = row.rstrip('\n')
            response = runtime_client.invoke_endpoint(EndpointName=ep_name,
                                          ContentType='text/csv', 
                                          Body=payload)
            response['Body'].read()
            sleep(1)
            i += 1
            if not (i % 100):
                print(i)
            
def invoke_endpoint_forever():
    while True:
        invoke_endpoint(endpoint_name, '/root/demo-sagemaker/notebooks/data/test_without_label.csv', runtime_client)
        
#thread = Thread(target = invoke_endpoint_forever)
#thread.start()
invoke_endpoint_forever()

# Note that you need to stop the kernel to stop the invocations<jupyter_output>100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
1900
2000
2100
2200
2300
2400
100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
1900
2000<jupyter_text>Listar ejecucionesUna vez el schedule este activo, el job se va a ejecutar en intervalos específicos. El siguiente código muestra las ultimas 5 ejecuciones y se tiene que ejecutar 1 hora después de iniciar la celda anterior para que muestre resultados.<jupyter_code>mon_executions = my_default_monitor.list_executions()
if len(mon_executions) == 0:
    print("We created a hourly schedule above and it will kick off executions ON the hour.\nWe will have to wait till we hit the hour...")

while len(mon_executions) == 0:
    print("Waiting for the 1st execution to happen...")
    time.sleep(60)
    mon_executions = my_default_monitor.list_executions()  
#Evaluate the latest execution and list the generated reports
latest_execution = mon_executions[-1]
latest_execution.wait()
print("Latest execution result: {}".format(latest_execution.describe()['ExitMessage']))
report_uri = latest_execution.output.destination

print("Found Report Files:")
S3Downloader.list(report_uri)
#If there are any violations compared to the baseline, they will be generated here. Let's list the violations.
violations = my_default_monitor.latest_monitoring_constraint_violations()
pd.set_option('display.max_colwidth', -1)
constraints_df = pd.io.json.json_normalize(violations.body_dict["violations"])
constraints_df.head(10)
#You can plug in the processing job arn for a single execution of the monitoring into this notebook to see more detailed visualizations of the violations and distribution statistics of the data captue that was processed in that execution
latest_execution.describe()['ProcessingJobArn']<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09643884096438841, 'fraction_numerical': 0.024257170242571704, 'mean_word_length': 3.612650909709233, 'pattern_counts': {'":': 37, '<': 60, '<?xml version=': 0, '>': 61, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 73, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '396002', 'license': 'Apache-2.0', 'n_tokens_mistral': 8727, 'n_tokens_neox': 8224, 'n_words': 2131, 'path': 'notebooks/sagemaker_studio.ipynb', 'repo_name': 'ivancho82/demo-sagemaker', 'size': '27126'}