
Los clientes de nuestra tienda quieren hacer marketing genial. Para que la gente compre más, regularmente les envía correos electrónicos. Y cada vez piensan: "¿Qué escribir en la carta?".
Puede escribir simplemente: "¡Compre con más frecuencia!", Pero no funciona muy bien. Una mejor idea es insertar anuncios de productos en una carta. Es recomendable anunciar productos que interesen a los compradores.
A continuación, hablaré sobre cómo hicimos recomendaciones personales reales desde cero.
Elige qué recomendar
Puedes recomendar cualquier cosa.
Puedes recomendar los productos más comprados. Por ejemplo, en una tienda de electrónica, estos son discos duros y teléfonos móviles. ¿Pero qué hay de aquellos que ya los tienen? Resulta que a todos se les recomienda lo mismo, no muy bueno.
Puede recomendar algo similar a lo que la persona miró en el sitio; por ejemplo, miró los zapatos, recomendamos ... ¡otros zapatos! No importa cuán extraño suene, se usa en la práctica e incluso funciona.
Pero todavía queríamos hacer algo especial para que todos vieran en la carta algo personal que realmente necesitaba, para que tuviera el deseo de volver a la tienda una y otra vez. La tarea fue complicada por el hecho de que tenemos casi 300 tiendas de clientes en varios campos. Y las recomendaciones deberían funcionar bien para cada una de ellas, ajustándose automáticamente a los detalles de una tienda en particular. Entonces comenzamos a hacer recomendaciones personales universales.
Haciendo el modelo base
Después de leer artículos de Amazon , decidimos hacer el modelo más básico de recomendaciones personales y ver cómo se muestra.
Para comenzar, descargue la tabla de compras y amplíela en una matriz escasa de cliente-producto.

Convertir una lista de compras en una matriz cliente-producto
A continuación, utilizamos el filtrado colaborativo . La intuición aquí es simple: el cliente número 1 compró el producto número 1 y dos productos número 3; el cliente número 2 también compró el producto número 1; es probable que quiera comprar el producto número 3.
El filtrado colaborativo implica la descomposición de una matriz dispersa grande en dos matrices de características latentes alargadas densas de tamaño sustancialmente más pequeño. Para la descomposición, utilizamos la implementación preparada de AlternatingLeastSquares de la biblioteca implícita .
Después de entrenar el modelo, tenemos síntomas latentes para todos los clientes y todos los productos. Se presentan en forma de matrices (número de clientes x número de signos) y (número de productos x número de signos), respectivamente.
Los signos latentes son signos que no se establecen explícitamente en ningún lugar, como, por ejemplo, la altura de una persona o el área de un apartamento. Por lo general, se obtienen como resultado de algunas transformaciones matemáticas sobre los datos originales.
Las matrices de entidades latentes están dispuestas de modo que si las multiplica, obtendrá una matriz del mismo tamaño que la original. Con un alto grado de convencionalidad, podemos decir que donde haya números más grandes, habrá números más grandes, aproximadamente uno. Donde menos es menos. Donde había ceros, habrá números pequeños, cerca de cero, posiblemente negativos. Pero lo importante es que en algunos lugares donde había ceros, aparecerán números bastante grandes: nuestras recomendaciones futuras.

Las compras que se influyen fuertemente entre sí se resaltan en el mismo color. Un cuadro destaca algunas recomendaciones futuras.
Ahora, si tomamos el vector de características para un cliente en particular y lo multiplicamos por la matriz de características del producto, obtenemos el vector de puntuación de todos los productos para ese cliente. Solo queda elegir entre varios productos con la máxima velocidad.
Un pequeño matiz, entre los productos recomendados con una alta probabilidad, habrá aquellos que ya hayan sido comprados por el cliente, deben excluirse.
Curiosamente, pero un esquema tan simple resultó funcionar y los clientes estaban felices de probar nuestras recomendaciones. Hicimos pruebas AB, donde comparamos recomendaciones personales con los más vendidos. En algunos casos, no hubo diferencia, pero en algunos vieron un aumento estadísticamente significativo en las conversiones en pedidos de hasta el 10%. Estas eran principalmente tiendas con una alta frecuencia de compras y, en consecuencia, una gran cantidad de datos.
Usamos más datos.
Estaba claro que la información sobre compras por sí sola no era suficiente para hacer buenas recomendaciones. Aunque solo sea porque muchos clientes no tienen compras en absoluto. Por lo tanto, decidimos mejorar nuestras recomendaciones.
Además de las compras, comenzamos a tener en cuenta las vistas de productos, así como a agregarlas a varias listas: en la cesta, en "favoritos", etc.
Para cada tipo de acción, seleccionamos un peso y lo agregamos a nuestra matriz dispersa con este peso.
Tomamos en cuenta el tiempo de acción.
Pensamos que la compra de ayer y la compra de hace un año no deberían tener el mismo efecto en las recomendaciones. Por lo tanto, introdujimos un coeficiente de olvido exponencial para todas las acciones.
Además, para algunas tiendas, por ejemplo, la ropa, la estacionalidad es importante: si es verano, entonces debe prestar más atención a lo que una persona compró en el verano hace un año que a lo que compró hace seis meses en el invierno.
Tomamos en cuenta los signos obvios.
Nuestra base de datos tiene una amplia variedad de información. Decidimos que todo debería usarse.
Para los productos, comenzamos a usar el precio, el fabricante, la categoría del producto y varios campos adicionales que indica la tienda (tamaño de la ropa, color de los muebles, la presencia de OMG en los alimentos para perros, etc.).
Para los clientes, tomaron género, edad, dominio de buzón, sistema operativo en la última sesión y el canal a través del cual ingresó a la base de datos (en línea, fuera de línea, red social, etc.).
Para adjuntar todo esto al modelo, nosotros:
- Hacemos matrices de características (por separado para clientes y productos), habiéndolas procesado previamente utilizando métodos estándar: escalado, codificación de una sola vez.
- En función de las características de los productos y la matriz cliente-producto existente, restauramos características adicionales emparejadas para los clientes. La restauración se realiza de tal manera que el producto de los atributos del producto se empareja con los atributos del cliente para acercar la matriz fuente lo más posible. Pegue estos signos adicionales a los latentes existentes.
- Del mismo modo, lo hacemos con los signos de los clientes.

Expandir signos latentes
Ahora tenemos más señales y podemos hacer recomendaciones más precisas. A partir de ese momento, el número de pruebas que mostraron un resultado estadísticamente significativo a favor de las recomendaciones personales comenzó a crecer. Además de las pruebas, la evaluación subjetiva de los expertos también ha mejorado.
Configurar hiperparámetros
Las métricas primero
Por supuesto, probamos nuestras recomendaciones todo el tiempo. Realizamos pruebas fuera de línea y en línea.
Por supuesto, las pruebas AB en línea son una forma más confiable de verificar qué tan buenas son las recomendaciones. Y estas pruebas mostraron buenos resultados.
Sin embargo, las pruebas en línea son terriblemente inconvenientes:
Necesita encontrar una tienda que quiera arriesgarse con sus clientes y probar la nueva versión del algoritmo.
Luego debe esperar un día / semana / dos para obtener resultados estadísticamente significativos.
Debe repetir esto 100 veces para probar 100 opciones diferentes.
Por lo tanto, las pruebas fuera de línea son indispensables. Y aquí no estará mal mencionar cómo los llevamos a cabo.
Como una métrica fuera de línea, eligieron el popular y simple: nDCG @ K (ganancia acumulada con descuento normalizada en K) , o más bien su promedio para varios miles de clientes.
Esta métrica es la calidad de clasificación . Toma valores de 0 a 1 y muestra cuán buenas son las recomendaciones.
Para calcular el valor de la métrica, necesita un estándar: recomendaciones ideales. No tenemos ese estándar. Pero encontramos una salida: consideramos recomendaciones en un momento en el pasado, hace un mes, y analizamos lo que una persona compró para este mes; este era nuestro estándar.
Aquí hay un pequeño truco: si le hubiéramos recomendado algo al cliente hace un mes, podría haberlo comprado, pero no lo había comprado. Pero nunca sabremos sobre esto.
Otro punto: podríamos recomendar un sombrero azul con un pompón, y un cliente compró un sombrero azul sin pompón. Los productos parecen ser similares, pero diferentes: las bolsas métricas. Por lo tanto, al calcular la métrica, comenzamos a tener en cuenta la similitud de los bienes.
Y ahora sobre hiperparámetros
Dado que tenemos una métrica fuera de línea, podemos probar de forma segura una variedad de opciones para nuestras recomendaciones y no preocuparnos de que alguien pueda sufrir.
Durante una semana agotando nuestra imaginación, probamos entre 2 y 3 docenas de modificaciones diferentes de nuestro algoritmo, entre las cuales se encontraban simples, como diferentes factores de olvido, y más complejas, como el uso de otro algoritmo para pegar signos obvios de clientes y productos.
Algunas modificaciones no tienen efecto en ninguna parte. Algunos mostraron mejoras en todos los proyectos, los arreglamos. Y algunos en varios proyectos mejoraron la métrica, mientras que en otros empeoraron. Entonces obtuvimos la configuración de hiperparámetro .
Ahora tenemos 11 hiperparámetros. Tomó varios días encontrar los valores óptimos de cada uno de ellos para todos los proyectos.
Después del ajuste, resultó que, en promedio, la métrica para todos los proyectos creció 6 veces, y el crecimiento más fuerte, ¡35 veces!
Mejorando la funcionalidad
Podemos hacer buenas recomendaciones personalizadas. Genial
¿Pero cómo funcionan? Algo como esto: todas las noches por la noche, cuando cae la carga en los servidores, comenzamos a contar recomendaciones para todos los proyectos. El consumo de RAM y CPU despega, pasan varias horas y las recomendaciones están listas. Van a un almacén especial y esperan hasta que los saquen de allí.
¿Por qué tomarlo? Por ejemplo, para enviar una carta. Eso suena bien
O para mostrar en el sitio. Imagina que vas al sitio, eliges un teléfono móvil, y hay recomendaciones personales en la ventana, y te ofrecemos ... ¡un hervidor de agua! ¿Por qué una tetera? Sí, porque compró un microondas hace un mes, y el algoritmo calculó que aquellos que compraron un microondas a menudo necesitan una tetera.
¡Pero necesitas un teléfono celular! Como ser
Ha llegado el momento de hacer recomendaciones que funcionen en tiempo real.
Desde el punto de vista de las matemáticas, nada nuevo: simplemente dividimos la etapa de entrenamiento modelo y la etapa de emisión de recomendaciones.
Todavía entrenamos al modelo una vez al día.
Y ahora podemos emitir recomendaciones en línea. Tan pronto como una persona realiza alguna acción en el sitio, por ejemplo, ve el producto o lo agrega a la cesta, se genera una solicitud. La solicitud indica quién hizo qué, con qué producto. El algoritmo de recomendación procesa esta solicitud y, en respuesta, genera una lista de recomendaciones para este cliente.
Para hacer esto posible, necesitábamos:
- Haga un repositorio donde se agreguen modelos después del entrenamiento.
- Organice un almacenamiento de valores clave para almacenar acciones realizadas previamente por el cliente, ya que lleva mucho tiempo cargarlas desde la base de datos.
- Acelerar significativamente nuestras recomendaciones. El principal punto de aceleración fue el uso de la biblioteca nmslib para encontrar los vecinos más cercanos para seleccionar los productos más relevantes para una persona. A los chicos astutos de Microsoft se les ocurrió cómo reducir el problema de la multiplicación de matrices y elegir la parte superior de los elementos con el valor más alto para la tarea de encontrar los vecinos más cercanos.
- Haga un microservicio que rastree las acciones de una persona en el sitio, envíe una solicitud de recomendaciones, tome estas recomendaciones y se las muestre a la persona.
Y esta máquina infernal se ha ganado. Y ganó rápidamente. Tan pronto como mire su teléfono móvil, las recomendaciones se vuelven a contar en una fracción de segundo, y ya le recomiendan teléfonos móviles, estuches, anteojos y similares.
Para aclarar lo que es rápido: soportamos una carga de 7000 rpm (solicitudes por minuto) utilizando solo 3 núcleos de CPU Intel Xeon 2.6 GHz. Esta carga se da en la actividad máxima de los 2 mayores de nuestros clientes.
Que sigue
Parece que desde el modelo actual exprimimos todo lo que es posible.
La mejora adicional requerirá cambios importantes.
Una de las opciones de mejora es la segmentación preliminar de los clientes en grupos.
Las personas se comportan de manera diferente: alguien compra a menudo y poco a poco, alguien rara vez, pero en grandes cantidades, alguien que vende bienes caros, alguien que es barato. De hecho, el modelo en sí mismo debe encontrar dichos grupos y recomendarles lo que necesitan.
Pero puede ser difícil, por ejemplo, si los grupos son pequeños. Por ejemplo, un pequeño grupo de personas jurídicas. O un grupo de hombres en una tienda de mujeres. No siempre se pueden determinar por el atributo formal "género", porque la esposa puede usar una tarjeta de fidelidad emitida para su esposo, y viceversa.
Puede intentar ayudar al modelo, si primero selecciona estos grupos, y luego crea un modelo para cada uno de ellos por separado.
Otro enfoque de mejora más serio puede ser tener en cuenta el historial de acciones.
Ahora solo tenemos en cuenta la prescripción de la acción, y esto no nos permite identificar patrones de comportamiento. Por ejemplo, el modelo no puede entender que si primero compró ropa para mujeres embarazadas y luego pañales, entonces es hora de recomendar alimentos para bebés.
En general, el trabajo para mejorar las recomendaciones, en nuestra opinión, puede durar casi indefinidamente. Con cada nuevo cliente usándolos, aparecen nuevos casos y nuevas hipótesis de mejora.
Así que seguimos mejorando e intentaremos escribir sobre lo que estamos haciendo. No digas adios :)