Les systèmes de recommandation sont devenus une partie intégrante et indispensable de nos vies. Ces algorithmes intelligents jouent un rôle essentiel dans l’élaboration de nos expériences en ligne, en influençant le contenu que nous consommons, les produits que nous achetons et les services que nous explorons. Que nous diffusions du contenu sur des plateformes comme Netflix , découvrions de nouvelles musiques sur Spotify ou effectuions des achats en ligne, les systèmes de recommandation travaillent discrètement en coulisses pour personnaliser et améliorer nos interactions.
L'élément unique de ces systèmes de recommandation est leur capacité à comprendre et à prédire nos préférences en fonction du comportement historique et des modèles d'utilisateurs. En analysant nos choix passés, ces systèmes organisent des suggestions personnalisées, nous faisant gagner du temps et des efforts tout en nous présentant du contenu/produits qui correspondent à nos intérêts. Cela améliore la satisfaction des utilisateurs et favorise la découverte, en nous présentant des offres nouvelles et pertinentes que nous n'aurions peut-être pas rencontrées autrement.
À un niveau élevé, les développeurs comprennent que ces algorithmes sont alimentés par des systèmes d'apprentissage automatique et d'apprentissage profond (appelés indifféremment réseaux de neurones), mais que se passe-t-il si je vous dis qu'il existe un moyen de créer un moteur de recommandation sans avoir à déployer votre réseau neuronal ? modèle net ou machine learning ?
Cette question est particulièrement pertinente dans le contexte des startups en phase de démarrage et intermédiaire, car elles ne disposent pas de tonnes de données structurées pour entraîner leurs modèles. Et comme nous le savons déjà, la plupart des modèles d’apprentissage automatique ne donneront pas de prédictions précises sans données d’entraînement appropriées.
J'ai récemment construit et déployé un moteur de recommandation de base pour un
J'ai eu une vaste
À un niveau élevé, nous avions les exigences suivantes d'un point de vue technique :
Le système doit être capable de capturer les intérêts d'un utilisateur sous forme de mots-clés. Le système devrait également être capable de classer le niveau d’intérêt d’un utilisateur pour des mots-clés spécifiques.
Le système doit être capable de capter l'intérêt d'un utilisateur pour les autres utilisateurs. Il devrait être capable de classer le niveau d’intérêt d’un utilisateur pour le contenu créé par un autre utilisateur.
Le système doit être capable de générer des recommandations de haute qualité basées sur les intérêts d'un utilisateur.
Le système doit être capable de garantir que les recommandations déjà consultées/rejetées par l'utilisateur ne réapparaissent pas pendant un nombre X de jours.
Le système doit avoir une logique pour garantir que les publications des mêmes créateurs ne sont pas regroupées sur la même page. Le système doit faire de son mieux pour garantir que si un utilisateur consomme dix publications (la taille de notre page), toutes doivent provenir de créateurs différents.
Le système devrait être rapide. Moins de 150 millisecondes de latence P99.
Toutes les autres exigences non fonctionnelles, telles que la haute disponibilité, l'évolutivité, la sécurité, la fiabilité, la maintenabilité, etc., doivent être remplies.
Encore une fois, il s’agit d’une liste très simpliste d’énoncés de problèmes. En réalité, les documents comptaient plus de 3 000 mots car ils couvraient également de nombreux cas extrêmes et cas extrêmes qui peuvent survenir lors de l'intégration de ce moteur de recommandation dans nos systèmes existants. Passons à la solution.
Je discuterai des solutions au problème une par une, puis je décrirai le fonctionnement global de l'ensemble du système.
Pour cela, nous avons créé quelque chose appelé un
Comme vous pouvez le voir sur l'image ci-dessus, nous stockons de nombreuses informations, telles que le nombre d'interactions (j'aime, commentaires, partages) et la récence de ces interactions (quand elles se sont produites pour la dernière fois) sous forme de données relationnelles entre deux utilisateurs ainsi qu'entre un utilisateur et un intérêt. Nous stockons même la relation entre deux mots-clés d’intérêt différents. j'ai utilisé
Ces mots-clés d’intérêt sont majoritairement des noms. Il existe un système en place qui décompose le contenu d'un article en ces mots-clés (noms). Il est alimenté par AWS ; un service de traitement du langage naturel (NLP) qui utilise l'apprentissage automatique pour diviser le texte en entités, phrases clés, etc. Encore une fois, vous pouvez utiliser n'importe quel service NLP géré (plusieurs disponibles) pour accomplir la même chose. Vous n'avez pas besoin d'apprendre ou de déployer vos modèles d'apprentissage automatique ! Si vous comprenez déjà l'apprentissage automatique, vous pouvez aller vérifier
Le diagramme suivant est une représentation simplifiée de haut niveau du fonctionnement du système.
Bien que ce qui précède semble simple, il se passe beaucoup plus de choses à chaque étape, et ces éléments doivent être soigneusement réfléchis puis programmés pour garantir que le système fonctionne de manière optimale.
Laissez-moi vous expliquer étape par étape :
Pour générer ces recommandations, nous devons d'abord convertir le contenu d'un article en quelque chose appelé -
Pour générer les intégrations vectorielles, vous pouvez utiliser n'importe quel modèle d'intégration important tel que le modèle d'intégration OpenAI , Amazon Titan ou tout modèle d'intégration de texte open source , en fonction de votre cas d'utilisation. Nous avons opté pour Amazon Titan en raison de son prix avantageux, de ses performances et de sa facilité de fonctionnement.
Maintenant, c'est là que les choses deviennent intéressantes. Vous souhaiterez concevoir les requêtes en fonction des besoins spécifiques de votre entreprise. Par exemple, nous accordons plus d'importance à la récence de l'engagement lors de la recherche d'intérêts qu'au nombre d'engagements avec un mot-clé ou un utilisateur spécifique. Nous exécutons également plusieurs requêtes parallèles pour trouver différents types d'intérêt de l'utilisateur - mot-clé ou autre utilisateur. Puisque nous générons plusieurs flux pour un seul utilisateur, nous exécutons également des requêtes faisant la promotion d'un sujet spécifique en fonction de la tendance (par exemple, vous verrez de nombreux messages liés à Noël à proximité de Noël ou des messages liés aux tremblements de terre si un tremblement de terre s'est produit). Inutile de dire que ce sujet n'apparaîtra dans les résultats de la requête que si l'utilisateur a manifesté un certain intérêt à son égard au cours de son parcours.
Choisissez donc la logique qui convient à votre cas d'utilisation métier et au comportement que vous souhaitez piloter et exécutez plusieurs requêtes pour obtenir une liste suffisamment longue de tous les intérêts de l'utilisateur.
Les bases de données vectorielles sont principalement utilisées pour effectuer un type particulier de recherche appelé
Cache la base de données car l’un des problèmes que nous devons résoudre est la vitesse. Nous avons utilisé des ensembles triés Redis pour stocker les identifiants uniques des publications d'un utilisateur spécifique. Nous avons utilisé des ensembles triés Redis car l'ordre des publications dans le flux d'un utilisateur est critique. De plus, un autre problème que vous devez résoudre est que le « système doit avoir une logique pour garantir que les publications des mêmes créateurs ne sont pas regroupées sur la même page ». Pour éviter la répétition du contenu du même créateur, nous avons écrit un algorithme simple qui garantit que si la publication d'un créateur spécifique est insérée à n'importe quelle position dans le flux d'un utilisateur particulier (ensemble trié), nous n'insérons pas une autre publication du même créateur. pour dix positions successives (nous avons une taille de page de 10 lors de la diffusion du flux à l'utilisateur final, nous l'avons donc gardé statique pour éviter toute complexité).
Pour décider de l'ordre d'une recommandation spécifique de l'utilisateur, nous avons pris en compte les éléments suivants :
La force de la relation avec un intérêt spécifique (ou un autre utilisateur) pour cet utilisateur : Elle est déterminée par une formule arithmétique qui prend différents points de données du graphe social. Tout cela est des données d'engagement comme l'horodatage des derniers likes créés, le nombre de likes créés, le dernier commentaire, etc. Le comportement d'engagement des utilisateurs est l'indicateur de leur intérêt pour quelque chose.
La popularité de la publication sur la plateforme : pour la déterminer, nous avons créé un algorithme qui prend en compte divers facteurs tels que l'engagement, les ratios engagement/impression, le nombre d'utilisateurs uniques qui se sont engagés, etc., pour générer un score d'engagement de cette valeur. publier au niveau de la plateforme.
Dans certains flux, nous donnons la priorité à la popularité ; dans d’autres, nous priorisons le graphe social. Mais surtout, ils constituent tous un mélange sain des deux.
Comme vous pouvez le voir sur le schéma ci-dessus, le système a été intentionnellement gardé très simple. Voici comment fonctionne le système -
Lorsque l'utilisateur A crée une publication, le service de publication, après avoir enregistré cette publication, déclenche un événement pub/sub dans une file d'attente, qui est reçu par un service d'arrière-plan destiné à la génération de candidats. Nous utilisons
Ce service d'arrière-plan reçoit ces informations de manière asynchrone et exécute les fonctionnalités évoquées précédemment : vérifications de confidentialité, vérifications de modération et génération de mots clés, puis génère les intégrations vectorielles et les stocke dans la base de données vectorielle. Nous utilisons
Chaque fois qu'un utilisateur s'engage (aime/commentaire/partage, etc.) après la mise à jour de notre base de données NoSQL principale, le post-service déclenche un événement pub/sub vers le service du moteur de recommandation.
Ce service de moteur de recommandation met à jour la base de données graphique, puis met à jour le flux recommandé de l'utilisateur en temps quasi réel en effectuant la recherche ANN et en mettant à jour la base de données Redis. Ainsi, plus les utilisateurs interagissent, plus le flux s’améliore. Des contrôles sont effectués pour garantir que les recommandations ne sont pas biaisées en faveur d'une liste spécifique de mots-clés . Ces vérifications sont effectuées pendant que nous interrogeons la base de données Graph. Ce service met également à jour le score d'engagement de manière asynchrone. Les scores d'engagement sont également recalculés pour les utilisateurs qui consultent la publication.
Étant donné que toutes les étapes ci-dessus sont effectuées de manière asynchrone en arrière-plan, ces calculs n'ont aucun impact sur l'expérience de l'utilisateur final.
Le flux est finalement servi à l'utilisateur final via un service de flux. Puisque ce service effectue simplement une recherche sur Redis et notre base de données NoSQL principale (
Certains services ont été écrits en
Nous utilisons
Nous utilisons
Comme vous pouvez l'imaginer, cette même configuration peut être modifiée pour créer un moteur de recommandation de base pour n'importe quel cas d'utilisation. Mais comme nous sommes un réseau social, nous aurons besoin de quelques ajustements pour rendre ce système plus efficace.
Des algorithmes d'apprentissage automatique/d'apprentissage profond seront nécessaires au niveau des graphiques sociaux pour prédire les mots-clés et les utilisateurs les plus pertinents pour l'utilisateur. Actuellement, l’ensemble de données est trop petit pour prédire quoi que ce soit avec précision, car il s’agit d’un tout nouveau produit. Cependant, à mesure que les données augmentent, nous devrons remplacer les requêtes et formules simples actuelles par les résultats d’algorithmes d’apprentissage automatique.
Les relations entre les différents mots-clés et les utilisateurs doivent être affinées et rendues plus granulaires. Ils sont actuellement à un niveau très élevé. Mais ils devront être plus profonds. Nous devrons explorer les relations de deuxième et troisième degrés dans notre graphique pour affiner les recommandations dans un premier temps.
Nous n’affinons pas nos modèles d’intégration pour le moment. Nous devrons le faire dans un avenir proche.
J'espère que vous avez trouvé ce blog utile. Si vous avez des questions, des doutes ou des suggestions, n'hésitez pas à me contacter au
Également publié ici .