[PYTHON] Comment créer un système de dialogue dédié aux débutants

introduction

Bonjour. C'est Hironsan. Depuis mars-avril, Line, Facebook, Microsoft et d'autres ont annoncé des plates-formes de développement de robots, un nombre explosif de robots est apparu. En fait, même s'il est limité à Facebook Messenger seul plus de 11 000 Bot sont opérationnels en juillet 2016Faire.

Cependant, la plupart de ces Bot sont de simples systèmes de questions-réponses, pas des systèmes interactifs. Avec cela, il n'est pas possible d'écouter progressivement les goûts de l'utilisateur.

Par conséquent, cette fois, je voudrais créer un ** système de dialogue de recherche de restaurant ** qui prend en compte l'histoire du dialogue, et enfin l'incorporer dans Bot. En tant qu'image terminée, vous pouvez créer quelque chose comme l'animation suivante. bot2.mov.gif

Plus précisément, créez-le dans les étapes suivantes.

En plus de rechercher des restaurants, vous pouvez également discuter. Grâce à la création de ces Bot, le but est de comprendre comment créer un système d'interaction de base.

Public cible

Préparation

Construire un environnement Python

Le système de dialogue créé cette fois sera construit en utilisant le système Python3. Par conséquent, veuillez installer après avoir téléchargé la série Python3 depuis le site officiel.

Download Python

Clonage de référentiel pratique

Nous préparerons désormais un référentiel pratique. Veuillez vous préparer selon la procédure suivante.

  1. https://github.com/Hironsan/HotPepperGourmetDialogue
  2. Cliquez sur le bouton "fork" en haut à droite pour fork (= copy) ce référentiel.
  3. Utilisez git clone pour récupérer le dépôt forké vers votre terminal et changer de branche. Maintenant, vous êtes prêt à partir.
$ git clone YOUR_FORK_REPOSITORY.git
$ cd HotPepperGourmetDialogue
$ git checkout -b tutorial origin/tutorial

De plus, définissez PYTHONPATH directement sous le répertoire HotPepperGourmetDialogue pour l'importation de module. N'ajoutez pas de guillemets doubles "".

$ export PYTHONPATH=`pwd`

Dans l'environnement d'invite de commandes, exécutez ce qui suit.

$ set PYTHONPATH=%CD%

Construire un environnement virtuel

Pour Virtualenv

Pour Virtualenv, exécutez la commande suivante pour créer et activer l'environnement virtuel.

$ pip install virtualenv
$ virtualenv env
$ source env/bin/activate

Pour Conda

Pour Conda, exécutez la commande suivante pour créer et activer l'environnement virtuel.

$ conda create -n env python
$ source activate env   #Pour l'invite de commande, activez env

Obtenir la clé API

Obtenez les deux clés API suivantes à utiliser dans le système d'interaction de recherche de restaurant.

L'API de conversation de chat docomo est utilisée pour discuter avec Bot, et l'API de recherche gastronomique HotPepper est utilisée pour rechercher des restaurants. À titre indicatif, cela prend environ 5 minutes pour la clé API de HotPepper et environ 1 jour pour l'API de dialogue de discussion docomo.

Jusqu'à ce que vous l'obteniez, créez un bot.

Créer un compte Slack

Cette fois, nous allons créer un bot sur Slack. Par conséquent, si vous ne possédez pas de compte Slack, créez-en un parmi les suivants. https://slack.com/

Veuillez définir le nom de l'équipe, etc. sur Yoshina.

Créer un compte Slack Bot

Commençons par créer un compte Slack Bot.

https://my.slack.com/services/new/bot

On suppose que l'équipe Slack est déjà ouverte et connectée en tant qu'utilisateur autorisé. Dans cet état, si vous ouvrez le lien ci-dessus, l'écran de création de compte Bot s'ouvre. Entrez le nom d'utilisateur de votre compte Bot dans le formulaire affiché et appuyez sur "Ajouter l'intégration du bot". スクリーンショット 2016-08-21 22.10.05.png

Appuyez sur "Ajouter une intégration de bot" et un nouveau formulaire sera affiché. Notez le "jeton API" qu'il contient car il sera utilisé dans le bot qui sera créé plus tard. スクリーンショット 2016-08-21 22.25.23.png

Vous pouvez changer le nom et l'image de l'icône du Bot créé avec "Personnaliser l'icône" ou "Personnaliser le nom". Enregistrez vos modifications avec "Enregistrer l'intégration". スクリーンショット 2016-08-21 22.26.46.png

Créons un canal privé et enregistrons le Bot créé pour le test après cela. Après avoir défini comme ci-dessous, enregistrez le contenu avec "Créer une chaîne". スクリーンショット 2016-08-21 22.30.18.png

Ceci termine les paramètres Slack. Commençons maintenant à créer un Bot.

Premier robot

Il est maintenant temps de créer le Bot. Utilisez la bibliothèque Python suivante. lins05/slackbot

L'installation se fait avec pip.

$ pip install slackbot

Essayez de lancer Slack Bot

Tout d'abord, accédez au répertoire de bot.

$ cd application

Après vous être déplacé vers le répertoire de l'application, décrivez les paramètres du Bot dans «slackbot_settings.py».

# -*- coding: utf-8 -*-
import os


API_TOKEN = os.environ.get('SLACK_API_KEY', '')
 
default_reply = "Suimasen. Ce mot Wakarimasen"

Ici, API_TOKEN lit la valeur notée précédemment à partir de la variable d'environnement et l'utilise. Par conséquent, exécutez la commande suivante et définissez la valeur que vous avez notée précédemment dans la variable d'environnement.

$ export SLACK_API_KEY=YOUR_API_KEY  #Pour l'invite de commande: set SLACK_API_KEY=YOUR_API_KEY

Ensuite, écrivez le code pour démarrer le Bot dans «slack_bot.py».

# -*- coding: utf-8 -*-
from slackbot.bot import Bot


def main():
    bot = Bot()
    bot.run()
 
if __name__ == "__main__":
    main()

Il est maintenant temps de démarrer Bot.

$ python slack_bot.py

Répondez à des mots spécifiques dans les mentions ou à des mots publiés sur la chaîne. スクリーンショット 2016-08-21 23.34.15.png

La réponse donnée ici est due au plug-in par défaut de la bibliothèque Slackbot. Cela seul n'est pas savoureux, je vais donc enregistrer le plug-in moi-même et étendre la fonction. Alors, créons le plug-in par nous-mêmes ensuite.

Premier plug-in

Dans Next, créons un Bot pour revenir du "Hello" au "Hello" de l'utilisateur. La bibliothèque Python Slackbot utilisée dans cet article peut être étendue avec des plug-ins. Par conséquent, en implémentant le plug-in vous-même, vous pouvez implémenter la capacité de répondre à des mots spécifiques dans les messages directs et les publications du canal auquel le Bot participe.

Tout d'abord, accédez au répertoire de placement du plug-in dans le répertoire Bot créé.

$ cd plugins

Ce répertoire de plugins contient "\ _ \ _ init \ _ \ _. Py". La raison pour laquelle ce fichier est nécessaire est que le répertoire à charger en tant que plug-in Slackbot doit être un package Python, donc "\ _ \ _ init \ _ \ _. Py" est inclus pour le rendre reconnu comme un package. Au fait, le contenu peut être vide.

Maintenant, après être passé au répertoire de déploiement du plugin, créons en fait le script du plugin. Écrivez le code suivant dans "slack.py".

from slackbot.bot import respond_to
 
@respond_to('Bonjour')
@respond_to('aujourd'hui')
def hello(message):
    message.reply('Bonjour!')

Un décorateur appelé "respond_to" est ajouté à la fonction "hello".

En spécifiant un mot-clé qui correspond à l'argument du décorateur «respond_to», la fonction sera enregistrée pour répondre aux mentions du Bot lorsque le plug-in est chargé. Les mots clés peuvent également être spécifiés à l'aide d'expressions régulières. De plus, comme dans cet exemple, il est possible de faire correspondre plusieurs mots-clés en ajoutant plusieurs décorateurs.

Enfin, ajoutez ce qui suit à «slackbot_settings.py» pour que le plug-in soit chargé.

PLUGINS = [
    'plugins',
]

Lancez Slackbot et envoyez une mention. Veuillez ajouter @. </ font>

$ python slack_bot.py
スクリーンショット 2016-08-21 23.51.18.png

Vous pouvez voir que le Bot créé cette fois-ci réagit comme prévu.

Umu retour Bot

Ensuite, utilisons des expressions régulières pour obtenir ce que dit l'utilisateur. Essayez de modifier "slack.py" comme suit.

# -*- coding: utf-8 -*-
from slackbot.bot import respond_to, listen_to


@listen_to('je(.*)est')
@listen_to('je(.*)est')
def hello(message, something):
    message.reply('Bonjour!{0}M.'.format(something))

Lancez Slackbot et publions. Veuillez ne pas ajouter @. </ font>

$ python slack_bot.py
スクリーンショット 2016-08-22 0.09.12.png

Vous pouvez voir que les remarques de l'utilisateur ont été acquises.

Il existe deux différences majeures entre la fonction Hello précédente et la fonction Hello actuelle. Tout d'abord, cette fois, nous utilisons le décorateur "listen_to". En spécifiant un mot qui correspond à l'argument du décorateur «listen_to», le Bot répondra aux messages sur les canaux auxquels il participe.

L'autre est "(. \ *)" Dans le décorateur. Cela utilise une expression régulière, et vous pouvez la faire correspondre avec n'importe quelle chaîne de caractères en spécifiant "(. \ *)". En outre, le contenu correspondant est stocké dans quelque chose du deuxième argument. Par conséquent, j'ai pu renvoyer ce que j'ai dit en utilisant quelque chose.

Il est encore plus facile pour Bot de résumer simplement ce que dit l'utilisateur. Écrivez simplement le code comme ceci:

@respond_to('(.*)')
def refrection(message, something):
    message.reply(something)

En plus de correspondre à n'importe quelle chaîne, les expressions régulières peuvent correspondre uniquement à des chiffres ou uniquement à des lettres majuscules. Voir ci-dessous pour plus de détails.

Expressions régulières en Python

De plus, lorsque vous écrivez une expression régulière, si vous la vérifiez en temps réel à l'aide d'un éditeur en ligne, vous pouvez immédiatement voir à quel modèle correspond l'expression régulière que vous écrivez, ce qui vous permet de travailler plus rapidement.

https://regex101.com/

regexp.mov.gif

Système de recherche de restaurant

Jusqu'à présent, vous savez comment créer un Slackbot en utilisant la bibliothèque slackbot. À partir de là, nous allons créer un système interactif qui recherche les restaurants en utilisant Python. Ensuite, construisez le Slackbot en incorporant le système de dialogue intégré sur Slack.

L'image terminée est la suivante. bot2.mov.gif Ce bot peut rechercher des restaurants via le dialogue. De plus, ce n'est pas de bon goût en soi, il est donc possible de discuter. Maintenant, créons le dessin terminé quand nous le savons. Tout d'abord, la préparation.

Préparation

Installez la bibliothèque utilisée dans le robot de recherche de restaurant. Exécutez la commande suivante pour installer la bibliothèque.

$ pip install requests
$ pip install pyyaml
$ pip install doco
  • Si vous obtenez une erreur de décodage Unicode lors de l'installation de doco sous Windows
  1. Téléchargez le référentiel depuis https://github.com/heavenshell/py-doco
  2. Modifiez la 18e ligne de setup.py comme suit et installez
open(rst, 'r', encoding='utf-8')
$ python setup.py install

Définissez également la clé API obtenue à partir de l'API de dialogue de discussion docomo et de l'API de recherche gastronomique HotPepper sur les variables d'environnement.

$ export DOCOMO_DIALOGUE_API_KEY=YOUR_DOCOMO_API_KEY
$ export HOTPEPPER_API_KEY=YOUR_HOTPEPPER_API_KEY

Pour un environnement d'invite de commandes, définissez comme suit.

$ set DOCOMO_DIALOGUE_API_KEY=YOUR_DOCOMO_API_KEY
$ set HOTPEPPER_API_KEY=YOUR_HOTPEPPER_API_KEY

Configuration du système

La configuration du système est la suivante. Il suit la configuration du système de dialogue de base. スクリーンショット 2016-08-18 20.50.40.png

Structure du répertoire

La structure des répertoires est la suivante. La structure des répertoires correspond à la configuration du système.

.
├── application                       #Créer un Slackbot
└── dialogue_system                   #Système de dialogue global
    ├── language_generation             #Générateur de langue
    ├── language_understanding          #Département de compréhension linguistique
    │   ├── attribute_extraction          #Extraction d'attributs
    │   ├── dialogue_act_type             #Estimer le type de dialogue
    │   ├── language_understanding.py
    │   └── utils
    ├── dialogue_management             #Département de gestion des dialogues
    ├── backend                         #Département de coopération externe
    │   └── apis
    ├── knowledge                       #Connaissance du domaine
    └── bot.py

Créons maintenant les composants du système un par un.

Compréhension de la langue

Eh bien, créons-le d'abord à partir du département de compréhension linguistique. Nous allons créer les deux processus suivants.

  • Extraction d'attributs
  • Estimation du type de dialogue

Il existe deux façons principales de les réaliser:

  • Méthode basée sur des règles
  • Méthode d'apprentissage automatique

Il est possible de créer un système robuste en utilisant la méthode d'apprentissage automatique, mais il est assez difficile de préparer les données. Par conséquent, créons d'abord une méthode basée sur des règles qui ne nécessite pas de données d'entraînement et qui est relativement facile à créer.

La structure des répertoires du service de compréhension linguistique est la suivante.

.
└── language_understanding          #Département de compréhension linguistique
    ├── attribute_extraction          #Extraction d'attributs
    ├── dialogue_act_type             #Estimer le type de dialogue
    ├── language_understanding.py   #Intégration de l'extraction d'attributs et de l'estimation du type d'interaction
    └── utils                       #Fonction pratique

Extraction d'attributs

Lorsque le service de compréhension de la langue reçoit le texte saisi par l'utilisateur, il en extrait les attributs. Les attributs à extraire cette fois sont les trois suivants. Utilisez ces trois informations lors de la recherche de restaurants.

  • Genre de cuisine
  • endroit
  • Limite budgétaire

Il existe une méthode d'extraction de mots-clés en tant que méthode d'extraction d'attributs basée sur des règles. Il s'agit d'une méthode pour préparer à l'avance un dictionnaire des lieux et des genres de cuisine et extraire la partie correspondante pendant le discours de l'utilisateur. À titre d'exemple spécifique, si l'utilisateur dit "Shinjuku est un bon endroit" et que le mot-clé "Shinjuku" est dans le dictionnaire des lieux, "Shinjuku" peut être extrait comme lieu du discours de l'utilisateur.

La structure de répertoire de la partie d'extraction d'attributs est la suivante.

.
└── attribute_extraction          #Extraction d'attributs
    ├── __init__.py
    └── rule_based_extractor.py

rule_based_extractor.py ressemble à ceci: attribute_extraction/rule_based_extractor.py

Vous pouvez extraire les attributs comme suit.

from rule_based_extractor import RuleBasedAttributeExtractor

extractor = RuleBasedAttributeExtractor()
attribute = extractor.extract(text='Je veux manger des ramen')
print(attribute)
>>> {'LOCATION': '', 'GENRE': 'ramen', 'MAXIMUM_AMOUNT': ''}

Estimer le type de dialogue

Lorsque le service de compréhension de la langue reçoit le texte saisi par l'utilisateur, il estime le type d'interaction. Les quatre types de dialogue suivants sont estimés cette fois.

  • Désignation du genre (INFORM_GENRE)
  • Spécifiez l'emplacement (INFORM_LOC)
  • Montant maximum spécifié (INFORM_MONEY)
  • Autre (AUTRE)

Nous utiliserons le résultat de l'extraction d'attributs pour estimer le type d'interaction. Dans ce procédé, si le genre de cuisson est extrait en tant qu'attribut, le genre est estimé comme le type de dialogue, et si l'emplacement est extrait, l'emplacement est estimé comme le type de dialogue. Si rien n'est extrait en tant qu'attribut, nous évaluerons Autre (OTHER) comme type d'interaction.

La structure de répertoires de la partie estimation du type d'interaction est la suivante.

.
└── dialogue_act_type             #Estimer le type de dialogue
    ├── __init__.py
    └── rule_based_estimator.py

rule_based_estimator.py est un code simple comme celui-ci: dialogue_act_type/rule_based_estimator.py

Après vérification du fonctionnement, ce sera comme suit.

from rule_based_extractor import RuleBasedAttributeExtractor
from rule_based_estimator import RuleBasedDialogueActTypeEstimator

extractor = RuleBasedAttributeExtractor()
estimator = RuleBasedDialogueActTypeEstimator()
attribute = extractor.extract(text='Je veux manger des ramen')
act_type = estimator.estimate(attribute)
print(act_type)
>>> 'INFORM_GENRE'

Intégration de l'extraction d'attributs et de l'estimation du type d'interaction

À ce stade, nous avons extrait les attributs et estimé le type d'interaction. Ensuite, intégrez-les et créez le code du service de compréhension linguistique dans "language_understanding.py".

Le code est ci-dessous. language_understanding/language_understanding.py

Gestion des dialogues

Le service de gestion du dialogue exécute les deux processus suivants en fonction du résultat de la compréhension des intrants (acte de dialogue).

  • Mise à jour de l'état interne
  • Sélection d'action

La structure des répertoires du service de gestion des dialogues est la suivante.

.
└── dialogue_management             #Département de gestion des dialogues
    ├── __init__.py
    ├── manager.py
    └── state.py

Regardons chacun.

Mise à jour de l'état interne

Dans la mise à jour de l'état interne, l'état interne du système interactif est mis à jour en fonction du résultat de la compréhension de la langue. Mettez à jour l'état interne à l'aide de règles. De plus, l'état interne peut avoir diverses informations, mais cette fois, par souci de simplicité, seule l'intention de l'utilisateur est donnée. L'intention de l'utilisateur est les attributs et les valeurs d'attribut obtenus dans le passé. Plus précisément, il contient les informations suivantes.

  • Genre de cuisine (GENRE)
  • EMPLACEMENT
  • Limite de budget (MAXIMUM_AMOUNT)

Tout d'abord, écrivez une classe liée à l'état à conserver. J'écrirai une méthode de mise à jour d'état dans cette classe. dialogue_management/state.py

Ensuite, nous écrirons une classe qui gère le dialogue. La classe de gestion de conversation délègue le processus de mise à jour d'état à la classe d'état. dialogue_management/manager.py

Sélection d'action

La section de sélection d'action décide de l'action suivante en fonction de l'état interne et des règles. Plus précisément, il génère le type d'interaction et le transmet à la génération de langage suivante. Sur la base de ce type d'interaction, le générateur de langue générera le texte. Appelez le lien externe si nécessaire.

Nous écrirons l'algorithme de sélection d'action dans la classe de gestion de dialogue écrite dans la mise à jour d'état interne. La sélection des actions est effectuée conformément à la politique suivante.

conditions Contenu
IF(Type d'interaction utilisateur=OTHER) Type de dialogue pour discuter(CHAT)Production
IF(Certaines valeurs d'attribut ne sont pas renseignées) Type de dialogue de sortie pour découvrir les attributs non renseignés
IF(Toutes les valeurs d'attribut sont remplies) Type de dialogue présentant un restaurant(INFORM_RESTAURANT)Production

Le code réel est ci-dessous. dialogue_management/manager.py

Génération de langue

Le service de génération de langue génère le langage en fonction des règles et des actions de dialogue reçues du service de gestion du dialogue.

La structure des répertoires du générateur de langage est la suivante.

.
└── language_generation             #Générateur de langue
    ├── __init__.py
    └── generator.py

La génération de la langue est effectuée conformément à la politique suivante.

conditions Contenu
IF(Type de dialogue=REQUEST_LOCATION) Écoutez l'emplacement
IF(Type de dialogue=REQUEST_GENRE) Écoutez le genre
IF(Type de dialogue=REQUEST_BUDGET) Demandez votre budget
IF(Type de dialogue=CHAT) Bavarder
IF(Type de dialogue=INFORM_RESTAURANT) Suggérer un restaurant

Ici, l'API de dialogue de discussion de docomo est appelée lors du chat, et l'API de recherche gastronomique HotPepper est appelée lors de la proposition d'un restaurant.

Le code réel est le suivant. language_generation/generator.py

Créer une classe Bot

Ceci termine la création des composants du système interactif. Je vais créer une classe Bot qui les combine. À l'intérieur de cette classe Bot, les composants du système d'interaction fonctionnent ensemble pour générer une réponse à l'utilisateur. dialogue_system/bot.py

Intégré dans Slackbot

Nous allons incorporer la classe Bot créée dans Slackbot. Créez un nouveau plug-in et écrivez le code suivant. application/plugins/slack.py

Après l'intégration, exécutez slackbot.

$ python slack_bot.py

Une fois exécuté, le Bot apparaîtra et vous pourrez interagir. bot2.mov.gif

Être plus intelligent

Cette fois, le service de compréhension de la langue l'a créé par extraction de mots-clés et règles, mais l'extraction de mots-clés ne peut pas extraire les mots qui ne sont pas dans le dictionnaire. Pour résoudre ce problème, vous pouvez utiliser l'apprentissage automatique pour extraire des attributs. En outre, l'estimation du type de dialogue peut être considérée comme une question de classification des phrases. Cela peut également être estimé à l'aide de l'apprentissage automatique. Récemment, les API d'apprentissage automatique ont été améliorées, veuillez donc les utiliser pour améliorer votre service de compréhension linguistique.

C'est Miso, mais dans l'article suivant, nous faisons la compréhension du langage en utilisant l'apprentissage automatique.

De plus, la gestion des dialogues à l'aide de règles est simple et facile à comprendre, mais à mesure que le nombre de règles augmente, il devient impossible de les gérer et de les modifier. Une autre option consiste à utiliser un apprentissage amélioré pour résoudre le problème. De plus, dans le cas d'un système d'interaction vocale, l'entrée peut contenir des erreurs. Des recherches ont également été menées pour traiter les erreurs d'entrée en utilisant un cadre d'apprentissage amélioré appelé POMDP. Si vous êtes intéressé, essayez de gérer le dialogue en utilisant un apprentissage amélioré.

en conclusion

Cette fois, j'ai construit un système de dialogue de recherche de restaurant sur Slack. C'est la fin de la pratique. Comment était-ce. C'était un simple système de dialogue axé sur les tâches basé sur des règles, mais j'espère que vous pouvez ressentir diverses possibilités en le faisant SlackBot. Pensons à un mécanisme pour le rendre plus intelligent en le combinant avec d'autres API Web et API d'apprentissage automatique!

référence

Recommended Posts