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.