Un ejemplo práctico de cómo usar la api del estimador con TensorFlow

TensorFlow es una biblioteca de código abierto que se utiliza para la creación de modelos de Machine Learning desarrollada por Google. Se caracteriza por ser flexible y ofrecer una amplia gama de herramientas para su implementación, como por ejemplo la API del estimador o Estimators API.

Con esta API se reduce el código estándar necesario para preparar un modelo de TensorFlow. Pero la mejor manera de entender cómo funciona es a través de un ejemplo práctico. Por ello, hemos elegido el trabajo que hicimos para uno de nuestros clientes para contártelo.

Este cliente, líder mundial en soluciones de seguridad, ofrece una amplia gama de soluciones dirigidas a numerosos sectores y segmentos de clientes, desde pequeñas empresas hasta grandes complejos industriales. Uno de sus servicios más destacados es el Centro de Operaciones, también conocido como SOC, cuyo objetivo es proporcionar soluciones vanguardistas y diferenciadoras mediante el uso de las tecnologías más innovadoras y la supervisión continua de sus clientes.

Entre otras cosas, el SOC es responsable de recibir y administrar los mensajes de falla en sus dispositivos de vigilancia. Dentro del proceso de gestión de dichos avisos, hay un operador en el SOC que, en un momento dado, tiene que tomar la decisión de dónde enviar dicho aviso. Se puede enviar a un técnico de sala que intente resolver el problema de manera remota, o a un técnico de campo que resuelva el problema moviéndose físicamente al dispositivo dañado.

El objetivo de esta solución es generar un modelo predictivo confiable, que en el futuro podría permitir crear una herramienta capaz de ayudar al operador de SOC a la hora de decidir dónde derivar cada falla, con el fin de mejorar sus índices de éxito y, por lo tanto, generar un ahorro para nuestro cliente.

Data pipeline: análisis de datos, procesamiento y entrenamiento del modelo

Uno de los pasos más importantes y difíciles en un proyecto de datos es la adquisición de datos, sobretodo cuando vienen en archivos .csv. Se debe manejar en un proceso ETL para que se use correctamente. En una visión general de alto nivel, el flujo de la tubería (pipeline) de datos:

google-tensorfloe

  • El conjunto de datos original se carga en un contenedor en archivos .csv
  • Una vez que los datos se almacenan en el almacenamiento en la nube, se activa una función de la nube como parte del proceso ETL. La función de nube (disponible aquí) está estructurada con diferentes objetivos, pero el proceso más importante se puede describir en la siguiente captura de pantalla:
# Phase of analysis of the data set.
    
	df = preprocess_dataset(df)
    
	# Processing phase of the data set.
    
	df = analyze_and_process_dataset(df, bucket, local_tmp_path, column_codes_path, dataset_training_path, dataset_original_name)
    
	# Model training on ML Engine
    
	train_model_in_ml_engine(
    	project_name,
    	'gs://' + bucket_name + '/' + ml_engine_job_info_path,
    	ml_engine_package_uris.split(','),
    	'gs://' + bucket_name + '/' + dataset_training_path + 'data-' + dataset_original_name,
    	'gs://' + bucket_name + '/' + dataset_training_path + 'test-' + dataset_original_name)

Como se puede observar, en primer lugar se realiza un proceso previo de datos, por lo que los archivos de marco de datos de panda se generan y almacenan en el almacenamiento en la nube (paso 3). Luego, ese nuevo conjunto de datos preprocesados ​​se analiza, procesando el conjunto de datos, almacenando los archivos de codificación de las columnas y los conjuntos de datos en Almacenamiento en la nube (paso 4) para garantizar que se pueda realizar la capacitación y evaluación del modelo (paso 5).

Todas las cloud functions se basan en trabajos previos realizados en cuadernos locales a través de datalab.

El primer paso importante de la cloud function es el primer preprocesamiento de datos donde:

  • Se eliminan algunos campos innecesarios
# Drop columns with very scattered initial values.

df = df.drop(['alarm_incident_full_clear_opactdisp_id', 'alarm_incident_full_clear_emp_no', 'event_history_test_seqno', 'site_install_servco_no'], axis=1)
df = df.reset_index(drop=True)
# Drop columns whose content does not contribute

df = df.drop(['event_history_event_id', 'alarm_incident_status', 'comment'], axis=1)
  • Algunos otros campos están preprocesados ​​(rellenando algunos campos faltantes por valores predeterminados o siendo formateados):
df['event_history_event_id'] = df['event_history_event_id'].str.strip()
  # Replacing and drop empty strings with NaN values

             df['alarm_incident_delay_seconds'].replace('', np.nan, inplace=True)
	df['system_systype_id'].replace('', np.nan, inplace=True)
	df['site_site_no'].replace('', np.nan, inplace=True)
	df['site_sitetype_id'].replace('', np.nan, inplace=True)
	df['site_sitestat_id'].replace('', np.nan, inplace=True)
	df['alarm_incident_status'].replace('', np.nan, inplace=True)
	df['system_Nzonas'].replace('', np.nan, inplace=True)
	df['site_Nvias'].replace('', np.nan, inplace=True)
	df['site_cspart_no'].replace('', np.nan, inplace=True)
	df['site_siteloc_id'].replace('', np.nan, inplace=True)
	df['alarm_incident_alarminc_no'].replace('', np.nan, inplace=True)
	df['comment'].replace('', np.nan, inplace=True)
# Remove blank spaces from columns with identifiers

	df['system_systype_id'] = df['system_systype_id'].str.strip()
	df['site_sitetype_id'] = df['site_sitetype_id'].str.strip()
	df['site_sitestat_id'] = df['site_sitestat_id'].str.strip()
	df['event_history_event_id'] = df['event_history_event_id'].str.strip()
	df['site_siteloc_id'] = df['site_siteloc_id'].str.strip()

	df = df.reset_index(drop=True)

En el proceso de analizar el conjunto de datos, se obtienen nuevas variables a partir de los datos originales.

# Processing the date to obtain the day of the week, month and season of the year

	df['event_history_event_date'] = pd.to_datetime(df['event_history_event_date'])
	df['day_of_week'] = df['event_history_event_date'].dt.weekday_name

	df['month'] = df['event_history_event_date'].dt.month

	df = df.drop(list(df.filter(regex='date')), axis=1)

	df['season'] = 3

	df.loc[(df['month']==3) | (df['month']==4) | (df['month']==5), 'season'] = 0
	df.loc[(df['month']==6) | (df['month']==7) | (df['month']==8), 'season'] = 1
	df.loc[(df['month']==9) | (df['month']==10) | (df['month']==11), 'season'] = 2

En el proceso del conjunto de datos, se almacenan los archivos de codificación de las columnas y los conjuntos de datos en el almacenamiento en la nube, por lo que se podría realizar una capacitación y una evaluación del modelo.

# Encodings of text variables to unique identifiers and storage in Cloud Storage for use by other CFs
    
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'system_systype_id', column_codes_path, 'systypeId_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'site_sitetype_id', column_codes_path, 'sitetypeId_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'site_sitestat_id', column_codes_path, 'sitestatId_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'site_siteloc_id', column_codes_path, 'sitelocId_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'day_of_week', column_codes_path, 'dayofweek_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'site_site_no', column_codes_path, 'siteNo_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'site_cspart_no', column_codes_path, 'cspartNo_cod.pkl')
	df = encode_values_to_pickle_and_upload_to_cloud_storage(df, bucket, local_tmp_path, 'system_system_no', column_codes_path, 'systemNo_cod.pkl')

	df['system_systype_id'] = df['system_systype_id_coded']
	df['site_sitetype_id'] = df['site_sitetype_id_coded']
	df['site_sitestat_id'] = df['site_sitestat_id_coded']
	df['site_siteloc_id'] = df['site_siteloc_id_coded']
	df['day_of_week'] = df['day_of_week_coded']
	df['site_site_no'] = df['site_site_no_coded']
	df['site_cspart_no'] = df['site_cspart_no_coded']
	df['system_system_no'] = df['system_system_no_coded']

	df = df.drop('system_systype_id_coded', axis=1)
	df = df.drop('site_sitetype_id_coded', axis=1)
	df = df.drop('site_sitestat_id_coded', axis=1)
	df = df.drop('site_siteloc_id_coded', axis=1)
	df = df.drop('day_of_week_coded', axis=1)
	df = df.drop('site_site_no_coded', axis=1)
	df = df.drop('site_cspart_no_coded', axis=1)
	df = df.drop('system_system_no_coded', axis=1)

Una vez que se analizan los datos, el 85% del conjunto de datos se envía a un Almacenamiento en la Nube para ser utilizado como datos de entrenamiento y el resto a otro para ser utilizado como datos de evaluación.

   # Generation of the training and test set for the model
    
	cut = int(np.round(0.85 * df.shape[0]))
    
	upload_in_csv_to_cloud_storage(df.iloc[0:cut], bucket, local_tmp_path, datasets_training_path, 'data-' + datasets_training_name)
	upload_in_csv_to_cloud_storage(df.iloc[cut+1:df.shape[0]], bucket, local_tmp_path, datasets_training_path, 'test-' + datasets_training_name)

Finalmente, para verificar que el modo actual sigue siendo válido para el nuevo conjunto de datos, y no hay ninguna variable que deba ser revisada, creamos y enviamos un trabajo de entrenamiento de modelo básico (tipo de entrenamiento) nuevamente a ML Engine con el entrenamiento y generó conjuntos de datos para fines de prueba.

 project_id = 'projects/{}'.format(project_name)
    
	job_name = 'origen_ticketing_tf_pipeline_trigger_' + time.strftime('%Y%m%d_%H%M%S')
    
	training_inputs = {
    		'runtimeVersion': '1.10',
    		'jobDir': job_dir + job_name,
    		'packageUris': package_uris,
    		'pythonModule': 'trainer.task',
    		'region': 'europe-west1',
   		 'args': [
        			'--train-file', train_file,
        			'--eval-file', eval_file
    		]}
    
	job_spec = {'jobId': job_name, 'trainingInput': training_inputs}
    
	cloudml = discovery.build('ml', 'v1')
    
	request = cloudml.projects().jobs().create(body=job_spec, parent=project_id)
    
	try:
    		response = request.execute()
	except HttpError as err:
    		# Do whatever error response is appropriate for your application.
    		# For this example, just send some text to the logs.
    		# You need to import logging for this to work.
    		logging.error('There was an error creating the training job. Check the details:')
    		logging.error(err._get_reason())

Modelo en TensorFlow

Para generar un modelo de aprendizaje capaz de representar los datos antes mencionados y hacer predicciones en consecuencia, decidimos utilizar los estimadores prefabricados en TensorFlow. En particular, usamos la clase DNNClassifier para crear un clasificador de red neuronal profundo basado en Tensorflow. Se ha elegido este estimador porque algunos ensayos anteriores se realizaron en máquinas locales y las redes neuronales dieron mejores resultados que el impulso de los algoritmos de árboles, entre otros. Con respecto a otras técnicas basadas en DNN, se han realizado pruebas con DNNRegressor que también nos permite modelar redes neuronales profundas, pero que también han dado peores resultados en nuestro caso.

Por lo tanto, el primer paso fue desarrollar una biblioteca o aplicación completa con la estructura de código que contiene todas las funciones necesarias. Para ello, hemos utilizado la plantilla de Google Cloud para aplicaciones ML. Estas funciones se ocupan de la definición de la estructura de datos, un poco de preprocesamiento de datos (selección de tipos de datos, transformación de variables categóricas ...), la creación del esquema de red neuronal profundo correspondiente, el diseño de la evaluación de ajuste de hiperparámetros y, finalmente, la Entrenamiento de la red neuronal y su evaluación en el conjunto de pruebas. Nuestro código contiene las siguientes funciones y estructura de directorios:

modelo-tensorflow

  • trainer: subdirectorio para almacenar el módulo principal de la aplicación.
  • __init__.py: ID de archivo que utilizan las herramientas de configuración para identificar directorios con código para empaquetar.
  • featurizer.py: las diferentes características de los datos se tratan para convertirlos a los tipos y estructuras adecuados, algunas transformaciones ...
  • input.py: los archivos de entrada para los conjuntos de entrenamiento y evaluación se recopilan de los depósitos de almacenamiento correspondientes y se transforman en el formato de tensorflow.
  • metadata.py: algunos parámetros necesarios para la ejecución de la estructura de código están codificados en esta función.
  • model.py: se elige el algoritmo de aprendizaje automático y se diseña su arquitectura. Además, los experimentos de capacitación y evaluación se ejecutan aquí.
  • task.py: los argumentos se analizan desde la consola y la función principal reside aquí.
  • config.yaml: contiene las diferentes configuraciones de hiperparámetros de prueba al entrenar a su modelo para maximizar la precisión predictiva de su modelo.
  • sample.py: script para generar instancias JSON de muestra para probar predicciones en línea.
  • setup.py: archivo con información del módulo.

Con respecto a la definición de arquitectura de red neuronal (basada en DNNClassifier), se han tomado algunas decisiones. En el caso del optimizador, Adagrad ha sido elegido debido a la escasez de datos y debido a su robustez mejorada en comparación con el tradicional Descenso Estocástico del gradiente.

Las funciones de activación consisten en funciones lineales rectificadas para las capas medias, que es la más aceptada en la literatura, y la función logística en la última capa (para hacer la clasificación).

Además, el abandono se está utilizando para la regularización de la red. Finalmente, algunos hiperparámetros se han ajustado con la implementación del algoritmo de optimización bayesiana de Google: número de capas en la red, el factor de escala de tamaño entre capas, la tasa de aprendizaje.

dnn_optimizer = tf.train.AdagradOptimizer(learning_rate = task.HYPER_PARAMS.learning_rate)

estimator = tf.estimator.DNNClassifier(
	
	n_classes = len( metadata.TARGET_LABELS),
	label_vocabulary = metadata.TARGET_LABELS,

	feature_columns = deep_columns,
	optimizer = dnn_optimizer,

	weight_column = metadata.WEIGHT_COLUMN_NAME,

	hidden_units = construct_hidden_units(),
	activation_fn = tf.nn.relu
	dropout = task.HYPER_PARAMS.dropout_prob,

	config = config,
)

Tuning del modelo con hiperparámetros

El resultado del flujo de datos fue un conjunto de datos final con 173679 filas y 49 columnas, incluida la etiqueta. Es bien sabido que para la fase de aprendizaje, es una buena práctica dividir el conjunto de datos original en conjuntos de entrenamiento, evaluación y prueba para trabajar con datos independientes en el entrenamiento, ajuste de hiperparámetros y evaluación de datos invisibles. Por lo tanto, los datos originales se dividieron en 85% para capacitación y evaluación (para ajuste de hiperparámetro) y 15% para prueba.

Para realizar el ajuste de hiperparámetro, se ha utilizado una máquina personalizada porque la configuración se ha optimizado paso a paso para reducir el tiempo total de procesamiento utilizado por la tarea. El objetivo del algoritmo es maximizar la precisión del modelo, usar una parada temprana para evitar el sobreajuste y con 5 intentos como máximo, ya que para mayores intentos hemos verificado que no se obtiene un gran aumento en el éxito. El rango de búsqueda de las diferentes variables a optimizar se ha elegido de acuerdo con las experiencias anteriores y el conocimiento de su comportamiento, lo que resulta en la siguiente configuración:

Donde queremos detallar las siguientes configuraciones:

trainingInput:
	scaleTier: CUSTOM
	masterType: large_model
	workerType: complex_model_m
	parameterServerType: large_model
	workerCount: 10
	parameterServerCount: 5
	hyperparameters:
		goal: MAXIMIZE
		hyperparameterMetricTag: accuracy
		enableTrialEarlyStopping: True
		maxTrials: 5
		maxParallelTrials: 2

		params:
parameterName: num-layers
	type: DISCRETE
	discreteValues:
2
3
4
	scaleType: UNIT_LINEAR_SCALE
parameterName: layer-sizes-scale-factor
	type: DOUBLE
	minValue: 0.2
	maxValue: 0.8
	scaleType: UNIT_LINEAR_SCALE
parameterName: learning-rate
type: DOUBLE
minValue: 0.0001
maxValue: 0.01
scaleType: UNIT_LOG_SCALE

En cuanto a la ejecución de "--scale-level STANDARD_1" y "--scale-tier BASIC", tardan mucho tiempo en completar la tarea y, en algunos casos, devuelven errores en los workers para los permisos y la memoria. Así que decidimos personalizar los grupos de trabajo con:

  • Master como tipo de modelo de gran tamaño, una máquina con mucha memoria, especialmente adecuada para servidores de parámetros cuando su modelo es grande.
  • Worker como tipo complex_model_m, una máquina con aproximadamente el doble de núcleos y el doble de memoria de complex_model_s.
  • El recuento de Workers es el número de réplicas de Workers que se utilizan para el trabajo de capacitación. Hemos configurado 10 Workers para admitir el número máximo de capacitación (maxTrial) para la ejecución paralela configurada (maxParallelTrials) sin bloqueos.
  • El número de réplicas del servidor de parámetros a usar para el trabajo de capacitación. Hemos configurado 5 servidores para admitir la cantidad máxima de capacitación (maxTrial).

El objetivo (objetivo) del algoritmo es maximizar la precisión del modelo (hyperparameterMetricTag), utilizando la detención temprana (enableTrialEarlyStopping) para evitar el sobreajuste y con 5 intentos como máximo (maxTrials).

El rango de búsqueda para las diferentes variables a optimizar (número de capa, factor de escala de tamaño de capa, tasa de aprendizaje) se ha elegido de acuerdo con las experiencias anteriores y el conocimiento de su comportamiento.

Después de completar el número máximo de pruebas, 5, se ha obtenido un modelo optimizado con los siguientes hiperparámetros finales:

“hyperparameters”: {
	“num-layers”: “4”,
	“learning-rate”: “0.0014479715888709816”,
	“layer-sizes-scale-factor”: “0.75728686112411281”
},

Y los siguientes resultados finales (con el máximo de 30 pruebas que hemos ejecutado, solo se mejoró el 1.5 por ciento):

“finalMetric”: {
	“trainingStep”: “1006”,
	“objectiveValue”: 0.625320017338
}

Entrenamiento del modelo usando cloud ML Engine

Para cargar los trabajos de capacitación e hiperparámetros de ajuste al motor ML para que sean efectivos en Google Cloud, los comandos deben enviarse a través de la consola. En primer lugar, se definen las principales variables:

DATE=`date '+%Y%m%d_%H%M%S'`
export JOB_NAME=origen_ticketing_tf_$DATE
export GCS_JOB_DIR=gs://com-soc-projectdata/OrigenTicketingTF/jobinfo/$JOB_NAME

export TRAIN_FILE=gs://com-soc-projectdata/OrigenTicketingTF/dataset-training/data-mmm.csv
export EVAL_FILE=gs://com-soc-projectdata/OrigenTicketingTF/dataset-training/test-mmm.csv

export HPTUNING_CONFIG=config.yaml

export TRAIN_STEPS=2000
export EVAL_STEPS=500

export REGION=europe-west1

Los comandos de GCloud que se envían para los trabajos de ajuste del hiperparámetro son:

gcloud ml-engine jobs submit training $JOB_NAME \
    --stream-logs \
    --runtime-version 1.10 \
    --config $HPTUNING_CONFIG \
    --job-dir $GCS_JOB_DIR \
    --module-name trainer.task \
    --package-path trainer/ \
    --region $REGION \
    -- \
    --train-file $TRAIN_FILE \
    --eval-file $EVAL_FILE \
    --train-steps $TRAIN_STEPS \
    --eval-steps $EVAL_STEPS 

Los comandos de GCloud usados para envío sin hiperparámetros son estos:

gcloud ml-engine jobs submit training $JOB_NAME \
    --stream-logs \
    --runtime-version 1.10 \
    --job-dir $GCS_JOB_DIR \
    --module-name trainer.task \
    --package-path trainer/ \
    --region $REGION \
    -- \
    --train-file $TRAIN_FILE \
    --eval-file $EVAL_FILE \
    --train-steps $TRAIN_STEPS \
    --eval-steps $EVAL_STEPS 

Evaluación del modelo

Una vez que se entrenó el modelo de clasificación optimizado, fue necesario probar y validar su rendimiento. Para tal tarea, el modelo se ha evaluado en el conjunto de pruebas (15% del conjunto de datos completo) con una precisión final del 62.53%.

Teniendo en cuenta los resultados logrados en este estudio en particular, y considerando otras pruebas que se realizaron en una máquina local utilizando diferentes valores para los parámetros, otros métodos de aprendizaje y características de entrada ... los resultados parecen bastante buenos, pero hay margen de mejora. Por ejemplo, se podría hacer un poco más de ingeniería de características, haciendo uso, por ejemplo, de las capacidades de TensorFlow implementadas para tratar directamente con variables categóricas. Por otro lado, el clasificador DNNLinearCombined parece bastante prometedor según la literatura, por lo que probarlo podría ser una buena opción.

Además, los resultados son buenos si los comparamos con el operativo actual al tomar decisiones sobre el origen de un problema para nuestro caso real basado en la demostración, que tiene una precisión del 50%.

Para implementar el modelo en ML Engine con el fin de hacer nuevas predicciones, el modelo debe cargarse con los comandos de consola necesarios. Así, se establece el servicio de predicción:

export MODEL_BINARIES=$GCS_JOB_DIR/export/estimator/<timestamp>

gcloud ml-engine versions create <version> --model origen_ticketing_tf --origin $MODEL_BINARIES --runtime-version 1.10

Inspecciona los modelos binarios con la CLI de SavedModel TensorFlow se envía con una CLI que permite inspeccionar la firma de los archivos binarios exportados. Para hacer esto ejecuta:

saved_model_cli show --dir $MODEL_BINARIES --tag serve --signature_def predict

Predicción online con Cloud-Fn y Web Client

La etapa final cubierta en la Demo actual está relacionada con la implementación del modelo de aprendizaje para que esté disponible para las predicciones en línea.

Primero, crea una muestra procesada de los datos de prueba:

python sample.py $EVAL_FILE sample.json

Después, envía las solicitudes de predicción a la API. Para probar esto, puede utilizar la herramienta de predicción

gcloud ml-engine predict --model origen_recomm_tf --version <version> --json-instances sample.json

¡Finalmente, deberías ver una respuesta con las etiquetas predichas de los ejemplos!

CLASS_IDS  CLASSES    LOGISTIC                          LOGITS                             PROBABILITIES
[0]                  [u'0.0']         [0.3971346318721771]  [-0.417418509721756]  [0.6028653383255005, 0.3971346318721771]

Es importante resaltar que la versión del modelo utilizada en ML Engine, que es la que está expuesta al usuario para admitir la escalabilidad, está directamente vinculada a esa en Cloud Storage.

Como dijimos anteriormente, las variables de entrada utilizadas en el modelo son inferidas por aquellas introducidas por el usuario a través de la interfaz de usuario. Eso significa que necesitábamos traducir los iniciales al último.

En uno de los pasos anteriores decidimos guardar algunas tablas de codificación para poder realizar esa traducción, teniendo en cuenta el contexto completo del conjunto de datos. Por lo tanto, definimos una función personalizada en Cloud Functions responsable de realizar la tarea mencionada. A continuación, explicaremos las partes más representativas de la función:

a) Leemos los parámetros de la solicitud: que consisten básicamente en leer las entradas proporcionadas por el usuario a través de la interfaz de usuario.

request_json = request.get_json()
alarm_delay = request_json['alarm_incident_delay_seconds']
system_no = request_json['system_system_no']
site_no = request_json['site_site_no']
n_zonas = request_json['system_Nzonas']
n_vias = request_json['site_Nvias']
cspart_no = request_json['site_cspart_no']
alarminc_no = request_json['alarm_incident_alarminc_no']
rec_date = request_json['event_history_event_date']
systype_id = request_json['system_systype_id']
sitetype_id = request_json['site_sitetype_id']
sitestat_id = request_json['site_sitestat_id']
siteloc_id = request_json['site_siteloc_id']

b) Cargamos las tablas de codificación: que contienen las equivalencias entre los valores originales y los valores codificados.

blob = bucket.blob('newModel_fromV3/dayofweek_cod.pkl')
	blob.download_to_filename('/tmp/dayofweek_cod.pkl')    
	dow_cod = pandas.read_pickle('/tmp/dayofweek_cod.pkl')
    
	blob = bucket.blob('newModel_fromV3/sitelocId_cod.pkl')
	blob.download_to_filename('/tmp/sitelocId_cod.pkl')    
	siteloc_cod = pandas.read_pickle('/tmp/sitelocId_cod.pkl')
    
	blob = bucket.blob('newModel_fromV3/sitestatId_cod.pkl')
	blob.download_to_filename('/tmp/sitestatId_cod.pkl')    
	sitestat_cod = pandas.read_pickle('/tmp/sitestatId_cod.pkl')
    
	blob = bucket.blob('newModel_fromV3/sitetypeId_cod.pkl')
	blob.download_to_filename('/tmp/sitetypeId_cod.pkl')    
	sitetype_cod = pandas.read_pickle('/tmp/sitetypeId_cod.pkl')
    
	blob = bucket.blob('newModel_fromV3/systypeId_cod.pkl')
	blob.download_to_filename('/tmp/systypeId_cod.pkl')    
	systype_cod = pandas.read_pickle('/tmp/systypeId_cod.pkl')

c) Obtenemos y almacenamos los valores codificados y generamos nuevas variables cuando sea necesario: como sucede con los inferidos de la variable de fecha.

# Get the "system_systype_id" codification    
	syst_c = systype_cod[systype_cod['system_systype_id'] == str(systype_id)]
	new_syst = -1 # Default
	if syst_c.size > 0:
    		new_syst = syst_c.iloc[0]['system_systype_id_coded']
    
	# Get the "site_sitetype_id" codification    
	sitet_c = sitetype_cod[sitetype_cod['site_sitetype_id'] == str(sitetype_id)]
	new_site = -1 # Default
	if sitet_c.size > 0:
    		new_site = sitet_c.iloc[0]['site_sitetype_id_coded']
    
	# Get the "site_sitestat_id" codification    
	sitest_c = sitestat_cod[sitestat_cod['site_sitestat_id'] == str(sitestat_id)]
	new_sitest = -1 # Default
	if sitest_c.size > 0:
    		new_sitest = sitest_c.iloc[0]['site_sitestat_id_coded']
    
	# Get the "site_siteloc_id" codification    
	sitel_c = siteloc_cod[siteloc_cod['site_siteloc_id'] == str(siteloc_id)]
	new_sitel = -1 # Default
	if sitel_c.size > 0:
    		new_sitel = sitel_c.iloc[0]['site_siteloc_id_coded']
# Get the "event_history_event_date" codification
    
	dateDF = pandas.DataFrame(columns=['date'])
	dateDF.loc[0] = [rec_date]
	day = pandas.to_datetime(dateDF['date']).dt.weekday_name.iloc[0]
	month = pandas.to_datetime(dateDF['date']).dt.month.iloc[0]
    
	day_c = dow_cod[dow_cod['day_of_week'] == day]
	new_day = day_c.iloc[0]['day_of_week_coded']
    
	season=-1
	if ((month==3) or (month==4) or (month==5)):
    		season = 0
	else:
    		if ((month==6) or (month==7) or (month==8)):
        			season = 1
    		else:
        			if ((month==9) or (month==10) or (month==11)):
            				season = 2
        			else:
            				season = 3

d) Creamos la nueva instancia: que se utilizará para obtener una predicción del modelo.

instance = [str(alarm_delay), str(system_no), str(site_no), str(n_zonas), str(n_vias), str(cspart_no), str(alarminc_no), str(month), str(season), str(new_syst), str(new_site), str(new_sitest), str(new_sitel), str(new_day)]

e) Enviamos la solicitud de predicción.

prediction = send_to_predict_in_ml_engine('securitas-ml-starter', 'origen_ticketing_sl', instance, 'v3')

f) Devolvemos el resultado dado por el modelo.

# Return the result of the predictions
	if 'error' in prediction:
    		return (flask.jsonify(prediction['error']), 500, headers)
       	 
	return (flask.jsonify(prediction['predictions']), 200, headers)

 

¿Quieres transformar tu empresa con tecnologías de futuro?

fondo-footer
base pixel px
Convert
Enter PX px
or
Enter EM em
Result