Sujets suggérés - Suggestions basées sur le titre et le contenu

Ce serait tout à fait fantastique si les sujets suggérés prenaient en compte les titres et le contenu des sujets. Par exemple, si vous lisez un sujet sur le thème de « l’analyse », des sujets contenant un contenu similaire pourraient être intégrés aux résultats de suggestion actuels.

Si cela pouvait être réalisé efficacement, je suis convaincu que ce serait un succès assuré pour augmenter l’engagement, tant pour les nouveaux visiteurs que pour les utilisateurs actifs. Même si ces suggestions se contentaient d’utiliser uniquement les titres des sujets (au lieu du titre et du contenu).

6 « J'aime »

J’ai créé un sujet similaire, mais il est verrouillé.
Actuellement, j’ai désactivé cette fonctionnalité et l’ai remplacée par la mienne.

1 « J'aime »

Il s’agit d’une fonctionnalité très complexe à construire efficacement, et le sujet est un véritable abîme. À un certain point, on commence à envisager l’apprentissage automatique, et l’abîme ne fait que s’approfondir.

Je comprends l’intérêt d’utiliser l’IA pour déterminer du contenu connexe ; cela peut être très pratique pour les sujets de Support, qui peuvent presque devenir « en libre-service ». Vous posez une question, le ML sélectionne 10 candidats et les publie simplement en tant que réponse que vous pouvez soit accepter, soit supprimer. De même, lorsqu’un utilisateur anonyme consulte une section d’aide, il est utile d’afficher du contenu connexe.

Cela dit… c’est une tâche gigantesque. Ce n’est pas prévu dans notre feuille de route pour l’année prochaine. Mais @eviltrout est très intéressé par l’expérimentation de l’IA/ML à un moment donné, et c’est le genre de projet qui pourrait s’y rattacher.

@codinghorror reste un grand fan de DJ Random, car il estime que cela peut surpasser de nombreux algorithmes sophistiqués (et c’est souvent le cas).

7 « J'aime »

DJ random est fantastique, bien que nous le limitions par heure et par catégorie / tag — cela compte.

3 « J'aime »

Bonjour,

Nouveau parmi vous, désolé si je m’attarde sur un sujet déjà épuisé.

Je suis d’accord avec @sam pour dire qu’il y a un piège, mais d’un autre côté, la technologie de modélisation thématique est désormais assez mature et des outils prêts à l’emploi très performants existent. Un projet récent que j’ai mené a analysé environ 5 millions de titres et résumés de brevets ; analyser l’ordre de grandeur de milliers de sujets sur mon tout nouveau site Discourse site serait un jeu d’enfant. De plus, ma communauté pourrait avoir l’énergie nécessaire pour rendre cela possible.

De la part des experts : j’aimerais avoir votre avis sur le fait de savoir si je devrais envisager de concevoir un plugin, ou si je devrais plutôt me pencher sur le code source de Discourse (que j’ai téléchargé depuis GitHub).

J’ai trouvé cela concernant l’extraction de sujets Discourse avec Python, mais je n’ai pas encore réussi à le faire fonctionner. Quelque chose de similaire devrait me permettre de récupérer les données hors ligne, de construire le modèle, puis de le charger pour des requêtes ultérieures.

La plupart des bons outils sont en Python, à titre d’information…

4 « J'aime »

Fonctionnellement, cela s’intègre mieux dans le panneau « Votre sujet est similaire à… » lorsque vous rédigez un nouveau sujet.

1 « J'aime »

Je vous recommande vivement de privilégier un plugin plutôt que de modifier le code source. Il est extrêmement peu probable que nous puissions intégrer une fonctionnalité de ce type dans le cœur du système, car cela nécessiterait une dépendance massive vis-à-vis de Python ainsi qu’une interface utilisateur étendue pour l’entraînement, etc.

Il y a beaucoup de travail à prévoir concernant les mécanismes d’entraînement et autres. Avez-vous une description détaillée des mécanismes par lesquels vous effectueriez l’entraînement ? Quels modèles précis recommanderiez-vous d’utiliser ? Que se passe-t-il lorsqu’un sujet comporte 100 messages ? 1000 messages ?

Quels signaux utiliseriez-vous, et quelle pondération attribueriez-vous à chaque élément (vues, catégories, balises, etc.) ?

Je suis extrêmement enthousiaste à l’idée de ce projet, mais je sens qu’il s’agit d’une tâche assez considérable.

3 « J'aime »

Il y a beaucoup de travail à faire concernant les mécanismes d’entraînement, etc. Avez-vous un aperçu des mécanismes par lesquels vous effectueriez cet entraînement ? Quels modèles exacts recommanderiez-vous d’utiliser ?

Les outils actuels utilisés par mon équipe proviennent de gensim. Il dispose d’une interface standard module Python. Il a été assez bien testé depuis de nombreuses années.

La configuration qui me vient à l’esprit serait la suivante :

  • Premièrement : choisir un ensemble de documents : cela pourrait être l’ensemble des racines de sujets, ou l’ensemble des messages.

De temps en temps (par exemple, une fois par semaine ? une fois par mois ? selon le trafic du forum), construisez le modèle doc2vec :

  • Scrappez les sujets Discourse dans un fichier (ou plusieurs fichiers) de texte md, titre + corps du sujet. Considérez maintenant chaque sujet comme un document, ou « document », pour les algorithmes Gensim.
  • Exécutez des outils NLP standards pour traiter les documents, effectuer la mise à la racine des mots, etc.
  • Utilisez doc2vec (de l’implémentation Gensim) pour construire un modèle qui mappe chaque document dans un vecteur dans un espace de dimension d. Vous devez choisir le paramètre méta d par expérimentation ; Google utilise d=40 pour ses modèles de brevets ; je ne suis pas sûr de la valeur de d utilisée par Google Scholar. J’utilise généralement d=200. Chaque dimension de l’espace peut être considérée comme une « caractéristique » liée au contenu sémantique.
    • (À titre d’information : l’algorithme doc2vec construit l’espace de caractéristiques en entraînant un réseau de neurones ciblé pour apprendre les séquences de mots ; le réseau de neurones possède une couche cachée de dimension d ; les sorties de la couche cachée forment l’espace latent de caractéristiques)
  • La construction du modèle est la tâche la plus lourde, selon le nombre de documents que vous avez. 38 ans de brevets = 5 millions de documents ; le modèle doc2vec prend toute une nuit sur une vieille machine à 8 cœurs.
  • Tâche supplémentaire intéressante (optionnelle) : regrouper le nuage de documents dans l’espace de caractéristiques de dimension d.
    • Des outils prêts à l’emploi pour le regroupement, par exemple de la bibliothèque Python sklearn, peuvent être utilisés.
    • Le regroupement fournit une classification émergente ; des questions de recherche intéressantes incluent la manière dont ces classifications se chevauchent avec les catégories de mots-clés (ou de tags Discourse).

Cela se déroulerait hors ligne. Ensuite, en ligne :

  • Le modèle serait chargé.
  • Une fois le modèle chargé, une tâche plutôt légère consiste à analyser un nouveau document et à interroger le modèle pour obtenir sa position dans l’espace de caractéristiques de dimension d.
    • Notez que ce nouveau document ne déclenchera pas une reconstruction du modèle. Le modèle restera statique pour les requêtes en ligne. Le nouveau document sera intégré lors de la prochaine construction du modèle (par exemple, hebdomadaire).
  • Enfin, la dernière tâche légère consiste à demander quels sont les documents voisins dans l’espace de caractéristiques. Il existe des outils Gensim pour obtenir une liste de documents voisins, mais vous pouvez également utiliser numpy directement pour charger tous les vecteurs de documents dans une structure comme un arbre kd qui permet une requête rapide des points voisins directement.

Que se passe-t-il lorsqu’un sujet compte 100 messages ? 1000 messages ?

La partie hors ligne évolue plus ou moins linéairement avec le nombre de documents, mais devrait être très gérable pour 10 000 à 100 000 documents. Même 1 million de documents est acceptable pour un traitement par lots hebdomadaire.

Qu’utiliseriez-vous comme signal, et quelle force donneriez-vous à chaque élément (vues/catégorie/tag, etc.) ?

Dans ce contexte, la « force du signal » pour un nouveau sujet est directement interprétée comme la distance (inverse) entre l’incrustation de l’espace vectoriel du nouveau sujet et les vecteurs de documents existants. On pourrait habiller ce signal avec d’autres considérations (likes, vues, etc.), mais ce sont des fioritures supplémentaires par rapport à l’algorithme de base que je décris.

Une fois que moi (ou quelqu’un d’autre) aura fait fonctionner le scraping, la partie hors ligne décrite ci-dessus est assez simple et mécanique.

La partie difficile (pour moi) serait la partie en ligne, qui nécessiterait une interface entre Rails Discourse et quelques appels Python (par exemple, vers les outils Gensim). Tout exemple de ce type d’interface serait utile pour que je puisse l’examiner.

6 « J'aime »

@Bcat : Je serais très intéressé de voir comment vous avez « remplacé par le vôtre ». Avez-vous un plugin ou un dépôt que je pourrais consulter ?

La pièce délicate en termes de performance est le mécanisme RPC ici. Vous ne voulez pas lancer un nouveau processus Python pour chaque visualisation de sujet.

Même un appel HTTP pourrait être trop lent.

Peut-être… peupler une table related_topics (topic_id, related_topic_id, rank) ? Vous pourriez alors vous appuyer sur les WebHooks pour mettre à jour la table rapidement lorsque de nouveaux sujets sont publiés, et Ruby n’aurait plus besoin d’appeler Python.

Du côté de l’implémentation Discourse, ce serait assez simple : vous devriez simplement réécrire cette méthode pour consulter les informations dans votre nouvelle table related_topics.

2 « J'aime »

L’ancienne méthode ne fonctionnait pas, alors je l’ai remplacée par Google Ads. Les sujets suggérés par Google sont très astucieux.
Quant à l’ancienne façon de faire, j’ai désactivé la suggestion par défaut et l’ai remplacée par un extrait JavaScript qui appelle /search, puis renvoie une liste de sujets.

2 « J'aime »

Merci pour l’orientation vers l’implémentation du tableau. Cependant, je ne suis pas sûr que cette approche soit évolutive. Pour N sujets, nous avons besoin d’un tableau de taille N^2. Ainsi, pour 10^4 sujets, le tableau contiendrait 10^8 entrées.

Je ne vois pas comment éviter d’avoir besoin d’un appel Python pour analyser un nouveau sujet, l’encoder et trouver ses plus proches voisins. J’ai déjà construit une interface web, mais je serais probablement tenté, dans ce cas, d’exécuter simplement un processus Python en arrière-plan et de communiquer avec Discourse via une socket ou un canal, de manière à ressembler davantage à des lectures et écritures dans un fichier qu’à un véritable appel Python. (Après tout, tout s’exécute sur mon serveur…)

Désolé, je pense que je comprends tout à fait mal la situation ?

Si vous avez 100 sujets et que chaque sujet affiche 5 sujets connexes, pourquoi le tableau devrait-il être plus grand que 500 ?

1 « J'aime »

N topics = N points dans la représentation de l’espace vectoriel.
La matrice des distances entre chaque point est de taille N² (la matrice étant symétrique, il y a N*(N-1)/2 valeurs indépendantes). C’est ce N² auquel je faisais référence.

Cependant, des structures de données astucieuses (par exemple, un arbre kd) permettent de trouver les voisins les plus proches sans effectuer une recherche exhaustive dans le tableau des N² différences.

Quoi qu’il en soit, je sais comment réaliser tout cela en Python, en renvoyant le petit tableau auquel vous faites référence, de taille N x 5 pour les 5 topics les plus proches.

1 « J'aime »

Ensuite, si vous exécutez cela quotidiennement en Python, vous pouvez simplement connecter Python directement à la base de données Discourse pour qu’il génère ce tableau de cache.

Ensuite, la partie du plugin Discourse devient assez triviale. Au lieu de sélectionner depuis l’emplacement X, il sélectionne depuis l’emplacement Y (un tableau différent).

Vous n’avez plus besoin de vous battre avec des pipelines qui doivent faire le pont entre deux langages de programmation pour une seule requête.

L’approche d’IA qui a été suggérée ici semble intéressante et pourrait être la solution idéale.

Je me demande s’il ne vaudrait pas la peine d’explorer une approche moins technique : la section « Sujets suggérés » pourrait contenir un bouton « Suggérer un sujet ». Cliquer sur ce bouton permettrait aux utilisateurs de publier un lien vers un autre sujet sur le site, ainsi qu’une brève description de la raison pour laquelle les deux sujets sont liés.

Ce n’est pas une maquette complète, mais pour être sûr que nous sommes sur la même longueur d’onde, je veux dire quelque chose comme ceci :

Pour le contexte, je souhaite suggérer des sujets qui soutiennent et contredisent les points de vue exprimés dans un sujet particulier. Par exemple, si quelqu’un crée un sujet affirmant que le changement climatique n’est pas un problème majeur, j’aimerais que les utilisateurs du site puissent suggérer des sujets connexes qui soutiennent ou contredisent cet argument.

Cela pourrait également être utile pour des sujets moins controversés. Lorsque je réponds à un sujet ici, j’utilise souvent la fonction de recherche du site pour voir s’il existe des sujets connexes. Les résultats de cet effort pourraient être préservés en permettant aux utilisateurs de suggérer des sujets connexes. Par exemple, la lecture de ce sujet m’a fait penser à l’utilisation récente de l’IA par Discourse ici : Discourse Disorder. Il me semblerait pertinent que ce sujet apparaisse dans la liste des sujets suggérés de ce sujet, avec une note indiquant que Discourse semble étudier des moyens d’intégrer les forums à l’IA.

3 « J'aime »

Mise à jour, ceci est maintenant implémenté dans le plugin Discourse AI :confetti_ball:

5 « J'aime »