Usamos cookies. Tienes opciones. Las cookies nos ayudan a mantener el sitio funcionando sin problemas e informar sobre nuestra publicidad, pero si deseas realizar ajustes, puedes visitar nuestro Aviso de cookies para más información.
Uso de cookies en su dispositivo. Las cookies nos ayudan a mantener esta página web funcionando correctamente y a personalizar nuestra publicidad, pero el uso que hacemos de las cookies depende de usted. Acepte nuestra configuración o personalícela.
×

Primeros pasos en sistemas de recomendación

(Re)introducción

Recientemente, mi compañera Suni escribió unas primeras pinceladas sobre quiénes y de qué manera usan sistemas de recomendaciónEn su post menciona diferentes métodos para calcular estas predicciones, de los cuales nosotros vamos a emplear el filtrado colaborativo.

Un enfoque mixto, como el que tiene Spotify con sus playlist diarias, posiblemente sería el más acertado, detectando, por ejemplo, cuál es el tema más interesante para ese usuario y haciendo las recomendaciones sobre ese tema (filtrado basado en contenido + filtrado colaborativo). Posteriormente podrían añadirse reglas para ponderar estas recomendaciones basadas en aspectos demográficos (filtrado basado en reglas), pero, en principio, el propósito de este ejercicio es demostrar la implementación de una arquitectura funcional que cumpla el propósito de la recomendación de la manera más comprensible.

Hace algún tiempo que nuestro equipo encontró a su vez esta solución recomendada por Google para realizar este tipo de predicción sobre su arquitectura: Google Cloud Platform (GCP). En parte a raíz de ese artículo, en parte por la necesidad de ponernos en forma a la hora de desplegar servicios en la Cloud, y en parte por pura curiosidad del equipo, empujamos este proyecto hasta llevarlo a puerto.

Recolección

¿Así que estás decidido a hacer recomendaciones?, ¿sobre qué?

Una buena forma de optimizar las vistas a nuestro blog, y a su vez presentar contenido más relevante a nuestros lectores, podría ser recomendar artículos ya publicados. Además, podemos saber si a un usuario le ha enganchado un artículo si termina de leerlo, así que cada vez que se lee un artículo recogemos la siguiente información:

  • Lector (id): identificador que nos permita separar las lecturas de un usuario, de las de los demás.
  • % de lectura (rating): en función de si le gusta o no, el usuario abandonará el artículo o lo terminará.
  • Artículo: (URL): identificador de este artículo.

Almacenaremos esta información en una base de datos para luego calcular la recomendación.

Nota: en este caso hemos optado por desarrollar una recolección personalizada, pero el mismo dato podría extraerse de una implementación de analítica, aunque efectos similares se podrían haber conseguido utilizando el tiempo en página como rating, una valoración directa del artículo, el número de comentarios, etc.

 

Recomendación 2

a de la arquitectura del recomendador empleando módulos de GCP.

En nuestro caso, como estamos realizando este ejercicio empleando GCP, recogemos los datos valiéndonos de Cloud Functions y los insertamos en una base de datos Cloud SQL. Para no distraer de la narrativa, pondré a disposición del lector la función de recolección e inserción de la base de datos en lugar de insertarlo aquí.

 

Recomendación 3

 

Figura 2: Diagrama entidad-relación de la base de datos para almacenar la información relacionada con las predicciones basadas en vistas de artículos.

De acuerdo con la Figura 2, que explica el diagrama entidad-relación de nuestra base de datos, tendremos dos tablas principales, una para los datos proporcionados por la capa de recolección y otra para los calculados por nuestro algoritmo de recomendación. Además, tendremos dos tablas para traducir los identificadores de usuario y de post en algo manejable por el algoritmo (la librería que emplearemos nos obligará a utilizar índices naturales para representar a cada usuario y cada producto a recomendar).

Predicción

A la hora de ejecutar el algoritmo predictivo, necesitaremos transformar los datos que hemos extraído en algo que pueda manejar el algoritmo de predicción. Como comentábamos antes, tenemos dos tablas de traducción de identificadores de usuario y producto en índices.

Partiendo del dato recuperado que podemos ver en la tabla 1, tendremos un dato traducido como en la tabla 2.

visitorId

url

rating

015e7e6…3d08100408

http://www.analiticawe…-para-ser-mejor-analista/

25

015e7f1…3d06a0086e

http://www.analiticawe…-para-ser-mejor-analista/

0

015e80d…3d06a0086e

http://www.analiticawe…-para-ser-mejor-analista/

100

015e810…3d06a00ac2

http://www.analiticawe…-para-ser-mejor-analista/

50

015e814…3d06b008a0

http://www.analiticawe…-para-ser-mejor-analista/

25

015fac9…190700086e

http://www.divisadero….po-de-datos-estas-usando/

75

015f528…1c06b0086e

http://www.divisadero….po-de-datos-estas-usando/

75

0160571…4506a0086e

http://www.divisadero….po-de-datos-estas-usando/

50

0160894…4506a0086e

http://www.divisadero….po-de-datos-estas-usando/

50

015f2a0…1906b0086e

http://www.divisadero….iva-sistema-recomendacion

50

015ffec…1900d0086e

http://www.divisadero….iva-sistema-recomendacion

50

0160040…4208a0093c

http://www.divisadero….iva-sistema-recomendacion

0

016007d…5700d007e8

http://www.divisadero….iva-sistema-recomendacion

25

Tabla 1Tabla con los IDs de usuario e identificadores del producto (en nuestro caso la URL) sin indexar.

userId

postId

rating

323452

234

25

532342

234

0

421254

234

100

655343

234

50

367561

234

25

345323

121

75

432122

121

75

316052

121

50

787238

121

50

732637

104

50

283712

104

50

983716

104

0

367167

104

25

Tabla 2: Tabla con los IDs de usuario e identificadores del producto indexados.

El algoritmo de recomendación que estamos utilizando es el de filtrado colaborativo. Para ejecutarlo podemos seguir la recomendación de buenas prácticas para ejecutar tareas periódicas en GCP.  En nuestro caso hemos escrito este script en python para ejecutar en pyspark sobre Dataproc,tomando como modelo el que provee Google.

La ejecución de este script sobrescribe la tabla de predicciones (como podemos ver en la Figura 1) con la información más fresca, y nos deja un resultado como el de la tabla 3.

userId

postId

rating

18872

2289

98

42044

1644

23

42044

4723

22

42044

13860

21

42044

698

21

42044

148

20

24688

1655

53

24688

58

50

24688

1654

45

24688

4482

43

..

Tabla 3: Resultado del algoritmo de predicción

Egresión

Gracias a las Cloud Functions y demás arquitectura Serverless que ofrecen los grandes proveedores de servicios en la nube (AWS con las Lambda Functions, Google con las Cloud Functions y Microsoft con Azure Functions) podemos implementar este tipo de APIs muy fácilmente.

Hace unos meses, mi compañero Nico revisaba la ventaja estratégica que supone este tipo de servicios en su artículo. Puede servirnos de introducción si queremos un poco de contexto antes de ponernos manos a la obra.

Símplemente pediremos las recomendaciones (si las hubiera) para el usuario actual desde el frontusando una función similar a esta (sirva de plantilla). Es interesante señalar que estamos ingresando datos de orígenes disjuntos como son nuestros dos blogs (Analitica Web y el blog de Actualidad de Divisadero) por lo que, para que las recomendaciones tengan sentido dentro de cada uno, deberemos filtrar las que se refieren a este. Es decir, dentro del blog de Analitica serviremos solamente recomendaciones sobre este mismo blog.

Al pedir los datos a la api para cierto ID, debería devolvernos una respuesta de este tipo:

{

“tuuid”: “015e949d37bb001a1b2316be0a3e04072003606a00918”,

“post_array”: [

“https://www.analiticaweb.es/torturando-los-datos-capitulo-i/”,

“https://www.analiticaweb.es/cross-device-tracking-google-analytics/”,

“https://www.analiticaweb.es/un-paso-mas-en-data-studio/”,

“https://www.analiticaweb.es/multi-channel-funnels-o-embudos-multicanal-de-ga/”,

“https://www.analiticaweb.es/trucos-lowcost-para-adobe-analytics/”

]

}

Después es tarea personal mostrar esta información de manera relevante sobre la página.

Next Steps

Ahora mismo las recomendaciones se calculan periódicamente, el dato no es absolutamente fresco. Es decir, si una visitante habitual del blog lee un artículo, esta información no se incluirá en las recomendaciones hasta la próxima vez que se recalculen. Se dará la paradoja de que después de leer los artículos recomendados, seguiremos recibiendo las mismas recomendaciones. Aunque las predicciones puedan recalcularse con mucha frecuencia, seguirán siendo procesos en batch, cuando lo que necesitamos es un procesamiento en streaming con el dato siempre fresco.

Para este propósito disponemos en GCP de una herramienta llamada Dataflow, fácilmente operable en python, que junto con esta librería (FluRS) podría realizar esta predicción casi en tiempo real. Funciona implementando el algoritmo de Descenso Estocástico del Gradiente (SGD) para calcular un modelo fiable, pero con la particularidad de hacerlo de manera incremental, de tal forma que se pueden añadir datos al vuelo.

Da gusto trabajar con la plataforma Fully Managed de GCP, con toda la potencia al alcance de la mano. Espero que el lector pueda extraer información práctica del artículo. Como siempre, las preguntas son bien recibidas.

 

Unirse al debate
En nuestra compañía