L'expérience de la personnalisation d'une boutique en ligne à l'aide de l'exemple d'une recommandation dynamique

Bonjour, Habr!

Je partagerai mon expérience sur la façon dont nous mettons en place notre propre système de personnalisation basé sur la «connaissance» d'un acheteur potentiel.

image

La seule différence entre notre solution et les solutions classiques était l'utilisation d'un ensemble combiné d'un certain nombre de solutions et satisfaisait la liste des exigences:

  • le service était censé fonctionner immédiatement sur N sites
  • segmentation d'audience dynamique
  • Filtrage collaboratif à des fins de prévision dans différentes conditions de segments d'audience
  • statique pré-généré sous la forme de contenu recommandé + mélange dynamique de produits basé sur l'analyse du flux de clics
  • changement de contenu, presque en temps réel, de la RAM, en tenant compte des coefficients dynamiques

C'est plus détaillé :) Et sur le rake qui nous a aidé à changer la pile pour le mieux.

Contexte


Il existe un groupe de sites du même sujet, dont le public est similaire - les sites d'une seule exploitation. Le contenu est différent, en règle générale, chaque site publie des informations sur les biens que la société holding produit. En plus de ces sites de "contenu", il existe également sa propre boutique en ligne dans laquelle ces produits sont vendus.

Chaque site a sa propre équipe marketing, ses propres compteurs GA et Ya Metrics. Analysant leur propre public, leurs collègues spécialistes du marketing ont personnalisé le contenu du site en tenant compte des besoins des visiteurs. Naturellement, les publics de ces sites se sont croisés, mais comme il n'y avait à l'époque aucun guichet unique, les résultats de l'analyse étaient locaux.

Tout analyste prendra la bonne décision, sera à portée de main avec plus de données. Pour ce bon objectif, il a développé sa propre version du compteur.

Pourquoi pas Google Analytics?

Échantillonnage, le manque de capacité à tout tirer sur l'utilisateur avec sa chaîne de mouvements du site externe, à travers un tas de nos sites, avec des détails qu'il a regardés, etc. Oui, en termes de tâches GA, c'est un bon outil, mais quand vous voulez obtenir des données en temps réel et décider immédiatement quel contenu montrer au visiteur, alors ... le géant de l'analyse n'a pas une telle solution. Danser avec des tambourins d'ID client pour le transfert entre sites n'est pas notre option.
La définition d'un compteur unique pour tous les sites n'est pas une décision «politique» tout à fait correcte, et ils tomberaient immédiatement dans la restriction de la version gratuite.

Je dois dire tout de suite que je n'ai pas commencé à réinventer la roue et me suis limité à une modeste fonctionnelle dont les tâches étaient:

  1. Corrigez chaque utilisateur unique, quel que soit le site sur lequel se trouve le groupe. Cela était nécessaire pour créer un profil client unique dans lequel toutes ses données seraient écrites en référence à chaque site.
  2. Suivi d'une longue chaîne de transitions entre tous les sites d'un groupe au cours d'une session. Cela était nécessaire pour identifier: les intérêts des utilisateurs; ce qu'ils ont regardé; ce qu'ils ont acheté; ce qui a été mis dans le panier mais non acheté; quels produits de différents sites pourraient être des «produits de substitution» au cours du processus d'achat, etc.
  3. Suivi des activités publicitaires de tous les marketeurs (dans chaque équipe du site) pour une analyse ultérieure. Cela était nécessaire pour: enrichir le profil de chaque visiteur; identification de campagnes publicitaires optimales liées au produit; identification de canaux publicitaires efficaces en référence à un produit ou une campagne, etc. la liste est très longue.

Toutes les données ont été versées en temps réel dans la collection locale. Cela s'est avéré pas très mal. À l'avenir, il était possible de faire des rapports agrégés à la fois par produit et par: public, campagnes publicitaires, sources de trafic et tout ce qui me vient à l'esprit. Pour chaque unité de marchandises, il y avait des données sur les prix, la quantité en stock, les remises, les promotions et même une mer de données.

Louez la situation, je suis analyste + développeur + marketeur + manager + j'ai eu accès à tout ce qui a été digitalisé dans la holding. Je n'avais pas de tâche technique au départ, je l'ai fait moi-même pour résoudre des tâches d'analyse de données ordinaires.

Moment technique:


  • MongoDB a été utilisé comme système de stockage unifié
  • collecte de données en temps réel basée sur javascript
  • échange local de données entre sites basé sur rabbitmq

Alors que tout, comme tout le monde ... Mais ça a commencé

Étant donné que les connaissances acquises sur les acheteurs et les produits se sont suffisamment accumulées, nous avons décidé de créer notre propre système de recommandation pour la boutique en ligne.

Tout s'est bien passé. Nous avons tout analysé, mais sans fanatisme. Le modèle a augmenté de taille et, comme cela arrive généralement, le moment est venu où j'en voulais plus.

Moment technique 2:


  • La réplication de MongoDB a aidé à vivre, mais le sharding a été immédiatement abandonné. Ce moment n'a pas passé sur un certain nombre d'aspects internes. Si la collection de flots de clics peut être dispersée autour de fragments, la collection de profils utilisateur n'est plus là. Il était possible de collecter les résultats des requêtes agrégées de différents fragments pour une partie des rapports, mais la vitesse d'exécution laissait beaucoup à désirer. Sans fragmentation, cela a fonctionné mieux et plus stable
  • Collecte de données en temps réel basée sur javascript - ici le bundle CORS + HTTPS était un dictateur. Cas, lorsqu'un utilisateur est venu sur l'un des sites du groupe, et que notre service l'a "autorisé" immédiatement dans la zone multi-domaines (je me souviens, il y avait 5 sites indépendants indépendants à l'époque), c'était technologiquement beau et mystérieux pour les autres marketeurs qui pouvaient maintenant voir tout hit chaîne pour tous les sites à la fois.
  • Le modèle du service de recommandation a été écrit en Python. Mais la formation a pris beaucoup de temps. Le fichier modèle fait plusieurs dizaines de Go.
  • Le service de recommandation fonctionnait normalement sur sa propre API, mais la réponse du serveur est devenue un goulot d'étranglement, ou plutôt, le temps qu'il a fallu pour obtenir le résultat. Plus il y a de données, plus le modèle est grand, plus le modèle est grand, plus le résultat est lent. En réponse, il a fallu prendre en compte de nombreux facteurs qui changeaient toutes les heures (stocks de marchandises en stock, caractéristiques et mode des utilisateurs, toutes sortes de remises, etc.)

Quelques mois plus tard, la qualité de l'API a franchi toutes les limites saines de la «qualité». Pour les utilisateurs, la vitesse de réponse a dépassé la barre des 400 ms. Les blocs de contenu se sont rassemblés lentement, le site a commencé à s'émousser sensiblement. Les collections MongoDB ont totalisé des dizaines de millions de documents ...

Il est temps de changer quelque chose


Presque tous les instruments ont été enregistrés au niveau des opérations, chaque éternuement a été mesuré.

Qu'est-ce qui a changé pour quoi:

  • Clickhouse sur MongoDB
  • plus de MongoDB vers MongoDB + Tarantool
  • EVE sur le ballon
  • Flacon sur Falcon
  • un fichier séparé était avec des promesses en js et avec une autorisation utilisateur sur tous les domaines. Ils n'ont pas changé de logique, le refactoring a gagné

Pourquoi pas l'API métrique?

Au début, je cherchais simplement des solutions toutes faites de Yandex, mais ce ne fut pas long. C'est bien quand un site est en activité. et quand il y a n, et que vous voulez traiter les données immédiatement, alors il n'y a pas de temps pour danser avec des tambourins.

Pourquoi MongoDB?

Des spécifications de produits étaient constamment ajoutées, certaines d'entre elles, hélas, n'étaient pas toujours présentées.
Utilisation de requêtes agrégées - très bien adaptées au format du style technologique local de l'équipe. Le SQL classique ne voulait pas produire de tables.

Très souvent, les types et variantes de données stockées et traitées ont été modifiés.
Au début, je pensais que j'utiliserais Yandex clickhouse comme base pour le service, mais j'ai ensuite abandonné cette idée, mais clickhouse était également dans notre support de pile.

Un nouveau temps est venu, 2000 requêtes par seconde ... à condition qu'en une semaine déployez de nouvelles fonctionnalités et que la charge augmentera encore plus.

Au cours de l'apprentissage automatique, pour la première fois dans htop, j'ai vu 100% de charge de 12 cœurs à la fois et un échange complet sur un serveur productif. Zabbix a informé activement que MongoDB avait déjà changé de maître dans la réplique deux fois en 10 minutes. Tout le monde voulait de la stabilité et un état prévisible.

Il est temps de changer quelque chose 2.0


Le nombre d'utilisateurs a augmenté. Le nombre de clients est similaire. Pour tous ceux qui ont déjà visité l'un des sites, nous avons accumulé un profil personnel. L'audience des visiteurs réguliers était partiellement formée.

Que saviez-vous faire? Oui, tout rapport non standard pour analytics + diversité de contenu:

  • Sélectionnez tous les utilisateurs issus de la campagne publicitaire A, qui était au cours du dernier trimestre, parmi eux, recherchez ceux qui étaient intéressés par les produits de la rubrique N, puis excluez ceux qui ont acheté uniquement en stock, excluez ceux qui ont mis n'importe quel produit dans le panier et sont partis site. Selon eux, effectuez un tri par ordre décroissant des revenus du magasin si ces utilisateurs viennent maintenant sur le site Web du magasin et achètent des produits Z. Quelque chose comme ça, et avec d'autres boutons en nacre ...
  • Pour analyser le trafic entrant, pour les utilisateurs avec la balise utm Y pour former une offre de contenu, mais AVANT la génération, identifiez l'utilisateur, excluez ceux qui étaient la semaine dernière mais qui étaient sur le site S (l'un des groupes de sites de stockage) et qui étaient intéressés par le produit Q - pour une telle générer du contenu trié selon les critères x, y, z
  • Il est banal de trouver ceux qui visitent souvent le site A, cela arrive parfois sur le site B (ils ont visité une certaine section), et qui ont un chèque moyen dans la boutique en ligne de plus de N roubles

En fait, ce n'était pas au format "programmation anormale", je voulais autre chose. Un autre nous est venu. Au moment des campagnes publicitaires, la boutique en ligne était penchée sur la charge, que dire de notre API-shki, qui a pris cette charge «à côté d'elle».

Décisions prises à temps


Nous avons effectué une analyse de l'audience, décidé de collecter du contenu non pas pour tout le monde, mais pour des groupes de visiteurs. Toute la foule était regroupée. Chaque cluster avait ses propres caractéristiques et son «goût» pour le shopping. Le regroupement se fait tous les jours. Ceci est nécessaire pour que lors de la prochaine visite, l'utilisateur affiche exactement le contenu qui lui correspond le plus.

De session en session, les intérêts et les besoins du client changent, et si la dernière fois qu'il a été automatiquement affecté au cluster n ° 788897, puis en tenant compte de ses intérêts actuels, le système peut le transférer vers le cluster n ° 9464, ce qui affectera plus efficacement la conversion suivante.

Après la procédure de clustering quotidienne, l'étape suivante a été lancée - la formation du modèle, la prise en compte des nouvelles données et connaissances sur les clients et la prise en compte des marchandises apparues sur les rayons des magasins ou les laissant pour toujours.

Pour chaque cluster, nous avons préalablement formé des blocs de contenu et les avons enregistrés en mémoire. Puis Tarantool est entré en scène dans toute sa splendeur. Auparavant, nous l'utilisions pour stocker des données rapides, qui étaient ensuite utilisées dans l'apprentissage automatique. C'était la meilleure solution, afin de ne pas secouer MongoDB qui était déjà occupé par d'autres tâches. Dans l'espace, Tarantool stocke des données sur les marchandises, les données des utilisateurs (connaissances nécessaires sur l'acheteur).

En gros, ce soir, nous avons «préparé» du contenu pour chaque groupe de publics susceptibles de visiter le site demain. L'utilisateur est entré, nous avons rapidement déterminé si nous savions quelque chose sur lui, et si la réponse était oui, le package de contenu requis volerait vers Nginx. Par ailleurs, pour les utilisateurs de NoName, un cluster par défaut a été assemblé avec son contenu.

Post-traitement pour personnalisation


Nous savions qu'il y a des utilisateurs simples, et il y a ceux pour qui nous avons tout un dossier de connaissances. Tout cela était dans Tarantool et mis à jour en temps réel.

Au moment de l'assemblage de la page, nous connaissions tout l'historique des achats et des paniers abandonnés de chaque visiteur (s'il avait précédemment été notre client), déterminé son appartenance au cluster, le module clickstream a donné connaissance de la source du trafic, nous connaissions ses intérêts passés et immédiats. En construisant à la volée une gamme de TOP50 à partir de produits précédemment consultés (sur l'un des sites du groupe), nous avons "déterminé la mode" et mélangé le contenu "goût" de ces produits, dont les sujets sont le plus souvent des embranchements dans le TOP50. Cette simple analyse des derniers produits consultés a donné un réel profit. Contenu du cluster, nous avons enrichi personnalisé.

Résultat de notre expérience


  1. Nous avons accéléré le processus de création de contenu personnel N fois
  2. Réduction de la charge du serveur de 15 fois
  3. Nous pouvons créer presque n'importe quel contenu personnellement, en tenant compte des nombreux distributeurs de listes de souhaits, des fonctionnalités de la présentation du produit et des nombreuses exceptions, compte tenu des données du profil utilisateur et des événements qui se produisent actuellement sur le site - et tout cela pendant environ 25 ms
  4. La conversion de ces blocs ne tombe pas en dessous de 5,6% - les utilisateurs sont prêts à acheter ce qui est le plus proche de leurs besoins dès maintenant
  5. La vitesse de chargement des pages est idéale - ils ont supprimé le contenu qui "dépassait" le cluster de> 67%, ce qui est correct
  6. Nous avons un outil qui, selon les tâches des spécialistes du marketing, donne non seulement la réponse «ce qui s'est passé plus tôt», mais aide également à formuler un contenu fragmentaire dans un proche avenir, en tenant compte des intérêts et des besoins des acheteurs potentiels
  7. Des informations de DMP ont été ajoutées au profil de chaque acheteur, maintenant nous pouvons faire du clustering, y compris par réseau social, intérêts, niveau de revenu et autres bonbons
  8. Notre service de recommandation est devenu meilleur, plus de commandes en magasin

À quoi ça sert?


Nous avons acquis une nouvelle expérience, testé un certain nombre d'hypothèses que nous ne savions pas aborder auparavant, nous n'utilisons pas de solutions payantes tierces pour un service de recommandation qui ne prenait pas en compte toutes nos fonctionnalités et travaillait sur le même domaine. L'équipe a reçu un bon cas intéressant, qu'elle a réussi à gérer.

Les appétits grandissent ... nous testons maintenant une nouvelle logique d'assemblage de contenu. Nous voulons collecter des pages pour des campagnes publicitaires, des newsletters et d'autres activités externes. Les plans incluent le transfert de la logique de configuration du mode manul vers le sens d'apprentissage automatique. Les sites vivront leur propre vie, et nous, à l'exception du «pop-corn», observerons l'évolution de la présentation du contenu du site en fonction de l'opinion de l'IA.

Source: https://habr.com/ru/post/fr462887/


All Articles