[PYTHON] Créez un chatbot prenant en charge la saisie gratuite avec Word2Vec

Cet article est l'article du premier jour du Zeals Advent Calendar 2019. Ravi de vous rencontrer. Je suis Tamaki, qui rejoindra Zeals l'année prochaine. Zeals est engagé dans une entreprise utilisant la technologie de chatbot appelée commerce de chat. De plus, je fais actuellement des recherches sur le traitement du langage naturel à l'université. Il y a une conversation dans le bot qui n'introduit pas le traitement du langage naturel, mais j'ai pensé qu'il serait intéressant d'y ajouter une technologie de traitement du langage naturel, alors j'ai décidé d'en faire le thème de cet article.

Qu'est-ce que Word2Vec

Pour le dire très simplement, c'est une technologie qui permet la similitude entre les mots et l'addition et la soustraction de mots en remplaçant les mots par des représentations vectorielles et en apprenant à l'aide d'un réseau de neurones. (C'est trop vague pour voler Masakari) Incorporons les fonctions de similarité et d'addition / soustraction dans le chatbot! Telle est l'histoire de cette époque.

Flux de conversation Chatbot à créer

Une conversation de chatbot est un flux d'écoute des utilisateurs et de proposition du meilleur basé sur celui-ci. Alors, faisons un chat bot qui présente mon boom Vtuber aux utilisateurs cette fois. Le déroulement de la conversation du chat bot cette fois-ci est le suivant.

  1. Demandez à l'utilisateur de saisir les fonctionnalités
  2. Présentation du Vtuber le plus applicable aux fonctionnalités

Vtuber à présenter

Nous déciderons quel Vtuber introduire. Par conséquent, cette fois, nous avons sélectionné des personnes qui ont de fortes caractéristiques parmi les Vtubers et qui ont un grand nombre d'inscrits.

Le premier est Sisters. C'est un Vtuber avec une technologie VR très élevée. Cliquez ici pour la chaîne Youtube d'Omesys

Le second est Tsukinomi Rabbit. Vtuber avec une planification vidéo intéressante. Cliquez ici pour la chaîne Youtube de Tsukinomi Rabbit

La troisième personne est une partition de fleurs. C'est un Vtuber avec une capacité de chant très élevée. Cliquez ici pour la chaîne Youtube de musique de fleurs

Vue d'ensemble du programme

Maintenant, créons un programme chatbot qui introduit le Vtuber ci-dessus. Le déroulement global du programme est le suivant.

  1. Recevez des tweets sur Twitter sous le nom de Vtuber
  2. Formatage des tweets pour entraîner Word2Vec
  3. Générez un modèle Word2Vec avec des tweets formatés
  4. Incorporer le modèle Word2Vec dans le chatbot

La structure des répertoires ressemble à ceci.

.
├── chatbot.py
├── make_model.py
├── model_test.py
└── twitter

Voici le dépôt github créé cette fois https://github.com/ssabcire/chatbot

Version à utiliser cette fois

Obtenez des données de Twitter

Obtenez des tweets sur Vtuber. Je ne pense pas que le code qui atteint l'API Twitter est très important, donc je vais seulement expliquer comment créer un binaire à partir du référentiel qui a déjà été créé et accéder à l'API.

Veuillez cloner ceci. https://github.com/ssabcire/get-tweets

git clone https://github.com/ssabcire/get-tweets.git

Ensuite, créez keys.go et choisissez la clé de l'API Twitter et le répertoire pour stocker le tweet.

keys.go


package lib

const consumerKey string = ""
const consumerSecret string = ""
const accessToken string = ""
const accessTokenSecret string = ""

// path = $HOME+format de chemin. PATH est créé dans le répertoire personnel
const path = "py/chatbot/search-Omeshisu"

Ensuite, appuyez sur l'API Twitter pour générer un binaire à rechercher.

cd search
go build
./recherche Omeshisu

Cela prendra du temps en raison de la limitation de l'API Twitter, mais je peux maintenant faire tweeter les tweets par ʻOmeshisu`.

Création de modèles à partir de tweets

Ensuite, nous formaterons le tweet et générerons un modèle Word2Vec.

make_model.py


import re
import json
from itertools import islice
from pathlib import Path
from typing import List, Set, Iterator
from pyknp import Juman
from gensim.models.word2vec import Word2Vec


def make_w2v(json_files: Iterator[Path], model_path: str):
    '''
Enregistrer le modèle Word2Vec dans Tweet
    '''
    model = Word2Vec(_make_sentences(json_files), size=100,
                     window=5, min_count=3, workers=4)
    model.save(model_path)


def morphological_analysis(tweet: str) -> List[str]:
    '''
Analyse morphologique du tweet et du retour sous forme de liste
    '''
    text = _remove_unnecessary(tweet)
    if not text:
        return []
    return [mrph.genkei for mrph in Juman().analysis(text).mrph_list()
            if mrph.hinsi in ['nom', 'verbe', 'adjectif']]


def _make_sentences(json_files: Iterator[Path]) -> List[List[str]]:
    '''
Lit un tweet, effectue une analyse morphologique et renvoie une liste bidimensionnelle
    '''
    return [morphological_analysis(tweet) for tweet in _load_files(json_files)]


def _load_files(json_files: Iterator[Path]) -> Set[str]:
    '''
Lisez tous les fichiers de la liste qui contient le PATH du tweet JSON récupéré,
Renvoie un ensemble de texte
    '''
    tweets = set()
    for file in json_files:
        with file.open(encoding='utf-8') as f:
            try:
                tweets.add(json.load(f)['full_text'])
            except json.JSONDecodeError as e:
                print(e, "\njsofilename: ", file)
    return tweets


def _remove_unnecessary(tweet: str) -> str:
    '''
Supprimer les parties inutiles des tweets
    '''
    # URL, 'RT@...:', '@<ID> '
    text = re.sub(
        r'(https?://[\w/:%#\$&\?\(\)~\.=\+\-]+)|(RT@.*?:)|(@(.)+ )',
        '', tweet
    )
    #Tweet est Hiragana 1,S'il n'y a que 2 caractères,Vide
    # [", #, @]Je ne peux pas gérer juman
    return re.sub(
        r'(^[Ah-Hmm]{1,2}$)|([ | ])|([#"@])',
        '', text
    )


if __name__ == '__main__':
    cwd = Path().cwd()
    make_w2v(
        islice((cwd / "twitter" / "search-omesis").iterdir(), 0, 5000),
        str(cwd / 'omesis.model')
    )
    make_w2v(
        islice((cwd / "twitter" / "search-kahu").iterdir(), 0, 5000),
        str(cwd / 'kahu.model')
    )
    make_w2v(
        islice((cwd / "twitter" / "search-mito").iterdir(), 0, 5000),
        str(cwd / 'mito.model')
    )

Tout d'abord, je vais expliquer à partir de cette méthode en haut. Créez un modèle en utilisant la classe Word2Vec. Puisqu'il est nécessaire de passer un tableau à deux dimensions au premier argument, nous allons créer un tableau à deux dimensions avec _make_sentences ().

def make_w2v(json_files: Iterator[Path], model_path: str):
    model = Word2Vec(_make_sentences(json_files), size=100,
                     window=5, min_count=3, workers=4)
    model.save(model_path)

_make_sentences () prend un tweet de la liste des tweets, analyse morphologiquement le tweet et crée une liste de mots.

def _make_sentences(json_files: Iterator[Path]) -> List[List[str]]:
    return [morphological_analysis(tweet) for tweet in _load_files(json_files)]

«Juman ++» est utilisé pour l'analyse morphologique. J'utilise Human cette fois, mais toute personne capable d'analyser la morphologie convient, alors utilisez ce que vous voulez.

def morphological_analysis(tweet: str) -> List[str]:
    '''
Analyse morphologique du tweet et du retour sous forme de liste
    '''
    text = _remove_unnecessary(tweet)
    if not text:
        return []
    return [mrph.genkei for mrph in Juman().analysis(text).mrph_list()
            if mrph.hinsi in ['nom', 'verbe', 'adjectif']]

Maintenant, exécutons ce script.

python make_model.py

Il faut beaucoup de temps pour analyser une bonne quantité de tweets, mais j'ai pu générer trois modèles Word2Vec.

Confirmation des mots appris par le modèle

Jetons un coup d'œil aux mots appris dans le modèle

model_test.py


from pathlib import Path
from gensim.models.word2vec import Word2Vec

cwd = Path().cwd()
model = Word2Vec.load(str(cwd / "kahu.model"))
print(model.wv.index2entity)
['Score de fleur', 'Faire', 'Exposition', 'aller', 'chanter', 'Chanson', 'Devenir', 'de', 'J'aime', .......

Les mots sont appris comme ça. Ensuite, regardons le mot qui ressemble le plus à «Hanafu».

print(model.wv.most_similar(positive=['Score de fleur'], topn=5))
> [('Faire', 0.9999604225158691), ('de', 0.9999315738677979), ('Devenir', 0.9999290704727173), ('Dire', 0.9999224543571472), ('Observation', 0.9999198317527771)]

L'observation est le seul mot qui semble avoir un sens dans les mots supérieurs ... Vous pouvez également vérifier la similitude entre les mots.

print(model.wv.similarity('chanson', 'Score de fleur'))
> 0.9998921

Utilisons les fonctionnalités telles que la similitude de Word2Vec et intégrons-le dans le chatbot.

Créer un chat bot

Créer un bot à l'aide de l'API LINE était difficile car je n'avais pas le temps ~~, donc cette fois j'utiliserai une entrée standard et une sortie standard.

chatbot.py


import random
from pathlib import Path
from typing import List, Tuple
from gensim.models.word2vec import Word2Vec
from make_model import morphological_analysis


def exec(vtubers: List[Tuple[str, str]]):
    print("Présentation de Vtuber à partir des fonctionnalités. Quel type de fonctionnalités souhaitez-vous voir Vtuber?")
    utterance = input("Exemple:intéressant,mignonne,Haute technologie, ...Veuillez saisir la fonctionnalité en tant qu'essai: ")
    if not utterance:
        return print("Aucune fonctionnalité saisie")
    wakati_utterance = morphological_analysis(utterance)
    if not wakati_utterance:
        return print("Excusez-moi, mais veuillez saisir les fonctionnalités en d'autres termes.")
    s = set()
    for name, path in vtubers:
        model = Word2Vec.load(path)
        utterance_entities = [word for word in wakati_utterance
                              if word in model.wv.index2entity]
        if not utterance_entities:
            continue
        most_similar_word = model.wv.most_similar_to_given(
            name, utterance_entities)
        if model.wv.similarity(name, most_similar_word) > 0.95:
            s.add(name)
    if s:
        print("Voici le Vtuber qui correspond aux fonctionnalités que vous avez saisies!", _introduce(s.pop()))
    else:
        print('''Je suis désolé, mais je n'ai pas trouvé de Vtuber avec cette fonctionnalité..
Que diriez-vous de cela à la place.''', _introduce())


def _introduce(name: str = "") -> str:
    if not name:
        return random.choice((_message1(), _message2(), _message3()))
    elif name == "Omeshisu":
        return _message1()
    elif name == "Score de fleur":
        return _message2()
    elif name == "Lapin Tsukinomi":
        return _message3()


def _message1() -> str:
    return """\"Omeshisu\"
Cliquez ici pour le lien https://www.youtube.com/channel/UCNjTjd2-PMC8Oo_-dCEss7A"""


def _message2() -> str:
    return """\"Score de fleur\"
Cliquez ici pour le lien https://www.youtube.com/channel/UCQ1U65-CQdIoZ2_NA4Z4F7A"""


def _message3() -> str:
    return """\"Lapin Tsukinomi\"
Cliquez ici pour le lien https://www.youtube.com/channel/UCD-miitqNY3nyukJ4Fnf4_A"""


if __name__ == '__main__':
    cwd = Path().cwd()
    exec([('Omeshisu', str(cwd / 'omesis.model')),
          ('Score de fleur', str(cwd / 'kahu.model')),
          ('Lapin Tsukinomi', str(cwd / 'mito.model'))
          ])

Expliquons brièvement le code. Reçoit l'entrée standard et effectue une analyse morphologique.

def exec(vtubers: List[Tuple[str, str]]):
    print("Présentation de Vtuber à partir des fonctionnalités. Quel type de fonctionnalités souhaitez-vous voir Vtuber?")
    utterance = input("Exemple:intéressant,mignonne,Haute technologie, ...Veuillez saisir la fonctionnalité en tant qu'essai: ")
    if not utterance:
        return print("Aucune fonctionnalité saisie")
    wakati_utterance = morphological_analysis(utterance)
    if not wakati_utterance:
        return print("Excusez-moi, mais veuillez saisir les fonctionnalités en d'autres termes.")

Vérifiez si chaque mot existe dans le modèle Word2Vec de wakati_utterance dans la liste contenant les mots analysés morphologiquement, et si oui, ajoutez-le à la liste. Ensuite, retirez celui avec le plus haut degré de similitude, et si la valeur est de 0,95 ou plus (veuillez décider chacun), ajoutez-le à Set et introduisez Vtuber. Si la similitude est de 95% ou plus, il est prudent de dire que le mot est une caractéristique de Vtuber! Telle est l'idée.

    s = set()
    for name, path in vtubers:
        model = Word2Vec.load(path)
        utterance_entities = [word for word in wakati_utterance
                              if word in model.wv.index2entity]
        if not utterance_entities:
            continue
        most_similar_word = model.wv.most_similar_to_given(
            name, utterance_entities)
        if model.wv.similarity(name, most_similar_word) > 0.95:
            s.add(name)
    if s:
        print("Voici le Vtuber qui correspond aux fonctionnalités que vous avez saisies!", _introduce(s.pop()))
    else:
        print('''Je suis désolé, mais je n'ai pas trouvé de Vtuber avec cette fonctionnalité..
Que diriez-vous de cela à la place.''', _introduce())

Lançons ce script comme un essai.
python chatbot.py
Présentation de Vtuber à partir des fonctionnalités. Quel type de fonctionnalités souhaitez-vous voir Vtuber?
Exemple:intéressant,mignonne,Haute technologie, ...Veuillez saisir la fonctionnalité en tant qu'essai:intéressant
Voici le Vtuber qui correspond aux fonctionnalités que vous avez saisies!"Omeshisu"
Cliquez ici pour le lien https://www.youtube.com/channel/UCNjTjd2-PMC8Oo_-dCEss7A

python chatbot.py
Présentation de Vtuber à partir des fonctionnalités. Quel type de fonctionnalités souhaitez-vous voir Vtuber?
Exemple:intéressant,mignonne,Haute technologie, ...Veuillez saisir la fonctionnalité en tant qu'essai:Une voix qui chante
Voici le Vtuber qui correspond aux fonctionnalités que vous avez saisies!"Score de fleur"
Cliquez ici pour le lien https://www.youtube.com/channel/UCQ1U65-CQdIoZ2_NA4Z4F7A

Ummmm. J'ai pu le présenter gentiment. C'est le meilleur!

Problèmes avec ce programme

Cette fois, j'ai décidé de ne pas l'introduire selon que le mot saisi est inclus dans le modèle, donc Si vous saisissez «la chanson est bonne» ou «la chanson n'est pas bonne», le code ci-dessus réagira à la «chanson» et les personnes qui sont douées pour chanter seront présentées. Je ne comprends pas la dépendance des phrases. Cependant, Word2Vec peut calculer des mots, donc vous pourrez peut-être bien le faire en faisant Song-Poor = <a certain mot>. Il semble intéressant d'essayer plus d'idées ici.

prime

J'écris ceci depuis longtemps, mais en réalité, les chatbots n'utilisent pas beaucoup la liberté d'expression. La raison en est qu'au lieu de laisser l'utilisateur parler librement, l'utilisateur se voit proposer un format de choix tel que Réponse rapide. Cela est dû au fait que le taux de réponse est plus élevé lors des demandes de réponses. (↓ La réponse rapide est une fonction affichée comme ceci)

en conclusion

Le Vtuber que je recommande le plus est Kyo Hanabusa. C'est mignon et la chanson est tellement bonne que je suis contente de pleurer si tu y jettes un coup d'oeil! !! !! La chaîne Youtube de Kyo Hanabusa est ici ... Merci pour votre coopération ...!

Recommended Posts

Créez un chatbot prenant en charge la saisie gratuite avec Word2Vec
Créez une PythonBox qui sort avec Random après l'entrée PEPPER
Créons un groupe gratuit avec Python
Créer une page qui se charge indéfiniment avec python
Python: créer une classe qui prend en charge l'affectation décompressée
Créer une page d'accueil avec django
Créer un répertoire avec python
Créez une application Web qui reconnaît les nombres avec un réseau neuronal
Créons un script qui s'enregistre avec Ideone.com en Python.
Tornado - Créons une API Web qui renvoie facilement JSON avec JSON
Créez une API Web capable de fournir des images avec Django
Créez un programme qui peut générer votre image préférée avec Selenium
Créez un environnement virtuel avec Python!
[LINE Messaging API] Créez un BOT qui se connecte à quelqu'un avec Python
Une histoire qui prend en charge la notation électronique des examens avec reconnaissance d'image
5 façons de créer un chatbot Python
Créez un stepper de poisson avec numpy.random
Créer un téléchargeur de fichiers avec Django
Comment appeler une requête POST prenant en charge le japonais (Shift-JIS) avec des requêtes
Créez un BOT qui peut appeler des images enregistrées avec Discord comme des pictogrammes
Technologie qui prend en charge un service de jet d'argent qui peut monétiser un blog avec une seule balise
Créez une application Web qui peut être facilement visualisée avec Plotly Dash
Créer un décorateur de fonction Python avec Class
[Python] Un programme qui crée des escaliers avec #
Créez une image factice avec Python + PIL.
[Python] Créez un environnement virtuel avec Anaconda
Créer une application graphique avec Tkinter de Python
Créer un gros fichier texte avec shellscript
Créez un système stellaire avec le script Blender 2.80
Créer une machine virtuelle avec un fichier YAML (KVM)
Créez une application Web simple avec Flask
Créer un nouveau dict qui combine des dictés
Créer un compteur de fréquence de mots avec Python 3.4
[Python] Créez un LineBot qui s'exécute régulièrement
Créer un voisin le plus proche de connexion avec NetworkX
Un monde typé qui commence par Python
Créez un bot qui stimule les tendances Twitter
Créer un service Web avec Docker + Flask
Créer un référentiel privé avec AWS CodeArtifact
Créez un compteur de voiture avec Raspberry Pi
Créez une image diabolique avec le script de Blender
Créer une matrice avec PythonGUI (zone de texte)
Créer un graphique avec des bordures supprimées avec matplotlib
Créez un bot avec AWS Lambda qui démarre / arrête automatiquement les instances avec des balises spécifiques
Une histoire qui ne s'est pas terminée par la sortie lors du tournage avec l'entrée de tuyau
[kotlin] Créez une application qui reconnaît les photos prises avec un appareil photo sur Android
Un modèle qui identifie la guitare avec fast.ai
Créer un cadre avec un arrière-plan transparent avec tkinter [Python]
Créez des données de test comme ça avec Python (partie 1)
Créez une application qui devine les étudiants avec Python
Créer un fichier exécutable GUI créé avec tkinter
Mémo qui a fait un graphique pour animer avec intrigue
Créer un LINE BOT avec Minette pour Python
Créez une interface utilisateur de jeu à partir de zéro avec pygame2!
Créer un fichier PDF avec une taille de page aléatoire
Créer un environnement virtuel avec conda avec Python
[Note] Créez une classe de fuseau horaire sur une ligne avec python