[PYTHON] Construction d'un système de recommandation utilisant le bouche-à-oreille doc2vec

Je suis bokeneko, la bière artisanale de Retty et l'ingénieur. J'ai créé un système de recommandation expérimental en utilisant doc2vec, je vais donc vous présenter la méthode.

doc2vec

doc2vec est une évolution de word2vec. word2vec essaie de capturer la signification d'un mot par quels mots sont susceptibles d'apparaître autour de lui, mais doc2vec apprend à lui ajouter plus de contexte.

Par exemple, l'idée de word2vec est que "chien" et "chat" ont des significations similaires parce que "chien" et "chat" sont inclus dans xxx de la phrase "j'ai xxx". est. Cependant, si cette phrase est tirée d'un roman sur un chien, "chien" est extrêmement plus facile à sortir que "chat", et s'il s'agit d'un passage d'un roman SM ... J'espère que tu comprends. En d'autres termes, puisque la facilité avec laquelle les mots apparaissent dépend du contexte de la phrase, doc2vec vous permet d'apprendre quel type de phrase la phrase est à partir de quel type de mot est utilisé.

Pour plus d'informations, veuillez lire Représentations distribuées de phrases et de documents. Pour être honnête, je l'ai peut-être mal interprété car il est lu en diagonale.

Évaluer doc2vec

Vous pouvez apprendre l'expression distribuée des avis en appliquant des avis à doc2vec. Il y a doc2vec dans gensim, alors utilisons-le. Je suis vraiment reconnaissant qu'il soit facile de l'essayer, mis à part la théorie.

# -*- coding:utf-8 -*-

from gensim.models.doc2vec import Doc2Vec
from gensim.models.doc2vec import TaggedDocument

import MeCab
import csv

mt = MeCab.Tagger()

reports = []
with open("reports.tsv") as f:
    # reports.ID de bouche à oreille sur une seule ligne pour tsv,Les avis sont enregistrés dans les délimiteurs d'onglets
    reader = csv.reader(f, delimiter="\t")
    for report_id, report in reader:
        words = []
        node = mt.parseToNode(report)
        while node:
            if len(node.surface) > 0:
                words.append(node.surface)
            node = node.next
        #words est une liste de mots de bouche à oreille,Spécifiez l'ID de bouche-à-oreille dans les balises
        reports.append(TaggedDocument(words=words, tags=[report_id]))

model = Doc2Vec(documents=reports, size=128, window=8, min_count=5, workers=8)
model.save("doc2vec.model")

Vous pouvez maintenant apprendre le bouche-à-oreille en tant que vecteur de 128 dimensions. Vous pouvez vérifier le vecteur de bouche-à-oreille appris comme suit.

# -*- coding:utf-8 -*-

from gensim.models.doc2vec import Doc2Vec

model = Doc2Vec.load("doc2vec.model")
sample_report_id = .... #ID de bouche à oreille pour lequel vous souhaitez vérifier l'expression distribuée

report_vector = model.docvecs[sample_report_id]

Recommandation

Maintenant que nous avons appris le vecteur de bouche-à-oreille, quand il s'agit de le recommander, nous pensons d'abord à la moyenne ajoutée de tous les vecteurs de bouche-à-oreille d'un utilisateur comme le vecteur qui représente cet utilisateur. De la même manière, considérez la moyenne ajoutée de tous les vecteurs de bouche à oreille d'un magasin comme le vecteur représentant ce magasin. Utilisation du vecteur utilisateur et du vecteur de stockage créé de cette manière

Je pensais pouvoir dire ça. C'est juste une hypothèse, alors faisons-le immédiatement car nous devons l'essayer pour voir si cela fonctionne.

ngt

J'ai utilisé ngt pour calculer rapidement le voisinage du vecteur.

Pour l'utiliser, préparez les valeurs suivantes pour chaque dimension d'un vecteur sur une ligne séparée par des tabulations pour les utilisateurs et les magasins.

users.tsv


-0.32609        0.0670668       -0.0722714      -0.0738026      0.0177741 ....
...

restaurants.tsv


0.0385331       0.0978981       -0.0495091      -0.182571       0.0538142 ...
...

Ceci est fait en écrivant le résultat de doc2vec ci-dessus.

Créez ensuite un DB avec la commande suivante.

$ ngt create -d 128 users users.tsv
$ ngt create -d 128 restaurants restaurants.tsv

Ensuite, vous devriez avoir le répertoire suivant.

<cur dir>
|--restaurants
|   |-- grp
|   |-- obj
|   |-- prf
|   |-- tre
|
|--users
    |-- grp
    |-- obj
    |-- prf
    |-- tre

Maintenant, vous êtes prêt à partir. La recherche est la suivante.

#Lors de la recherche d'utilisateurs
$ ngt search -n 10 users search_query.tsv

#Lors de la recherche d'un magasin
$ ngt search -n 10 restaurants search_query.tsv

# search_query.tsv est écrit avec le vecteur cible sur une ligne et les valeurs de chaque dimension du vecteur séparées par des tabulations.
#Si vous cherchez un magasin près de chez moi, recherchez_query.Ecrivez mon vecteur utilisateur dans tsv.

Magasins à proximité des utilisateurs

Commençons par m'utiliser comme table de laboratoire et recommander des magasins que je recommande à ceux pour lesquels je n'ai pas rédigé d'avis.

Classement url
1 Shamrock par Abbott Choice
2 Têtes d'artisanat
3 Abbott Choice Shibuya
4 Édition du pub Swan Lake
5 Marché de la bière artisanale Magasin Jimbocho
6 Cooper Ales
7 Salle de robinetterie Bashamichi
8 8taps
9 Bungalow
10 Les Shannons

Je m'appelle la bière artisanale de Retty, mais ce n'est qu'un magasin de bière. C'est certainement mon préféré, donc je pense que ça marche.

Surtout Craft Heads n'a pas écrit de bouche à oreille, mais j'en ai beaucoup vécu. Ensuite, je parle d'écrire un bouche à oreille. De plus, je ne suis jamais allé dans la salle des robinets de la route carrossable. Désolé pour le bouche-à-oreille: P

Magasin à proximité du magasin

Les Craft Heads mentionnés ci-dessus sont mon magasin préféré, alors essayez de trouver un magasin à proximité de ce magasin.

Classement url
1 The Griffon
2 Bonne bière Fausets
3 Pub de bière Camden
4 Vivo!Bar à bière et à manger
5 Abreuvoir
6 Brewdog Roppongi
7 Salle des clapets Nakameguro
8 TAP STAND
9 République de Meguro
10 Burgon Dise Heimel

Ouais, c'est juste un magasin de bière. Au fait, je suis allé à tous. Il semble que le magasin de bière soit correctement recommandé.

Des utilisateurs proches des utilisateurs

Je ne vais pas mettre en dehors des utilisateurs autres que les employés de Retty, alors passez ici. Au fait, quand j'ai mis des utilisateurs près de moi, il y avait certainement des amateurs de bière.

Utilisateurs proches du magasin

C'est aussi un utilisateur, donc je vais l'ignorer.

Résumé

Est-il possible d'obtenir un vecteur représentant les utilisateurs / magasins en ajoutant la moyenne du bouche-à-oreille doc2vec? Je l'ai essayé sur la base de l'hypothèse, mais cela semble fonctionner assez bien. J'ai utilisé mecab pour récupérer le mot cette fois, mais phrasepiece semble assez intéressant, donc je pense l'utiliser cette fois.

P.S.

Dans ce qui précède, j'ai écrit que la moyenne ajoutée du vecteur de bouche à oreille est le vecteur utilisateur / vecteur de magasin, mais en fait, j'ai imaginé un peu plus.

Au début, c'était juste une moyenne supplémentaire, mais quand je l'ai essayé en interne, on m'a dit que mes anciens passe-temps étaient trop reflétés. Donc, si vous donnez plus de poids aux critiques récentes, il est dit qu'il n'y aura pas de magasins qui correspondent à vos loisirs pour ceux qui manquent de magasins de loisirs et qui ont beaucoup de messages autres que les magasins de loisirs de nos jours ... Puisqu'il y a eu diverses choses, je répète des ajustements fins. Le résultat ci-dessus est le résultat après le réglage fin.

Recommended Posts

Construction d'un système de recommandation utilisant le bouche-à-oreille doc2vec
Recommandation d'analyse des données à l'aide de MessagePack
Implémentation d'un système de dialogue utilisant Chainer [seq2seq]
Recommandation de poésie
Exemple d'utilisation de lambda
Remarques sur la création d'un environnement Linux à l'aide de VirtualBox + Vagrant sous Windows 10
Construction d'un environnement de développement Cortex-M pour TOPPERS utilisant Raspeye