Este artículo es el primero de una serie de instructivos de varias partes que te muestra cómo implementar un sistema de recomendación de aprendizaje automático (AA) con TensorFlow 1.x y AI Platform en Google Cloud Platform (GCP). En esta parte, se muestra cómo instalar el código del modelo de TensorFlow en un sistema de desarrollo y ejecutarlo en el conjunto de datos MovieLens
.
El sistema de recomendación en el instructivo usa el algoritmo de mínimos cuadrados alternos ponderados (WALS). WALS se incluye en el paquete contrib.factorization de la base de código de TensorFlow 1.x y se usa para factorizar una gran matriz de calificaciones de usuarios y elementos. Para obtener más información sobre WALS, consulta la descripción general.
Este artículo describe el código del modelo en detalle, incluido el procesamiento previo de datos y la ejecución del algoritmo WALS en TensorFlow.
La serie consta de las siguientes partes:
- Descripción general
- Crea el modelo (Parte 1) (este instructivo)
- Entrena y ajusta en AI Platform (parte 2)
- Aplica a datos de Google Analytics (Parte 3)
- Implementa el sistema de recomendación (Parte 4)
Objetivos
- Comprender la estructura del código de TensorFlow que se usa para aplicar WALS a la factorización de matrices
- Ejecutar el código de muestra de TensorFlow de manera local para realizar recomendaciones en el conjunto de datos
MovieLens
Costos
En este instructivo, se usa Cloud Storage y AI Platform; ambos son servicios facturables. Puedes usar la calculadora de precios para calcular los costos según el uso previsto. El costo previsto para este instructivo es de $0.15. Si eres un usuario nuevo de GCP, puedes optar por una prueba gratuita.
Antes de comenzar
-
En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.
- Habilita las API de Compute Engine and AI Platform.
Ejecuta el modelo de TensorFlow
Puedes ejecutar los pasos en esta sección en una instancia de Compute Engine con al menos 7 G de memoria, como se muestra en el siguiente procedimiento. Como alternativa, puedes ejecutar los pasos en esta sección en un sistema macOS o Linux local; en ese caso, no es necesario crear una instancia de Compute Engine.
Crea la instancia de Compute Engine
En Google Cloud Console, ve a la página Instancias de VM.
Haz clic en Crear instancia.
Nombra tu instancia como quieras y elige una zona. Si aún no tienes una zona de preferencia, elige una que esté geográficamente cerca.
En la lista desplegable del tipo de máquina, selecciona 2 CPU virtuales con n1-standard-2.
En la sección Alcances del acceso, selecciona Permitir el acceso total a todas las API.
Haz clic en Crear.
Instala el código
Dirígete a la página Instancias de VM.
En la fila de tu instancia, haz clic en SSH para abrir una terminal basada en el navegador que esté conectada de forma segura a la instancia.
En la ventana de la terminal nueva, actualiza los repositorios de software de tu instancia.
sudo apt-get update
Instala
git
,bzip2
yunzip
.sudo apt-get install -y git bzip2 unzip
Clona el repositorio de código de muestra:
git clone https://github.com/GoogleCloudPlatform/tensorflow-recommendation-wals
Instala Miniconda. El código de muestra requiere Python 2.7.
wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh bash Miniconda2-latest-Linux-x86_64.sh export PATH="/home/$USER/miniconda2/bin:$PATH"
Instala los paquetes de Python y TensorFlow. Este instructivo se ejecutará en cualquier versión 1.x de TensorFlow.
cd tensorflow-recommendation-wals conda create -y -n tfrec conda install -y -n tfrec --file conda.txt source activate tfrec pip install -r requirements.txt pip install tensorflow==1.15
Descarga el conjunto de datos de
MovieLens
. Hay varias versiones del conjunto de datos.Para fines de desarrollo, recomendamos usar la versión
100k
, que contiene 100,000 calificaciones de 943 usuarios en 1,682 elementos. Descárgala con los comandos siguientes:curl -O 'http://files.grouplens.org/datasets/movielens/ml-100k.zip' unzip ml-100k.zip mkdir -p data cp ml-100k/u.data data/
Para fines de entrenamiento, recomendamos el conjunto de datos de
1m
, que contiene un millón de calificaciones. El formato del conjunto de1m
es un poco diferente al conjunto de100k
. Por ejemplo, el archivo de calificaciones está delimitado por caracteres::
. El código de muestra te permite usar el argumento--delimiter
para especificar que el conjunto de datos use este delimitador.curl -O 'http://files.grouplens.org/datasets/movielens/ml-1m.zip' unzip ml-1m.zip mkdir -p data cp ml-1m/ratings.dat data/
También puedes usar el conjunto de datos de
20m
con este proyecto. El conjunto de datos se proporciona en un archivo CSV. Si usas este conjunto de datos, debes pasar la marca--headers
, porque el archivo contiene una línea de encabezado.curl -O 'http://files.grouplens.org/datasets/movielens/ml-20m.zip' unzip ml-20m.zip mkdir -p data cp ml-20m/ratings.csv data/
Comprende el código del modelo
El código del modelo se incluye en el directorio wals_ml_engine
. La funcionalidad de alto nivel del código se implementa con los siguientes archivos:
mltrain.sh
- + Inicia varios tipos de trabajos de AI Platform. Esta secuencia de comandos de shell acepta argumentos para la ubicación del archivo de conjunto de datos, el delimitador utilizado con el propósito de separar los valores en el archivo y si el archivo de datos tiene una línea de encabezado. Se recomienda crear una secuencia de comandos que configure y ejecute los trabajos de AI Platform de forma automática.
task.py
- + Analiza los argumentos para el trabajo de AI Platform y ejecuta el entrenamiento.
model.py
- + Carga el conjunto de datos.
- Crea dos matrices dispersas a partir de los datos, una dirigida a entrenamiento y otra a pruebas. Ejecuta WALS en la matriz de entrenamiento disperso de calificaciones.
wals.py
- + Crea el modelo de WALS.
- Ejecuta el algoritmo de WALS.
- Calcula la raíz cuadrada del error cuadrático medio (RMSE) para un conjunto de factores de fila/columna y una matriz de calificaciones.
Cómo el modelo procesa los datos
El código del modelo realiza el procesamiento previo de los datos con el propósito de crear una matriz de calificaciones dispersas y prepararla para la factorización de la matriz. Esto implica los siguientes pasos:
El código del modelo carga los datos de un archivo de texto delimitado. Cada fila contiene una sola calificación.
ratings_df = pd.read_csv(input_file, sep=args['delimiter'], names=headers, header=header_row, dtype={ 'user_id': np.int32, 'item_id': np.int32, 'rating': np.float32, 'timestamp': np.int32, })
El código establece un conjunto 0-indexado de ID únicos para usuarios y artículos. Esto garantiza que un ID único corresponda a índices de fila y columna específicos de la matriz de calificaciones dispersas.
Los datos de
MovieLens 100k
usan ID basados en 1 en los que el índice más bajo del conjunto único es 1. Para normalizar, el código resta uno de cada índice. Demodel.py
:ratings = ratings_df.as_matrix(['user_id', 'item_id', 'rating']) # deal with 1-based user indices ratings[:,0] -= 1 ratings[:,1] -= 1
Los conjuntos de datos de
1m
y20m
MovieLens
omiten algunos ID de usuarios y elementos. Esto genera un problema: tienes que asignar el conjunto de ID de usuarios únicos a un conjunto de índices igual a [0 ... num_users-1]
] y hacer lo mismo para los ID de elementos. La asignación de elementos se realiza mediante el código siguiente[numpy](http://www.numpy.org/)
. El código crea un arreglo de tamaño [0..max_item_id]
] para realizar la asignación, por lo que si el ID máximo del elemento es muy grande, este método puede usar demasiada memoria.np_items = ratings_df.item_id.as_matrix() unique_items = np.unique(np_items) n_items = unique_items.shape[0] max_item = unique_items[-1] # map unique items down to an array 0..n_items-1 z = np.zeros(max_item+1, dtype=int) z[unique_items] = np.arange(n_items) i_r = z[np_items]
El código para asignar usuarios es, básicamente, el mismo que el de los elementos.
El código del modelo selecciona aleatoriamente un conjunto de pruebas de calificaciones. De forma predeterminada, el 10% de las calificaciones se eligen para el conjunto de pruebas. Estas calificaciones se quitan del conjunto de entrenamiento y se usarán para evaluar la precisión predictiva del usuario y los factores del elemento.
test_set_size = len(ratings) / TEST_SET_RATIO test_set_idx = np.random.choice(xrange(len(ratings)), size=test_set_size, replace=False) test_set_idx = sorted(test_set_idx) ts_ratings = ratings[test_set_idx] tr_ratings = np.delete(ratings, test_set_idx, axis=0)
Por último, el código crea una matriz dispersa scipy de manera conjunta (
coo_matrix
) que incluye índices y calificaciones de usuarios y elementos. El objetocoo_matrix
actúa como un wrapper para una matriz dispersa. También realiza la validación de los índices de usuarios y calificaciones, y verifica errores en el procesamiento previo.u_tr, i_tr, r_tr = zip(*tr_ratings) tr_sparse = coo_matrix((r_tr, (u_tr, i_tr)), shape=(n_users, n_items))
Cómo se implementa el algoritmo de WALS en TensorFlow
Una vez que los datos se procesan con anterioridad, el código pasa la matriz de entrenamiento dispersa al modelo de WALS de TensorFlow para que se factorice en el factor de fila X y el factor de columna Y.
El código de TensorFlow que ejecuta el modelo es muy simple, ya que se basa en la clase WALSModel
incluida en el módulo contrib.factorization_ops
de TensorFlow.
Un objeto
SparseTensor
se inicializa con los ID de usuarios y de elementos como índices y con las calificaciones como valores. Dewals.py
:input_tensor = tf.SparseTensor(indices=zip(data.row, data.col), values=(data.data).astype(np.float32), dense_shape=data.shape)
La variable de datos es el objeto
coo_matrix
de las clasificaciones de entrenamiento creadas en el paso de procesamiento previo.En el modelo se crea una instancia:
model = factorization_ops.WALSModel(num_rows, num_cols, dim, unobserved_weight=unobs, regularization=reg, row_weights=row_wts, col_weights=col_wts)
Los factores de fila y los tensores de factores de columna los crea de forma automática la clase
WALSModel
y se recuperan a fin de que puedan evaluarse después de factorizar la matriz:# retrieve the row and column factors row_factor = model.row_factors[0] col_factor = model.col_factors[0]
El proceso de entrenamiento ejecuta el bucle siguiente dentro de una sesión de TensorFlow con el método
simple_train
enwals.py
:row_update_op = model.update_row_factors(sp_input=input_tensor)[1] col_update_op = model.update_col_factors(sp_input=input_tensor)[1] sess.run(model.initialize_op) sess.run(model.worker_init) for _ in xrange(num_iterations): sess.run(model.row_update_prep_gramian_op) sess.run(model.initialize_row_update_op) sess.run(row_update_op) sess.run(model.col_update_prep_gramian_op) sess.run(model.initialize_col_update_op) sess.run(col_update_op)
Después de que se hayan ejecutado las iteraciones
num_iterations
, los tensores de factor de fila y columna se evalúan en la sesión con el fin de producir arreglosnumpy
para cada factor:# evaluate output factor matrices output_row = row_factor.eval(session=session) output_col = col_factor.eval(session=session)
Estos arreglos de factores se usan para calcular el RMSE en el conjunto de calificaciones de prueba.
Los dos arreglos también se guardan en el directorio de salida en formato numpy
.
Entrena el modelo
En este contexto, el entrenamiento del modelo implica factorizar una matriz dispersa de calificaciones en una matriz de factores de usuario X y una matriz de factores de elementos Y. Los factores de elementos y usuarios guardados se pueden usar como modelos base para un sistema de recomendación.
Este sistema toma a un usuario como entrada, recupera el vector de factores de usuario para ese usuario de X, multiplica ese vector por todos los factores del elemento Y y muestra los principales elementos N de acuerdo con la calificación predicha.
En la Parte 4 de este instructivo, se proporcionan más detalles sobre un sistema que usa el modelo entrenado para realizar predicciones y se muestra cómo implementar este sistema en GCP.
Cómo entrenar el modelo de manera local
Entrenar el modelo de manera local es útil para propósitos de desarrollo. Te permite probar con rapidez los cambios de código, incluidos los puntos de interrupción para una depuración fácil. Para ejecutar el modelo en Cloud Shell o desde tu sistema local, ejecuta la secuencia de comandos mltrain.sh
desde el directorio wals_ml_engine
con la opción local
.
cd wals_ml_engine
Para el conjunto de datos
MovieLens
100k
, especifica la ruta al archivo de datos100k
:./mltrain.sh local ../data u.data
Para el conjunto de datos
MovieLens
1m
, incluye la opción--delimiter
y especifica la ruta al archivo de datos1m
:./mltrain.sh local ../data ratings.dat --delimiter ::
Para el conjunto de datos
MovieLens
20m
, usa las opciones--delimiter
y--headers
:./mltrain.sh local ../data ratings.csv --headers --delimiter ,
El resultado del trabajo de entrenamiento muestra el RMSE calculado en el conjunto de prueba. Para el conjunto de datos 1m
y con los hiperparámetros predeterminados especificados en el código fuente, el resultado debe verse de la manera siguiente:
INFO:tensorflow:Train Start: <timestamp> ... INFO:tensorflow:Train Finish: <timestamp> INFO:tensorflow:train RMSE = 1.29 INFO:tensorflow:test RMSE = 1.34
Para obtener más detalles, consulta la Parte 2.
El RMSE corresponde al error promedio en las calificaciones predichas en comparación con el conjunto de prueba. En promedio, cada calificación que realiza el algoritmo está dentro de ± 1,29 de la calificación real del usuario en el conjunto de pruebas en el conjunto de datos 1m
. El algoritmo de WALS tiene un rendimiento mucho mejor cuando se ajustan los hiperparámetros, como se muestra en la Parte 2 de esta serie.
Limpieza
Si creaste una instancia de Compute Engine para ejecutar TensorFlow, debes detenerla con el propósito de evitar incurrir en cargos en tu cuenta de GCP. Esta instancia no se usa en la Parte 2 de esta serie. Sin embargo, la instancia de Compute Engine es necesaria para la Parte 3 y la Parte 4.
Detén la instancia de Compute Engine
- En Cloud Console, abre la página de lista de instancias de VM de Compute Engine.
- Selecciona el nombre de la instancia.
- Haz clic en Detener y confirma la operación.
Borra el proyecto
La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.
Para borrar el proyecto, sigue estos pasos:
- En Cloud Console, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
¿Qué sigue?
- En el instructivo siguiente, Recomendaciones para TensorFlow: entrena y ajusta en AI Platform (Parte 2), se explica cómo entrenar el modelo de recomendación en AI Platform y se ajustan los hiperparámetros.