Saltar al contenido →

Create ML Tutorial. MLTextClassifier

¿Qué es un modelo de clasificación de texto? Pues si atendemos a lo que dicen Apple…

A text classifier is a machine learning model that’s been trained to recognize patterns in natural language text, like the sentiment expressed by a sentence.

Y eso es lo que vamos a repasar en este artículo, el soporte que nos brinda Create ML para clasificar texto.

Anteriormente en Create ML Tutorial…

El el artículo anterior vimos una introducción a Create ML y su entorno, cargamos los datos necesarios para crear un modelo y aprendimos las funciones que nos permiten modificar esos datos para adecuarlos a lo que nosotros necesitamos.

Y ahora en Create ML Tutorial…

Con los datos que generamos en el artículo anterior vamos a entrenar un modelo de clasificación texto que nos diga cómo de buena es una reseña que escriban los usurios de nuestra app y lo exportaremos al formato .mlmodel para incorporarlo a nuestra app.

Creando un MLTextClassifier

Lo primero que necesitamos es importar el framework CreateML en nuestro playground, cargar el archivo json que acompaña al playground y meterlo en un MLDataTable tal y como aprendimos en el artículo anterior.

Una vez que tenemos los datos cargados ya podemos inicializar nuestro modelo de datos.

Los valores por defecto que aplica este inicializador son, para el algoritmo se opta por maxEnt, y para la validación se escoge un 5% de los registros del MLDataTable que se pasa al parámetro trainingData.

Más adelante veremos cómo podemos escoger nosotros tanto el algortimo como los juegos de datos.

Obteniendo las métricas de evaluación

Ahora que hemos entrenado el modelo necesitamos saber cómo de efectivo es en sus predicciones al final del entrenamiento y para eso tenemos que ver el valor que tiene la propiedad classificationError de las propiedades trainingMetrics y validationMetrics del modelo.

Estas propiedades son de tipo MLClassifierMetrics, que ademas de ayudarnos a calcular la precisión del modelo también nos informa de cuando estamos obviando una de las categorias durante las predicciones, con la propiedad precisionRecall, y si el modelo confunde una categoría con otra mediante la propiedad confusion. Ambas propiedades son de tipo MLDataTable

La forma de calcular este valor es de la siguiente forma:

Así que para saber qué tal nos ha ido dutante el entrenamiento y la validación tenemos que hacer algo parecido a esto…

Afinando el modelo. ModelParameters

Los datos que hemos obtenido han sido buenos, pero se pueden mejorar y para ellos debemos ser nosotros los que decidamos qué parámetros se van a aplicar al entrenamiento del modelo, así que tenemos que usar la estructura ModelParameters, que es un tipo anidado de MLTextClassifier.

Esta estructura nos permite definir 3 parámetros:

  1. El conjunto de datos de validación. Ya no será Create ML quien decida el porcentage de datos que irá a entramiento y a validación.
  2. El algoritmo. Es la aproximación que se elige para solucionar el problema. En el caso de la clasificación de texto Create ML nos deja elegir entre 2 tipos diferentes:
    • maxEnt. O Máxima Entropía. Es el algoritmo que se emplea por defecto. Al contrario que el CRF, no cree que las entidades sean denpendientes. Su objetivo principal es encontrar las características que ayuden a resolver el problema sin detenerse en si son redundandates.
    • crf. Es el acrónimo de Conditional Random Fields. Este algoritmo asume que las entidades son dependientes unas de otras y además toma en consideración futuras observaciones mientras intenta aprender el patrón.
  3. El idioma. Podemos establecer en que idioma están disponibles nuestros datos. Bastante útil tendiendo en cuenta las diferencias gramaticales entre los distintos idiomas.

Como curiosidad decir que el valor de ModelAlgorithmType la propiedad algorithm admite un valor asociado llamado revision. Pues bien, a día de hoy ese valor sólo puede ser 1 o nil.

Si teneís curiosidad por saber qué está haciendo al algoritmo usad las propiedades description o debugDescription del mismo.

¿Y no se puede configurar más? ¿Dónde le digo los epochs? ¿Y los steps de entrenamiento?. No se le dice en ningún sitio, es CreateML el que detine el entrenamiento cuando ve que el modelo deja de aprender, por decirlo de alguna manera.

A continuación podeís ver parte del contenido del panel de depuración de Playgrounds durante el entrenamiento.

Probando el modelo. Evaluación

¿Os acordáis que antes os hablaba de las propiedades precisionRecall y confusion? Pues ahora vamos a usarlas y veréis que es lo que nos muestran.

Recordemos que precissionRecall nos dice cuando estamos obviando cierta categoría o etiquetándola de forma incorrecta, y aquí teneís la salida que nos da.

La tabla de salida tiene una fila por cada categoría que tenga nuestro modelo, en nuestro caso 5, y nos dice la cantidad a aciertos o errores que ha tenido a la hora de predecir una de las pruebas.

La propiedad confusion por su parte es la que nos dice cuando estamos cambiando una categoría por otra. Su salida es esta

La tabla de salida muestra el producto cartesiano de las categorías del modelo, donde la columna True Label es la categoría que se está evaluando en ese momento, Predicted es la categoría que ha predicho el modelo que correspondía a una prueba, y por último Count nos dirá el número de veces que ha ocurrido eso.

Por ejemplo, si nos fijamos en la línea 17, podemos ver que el modelo ha clasificado una reseña como 5 cuando en realidad era 1 un total de 43 veces.

Todo esto nos dice que aún queda trabajo por hacer. Más abajo hay una sección titulada Sobre los Datos donde os doy algunos pasos más que se pueden dar.

Metadatos del modelo

Parece que el modelo funciona de manera aceptable así que ya podemos exportarlo a un archivo .mlmodel para que lo pueda usar quien lo necesite.

Pero antes de expotarlo estaría bien que diéramos información sobre el modelo, sus parámetros de entrada, la salida, etc. Vamos a ver como establecer esa información y otra más.

La clave de todo esto la tiene la estructura MLModelMetadata

Como veis, son las mismas propiedades que nos da coremltools para establecer los metadatos a excepción de los input_description y los output_description, que en el caso de MLModelMetadata no tiene una propiedad asignada a tal efecto.

Exportar el modelo para Core ML

Con el modelo y los metadatos listos sólo tenemos que decidir dónde queremos que Create ML genere el acrhivo .mlmodel

Y ya está todo listo, ahora tenemos un archivo que podemos importar a nuestro proyecto iOS y comenzar a realizar predicciones.

¿Y esto cuánto tarda?

Os puedo decir que en mi portátil, un MacBook Air de 2015, todo el proceso, desde cargar el archivo json hasta el momento de escribir el archivo mlmodel, duraba alrededor de 2-3 minutos.

Importación e integración en iOS

Para ver como se haría está integración he desarrollado un app muy simple que consta de un único controlador. En su vista asociada el usurio escribirá el título de la reseña que va a escribir de nuestra app y realizaremos una prediccón de cómo de buena (o mala) va a ser.

Lo primero que necesitamos es import el framework NaturalLanguage ya que necesitamos crear un NLModel a partir de nuestro modelo recién importado

El objeto NLModel que hemos creado nos deja preguntarle a nuestro modelo para que nos diga en que categoría se ajusta más la reseña del usuario mediante la función predictedLabel(for:) que nos devolverá la categoría en la que se ajusta más según sus valores.

Al final mostraremos un emoji bajo el título para mostrar el resultado de la predicción,

Excelente Buena Normal Mala Nefasta
😍 🙂 😐 😞 😡
5 4 3 2 1

Una aplicación práctica sería que si predecimos que el usuario va a reseñarnos de forma negativa le dirijamos a nuestra página de soporte para que pueda exponer sus quejas o resolver sus dudas en lugar de escribir directamente una mala reseña.

Sobre los datos

Una parte fundamental del desarrollo y entrenamiento de un modelo son los datos con los que le alimentamos. No sólo debemos centrarnos en la cantidad de datos, si no también en la calidad de los datos.

Dentro del concepto calidad entran cosas que sean acordes a lo que queremos categorizar, o que las categorias estén balanceadas. Hasta la propia Apple hace incapié en esto en la documentación:

This is a useful metric only when the data is well-balanced between categories.

Es por eso que para este artículo hemos usado los datos contenido en el archivo reviews_lite.json, que es un subconjunto del archivo reviews.json. La diferencia es que la vesión lite hay 8.000 reseñas para cada categoría, mientras que en la versión completa había variaciones, como por ejemplo 34.000 reseñas de categoría 5 y 8.500 de categoría 3.

Y a pesar de esto, Create ML conseguía ratios durante el entrenamiento de cerca del 77%, con los datos balanceados llega al 89%.

De todas formas el conjunto de datos es muy pequeño, pero como la misión principal de este tutorial es la guía sonre Create ML no he destinado mucho tiempo a la generación de los datos.

Os anímo a que useis el script Python que esté en el repositorio del artículo anterior y que probeís con diferentes cantidades de reseñas.

También podeís probar a eliminar las stopwords que contengan las reseñas. Hay muchas cosas que se pueden hacer para mejorar el rendimiento.

Y si no alcanzáis la precisión que queréis os animo a diseñar y entrenar vuestro modelo con Keras o TensorFlow y luego lo importéis mediante Core ML.

En el próximo artículo…

Seguiremos explorando las distintas opciones que nos brinda Create ML, en este caso nos centraremos en la clasificación de imágenes.

Código Fuente

Como siempre aquí os dejo el repositorio en GitHub para que podaís probar todo el código en local.

En él encontraréis el playground con la generación del modelo, la app iOS para probarlo y los juegos de datos en formato json.

Enlaces de interés

Artículos de la serie

  1. Create ML. Tutorial
  2. Create ML. MLTextClassifier
  3. Create ML. MLImageClassifier

Publicado en CoreML Create ML Machine Learning Swift