En busca de la mejor estrategia de Ranking: experimentación y confirmación dinámica
Obtener un ranking óptimo [1] implica analizar características muy importantes que debemos tener en cuenta para mantener un balance entre las necesidades del negocio, los ítems patrocinados y el contenido orgánico. Sin embargo, también es importante entender que existen particularidades detrás de cada usuario, es decir, no todos reaccionan igual a la misma oferta. Así, para llevar al usuario la mejor experiencia, es deseable iterar y realizar pruebas presentando distintas alternativas según cada caso y comprendiendo qué oferta se ajusta a sus preferencias a través de experimentos continuos.
Pero, ¿qué comprende generar un nuevo experimento de ranking?
Es un proceso largo que involucra distintas etapas. Termina siendo lento, no solo por las características del mismo sino también por las siguientes razones, a) es necesario solicitar datos de distintos orígenes al mismo tiempo, ya que requerimos manipular varias entidades, e integrar servicios de diferentes equipos con características particulares en su configuración y respuesta, b) se requiere implementar estrategias de ranking para equilibrar los intereses del usuario con las necesidades de los comercios, por ejemplo, aplicando algoritmos de Machine Learning; por último c) es necesario optimizar las estrategias de ranking para cada flujo de la App en el que se muestre un listado de ítems (listing).
Es por esto que nos planteamos desarrollar herramientas para mejorar nuestro proceso de iteración, algo que nos permita experimentar de una forma rápida y guiada por los datos, una plataforma que sea fácil de usar y que con sólo algunas configuraciones permita a los stakeholders de producto generar experimentos sin depender de tareas de ingeniería. Por ello nos planteamos los siguientes objetivos:
- El ranking debe ser fácil de cambiar / evolucionar.
- El artefacto orquestador, el cual define la conformación del listing, debe ser altamente configurable.
- Generar nuevos experimentos debe ser rápido.
- Queremos poder confirmar y ajustar los parámetros de un experimento tan rápido como sea posible.
Enfocándonos en frameworks que cumplieran con estos requisitos, nos encontramos con una técnica utilizada por grandes compañías como AirBNB [2], Spotify [3] y Lyft [4]: Server Driven UI, también conocida como Backend Driven Development.
Server Driven Experiments: Nuestra version de Server Driven UI
Server Driven UI (User Interface) consiste en la idea de desarrollar aplicaciones front-end con flujos y pantallas basadas en respuestas del servidor, donde las pantallas y la navegación tienen un comportamiento distinto dependiendo de las respuestas del servidor. La tarea más común en el proceso de desarrollo es la implementación de pantallas y componentes visuales que permitan la interacción con el usuario. Algunos de estos componentes son rellenados con información proveniente de una API, con tipos de datos primitivos como enteros, booleanos, alfanuméricos o por el resultado de operaciones que se aplican sobre estos datos usando la lógica de negocio [5].
Como se muestra en la Fig.1, se invoca un servicio (Server) que nos devuelve un JSON, luego se procesa la respuesta (Parser) y sobre la base del resultado se selecciona (Router) la siguiente pantalla a presentar (Scene). El concepto de Server Driven UI toma particular importancia al momento de desarrollar estas pantallas y componentes, las cuales se pueden reutilizar a través de un archivo orquestador. Es allí donde se configura cómo serán presentadas estas vistas, el orden y su contenido, siendo después seleccionado en relación al contexto del usuario.
Tomando como inspiración el concepto anterior, decidimos darle un giro y utilizarlo para cubrir estas necesidades de realizar experimentos con los resultados del ranking y el listing asociado según el contexto de cada usuario, obteniendo algo como se muestra en la Fig. 2. y que denominamos Server Driven Experiments.
Con este concepto anterior y con el servicio de búsquedas federadas [1], nos quedaba por resolver cuál sería el listing a presentar a cada usuario. Para ésto utilizamos un microservicio al cual llamamos “planner”, que como vemos en la Fig. 3 permite establecer experimentos A/B testing y así decidir cuál será el Seeking Plan ideal para optimizar el flujo de la App correspondiente.
Utilizando una Meta Flag se puede evaluar el contexto del usuario (como puede ser país, vertical, segmento del usuario, categoría, horario, entre otros) para obtener qué experimento es el que aplicaremos, y finalmente obtener el Seeking Plan que se utilizará para generar el ranking de comercios o productos. Es aquí donde podemos ir iterando los experimentos de lo que llamamos Dynamic Confirmation (Confirmación Dinámica), pues una vez que tenemos los resultados preliminares del experimento en ejecución, podemos ir ajustando la configuración del experimento asociado sin necesidad de realizar despliegue de ninguno de los servicios involucrados.
En este punto es importante tener en cuenta que definimos Seeking Plan como el artefacto orquestador representado en formato JSON, el cual encapsula la configuración que representa los distintos pasos necesarios para obtener resultados parciales, filtrar, rankear, y conformar el listing final. Dicha configuración está dividida en 4 secciones:
- Inspector: Configuración que describe cómo obtener los ítems candidatos (oferta de comercios) sobre la base de distintos criterios, como pueden ser: área de entrega, horarios, etc.
- Provider: Describe cómo filtrar y rankear los ítems obtenidos en el paso anterior. Estos ítems tienen diferentes niveles de granularidad, por ejemplo comercio o productos.
- Enricher: Como su nombre lo indica, esta sección de la configuración muestra cómo se deben enriquecer los ítems con información adicional.
- Blending Schema: Una vez que toda la información requerida es obtenida, la última fase consiste en aplicar algoritmos para mezclar los ítems obtenidos en las distintas etapas anteriores y unificarlos en un listing.
En la Fig. 4, dado el contexto de un usuario hipotético que pertenece al país Uruguay y se encuentra buscando cafeterías, vemos que accede a 1 de los 3 Seeking Plans que conforman este experimento y que se encuentran disponibles para ese contexto mencionado. Esto lo podemos tomar como un ejemplo en donde solo tenemos 2 variables de contexto, como es país y vertical, pero la versatilidad de estos experimentos es mucho más amplia.
Experimentos para todos
Después de iterar por todos estos pasos, nos complace haber logrado una forma de experimentar que cumple con los objetivos propuestos. En este sentido, obtuvimos un mecanismo para configurar fácilmente diversas estrategias de ranking a través del Seeking Plan [6], tomando información de distintas fuentes y armando un listing basado en el contexto del usuario según los diferentes flujos de la App. Ahora también somos capaces de ajustar nuestros experimentos sobre la base del feedback obtenido, generando así un balance entre las preferencias del usuario y las necesidades de los comercios asociados. Cabe destacar que todo esto es posible sin la necesidad de modificar código o hacer re-despliegue de los servicios involucrados. Así, logramos generar impacto en nuestro producto a través de cambios frecuentes.
Para más información, pueden ver la charla de PeYaTech en Nerdearla:
Referencias
[1] Ranking: conciliador entre los intereses del usuario y las necesidades de los comercios
[2] A Deep Dive into Airbnb’s Server-Driven UI System
[3] Building component-driven UIs at Spotify
[4] Lyft Mobile Podcast: Server Driven UI with Kevin Fang & Jeff Hurray
[5] Backend Driven Development — iOS
[6] En búsqueda de la mejor estrategia de Ranking en nuestra App