Blog de Amazon Web Services (AWS)

Clasificación de comentarios serverless con SageMaker y scikit learn

Por María Gaska, AI/ML Specialist SA de AWS

 

Cada vez más, es importante para las instituciones financieras apalancarse en las redes sociales para mejorar la relación con sus usuarios y comprender por qué se producen los distintos reclamos. Con este objetivo en mente recolectamos los comentarios públicos que los usuarios fueron dejando a las distintas instituciones bancarias de Colombia y los etiquetamos según la dimensión.

El desafío en este caso es construir un modelo que permita clasificar los reclamos en tiempo real para derivarlos al área correspondiente para su resolución.

En este artículo no se pretende mostrar las técnicas más avanzadas de NLP (procesamiento del lenguaje natural) si no demostrar utilizando un ejemplo simple e intuitivo cómo construir un micro servicio que entregue predicciones de un modelo de scikit learn.

 

Resumen de la solución

En este artículo vamos a desarrollar un modelo utilizando SageMaker Studio y scikit learn que luego vamos a implementar como microservicio serverless con la ayuda de Lambda y API Gateway.

 

 

Paso 1: Seleccionar el kernel e instalar las librerías

Para tener un control completo sobre el entorno donde vamos a desarrollar el modelo, dentro de los kernels de SageMaker Studio se debe seleccionar

Python 3(Base Python), un ambiente virtual de Anaconda vacío donde podemos instalar todas las librerías necesarias.

!pip install scikit-learn==0.21.3 pandas==1.1.1 seaborn sagemaker --use-feature=2020-resolver

También vamos a descargar el data set.

!wget https://serverless-text-classification.s3.amazonaws.com/sentiment_banking.csv

 

Paso 2: Explorar los datos

A continuación exploramos el data set.

df = pd.read_csv('sentiment_banking.csv')

df.head()

label='Dimensión'

df['Mensaje'] = df['Mensaje'].str.lower()

df[label].value_counts()
Tipo #
atención al ciente 1769
servicio 819
sociedad 777
innovación 726
ética 440

Paso 3: Construir el modelo

Para convertir el texto en un formato que sea manejable por los modelos de Machine Learning de scikit learn, necesitamos transformarlo en una representación numérica. Para esto vamos a utilizar la clase TfIdf que permite representar las palabras según su nivel de ocurrencia en cada texto, en comparación con su ocurrencia en el DataFrame completo. Sobre estos valores transformados vamos a entrenar un modelo predictivo utilizando un GradientBoostingClassifier.

train, test = train_test_split(df,test_size=0.33,random_state=42)

train_y = train[label]

train_X = train['Mensaje']

vec = TfidfVectorizer(ngram_range=(1, 2),min_df=4)

model = GradientBoostingClassifier(n_estimators=140)

clf = make_pipeline(vec,model)

clf = clf.fit(train_X, train_y)

 

Paso 4: Evaluación del modelo

Ahora vamos a evaluar las predicciones del modelo sobre el conjunto de test que separamos más arriba

test_y = test[label]

test_X = test['Mensaje']

predictions = clf.predict(test_X)

accuracy_score(test_y,predictions)

Con este modelo obtenemos un accuracy de 0.7585

Veamos ahora en detalle la matriz de confusión:

 

Como era de esperarse, las clases más difíciles de distinguir son “servicio” y “atención al cliente”.

 

Paso 5: Serializar el modelo y subirlo a S3

Ahora convertimos el modelo en un pickle file y vamos a subirlo a S3 para que esté disponible desde la función lambda.

filename = 'model.pkl'

pickle.dump(clf, open(filename, 'wb'))

session.upload_data('model.pkl',key_prefix='models')

 

Paso 6: Construir una lambda layer

Como primer paso para crear un API que permita predecir con este modelo, necesitamos replicar las librerías de este entorno. Esto se hace a través de una lambda layer.

Para esto vamos a descagar una lambda layer pública que contiene scikit learn 0.21.3 y todas sus dependencias, para luego subirla al bucket que venimos utilizando y construir la url resultante:

!wget https://serverless-text-classification.s3.amazonaws.com/sklearn.zip

session = sagemaker.Session()

bucket = session.default_bucket()

prefix = 'layers'

session = sagemaker.Session()

session.upload_data('./sklearn.zip',key_prefix=prefix)

url = f'https://{bucket}.s3.amazonaws.com/{prefix}/sklearn.zip'

print(url)

Desde la consola de lambda, vamos a construir la lambda layer referenciando a la ubicación en S3 donde quedó nuestro .zip con las librerías. Asegúrense de hacerlo en la misma región donde están ejecutando SageMaker Studio.

 

 

Paso 7: Construir la función lambda

Ahora que tenemos una lambda layer lista, podemos pasar a definir la función. Desde la consola de IAM, vamos a crear un rol para esta función lambda que tenga permisos de lectura sobre S3. Podemos llamarlo lambdaReadS3.

En el caso de uso seleccionamos “Lambda” y entre los permisos “AmazonS3ReadOnlyAccess”. Luego vamos a usar ese rol para crear la función lambda.

En esta función lambda necesitamos configurar también nuestro bucket entre las variables de entorno y agregar al entorno la lambda layer que acabamos de crear:

 

 

Por último, la función lambda necesita leer el modelo del bucket fuera del handler y utilizarlo para predecir.

import json

import pandas as pd

from io import StringIO

import sklearn

import pickle

import boto3

import os

s3client = boto3.client('s3')

s3bucket = os.environ['bucket']

filename = 'models/model.pkl'

temp_file =  '/tmp/'+ filename.split('/')[-1]

s3client.download_file(s3bucket, filename, temp_file)

loaded_model = pickle.load(open('/tmp/model.pkl', 'rb'))

def lambda_handler(event, context):

    payload = event['queryStringParameters']['payload']

    df = pd.read_csv(StringIO(payload),header=None)

    df[0] = df[0].str.lower()

    #

    result = loaded_model.predict(df.iloc[:,0])

    #

    return {

        'statusCode': 200,

        'body': json.dumps({'predictions':list(result)})

    }

 

Paso 8: Integración con API Gateway

Desde la consola de API Gateway vamos a crear una nuevo integración con lambda para incorporar el modelo predictivo en una Rest API.

 

 

Luego vamos a crear un método de tipo GET que se integre con nuestra lambda. Marquen la opción de Lambda Proxy Integration. La función que creamos más arriba se puede referenciar por nombre o por arn.

 

 

Una vez creado el método hay que desplegarlo desde el menú de deploy creando un nuevo stage, en este caso test.

 

 

Una vez desplegada, la API devuelve una url de invocación que es accesible públicamente. Desde esta url podemos probar las respuestas del modelo con cualquier navegador.

 

 

Conclusión

Utilizando estas herramientas podemos construir un microservicio liviano, enteramente “serverless” y por lo tanto muy efectivo desde el punto de vista de los costos y del mantenimiento de infraestructura.

Limpieza

Para evitar incurrir en cargos pueden borrar el bucket S3 que se creó, la Rest API y hacer shut down de la imagen en SageMaker Studio.

 


Sobre el autor

María Gaska es arquitecta de soluciones en AWS desde hace casi dos años. En su rol, ayuda a los clientes tanto a determinar la mejor arquitectura para sus distintas aplicaciones como a encontrar los mejores algoritmos para resolver problemas de Machine Learning e IA. Antes de AWS, trabajó como desarrolladora de modelos de deep learning en un startup enfocado en NLP y chatbots y también como profesora full time en una coding school a cargo de un curso de data science.

 

 

 

Sobre los revisores

Andres Palacios es arquitecto de soluciones especialista en Analytics en AWS. En su rol apoya a los clientes a encontrar la mejor solucion y arquitectura para sus necesidades al igual que aprovechar los servicios de AI/ML para generar innovación y mejorar la productividad. Antes de AWS, trabajó para consultoras Big Four en las áreas de Data y Analytics, tanto como en consultoría estratégica, arquitectura e implementación de soluciones de procesamiento y consumo distribuidas.

 

 

 

Sergio Beltran es arquitecto de soluciones especialista en AI/ML en AWS. En su rol apoya a los clientes a encontrar la mejor solución y arquitectura para sus necesidades al igual que aprovechar los servicios de AI/ML para generar innovación y mejorar la productividad. Antes de AWS, trabajó data scientist y gerente de business development en la industria Telco.