Pythonで作る対話システムの感想


背景

  • 何か言語処理システムを作ってみようと思ったため

感想

  • 自分のような理論だけじゃ嫌で作らないとわかりずらい・イメージしにくいという方にはかなりおすすめの本.(というか,対話システムの作成方法がまとめれられている日本語の新しい本がこれしかない?)
  • 対話システムとは何なのかというところから,それらの種類について知ることができた.
  • また,各種のシステムをこの本で作成することができ,どのようにして作成するのかのイメージができてよかった.
  • 個人的には,方言への変化やスマートスピーカーへの応用などもあって面白かった.
  • タスク指向の部分は,現状自分が考えていたほど自動化が進んでいるわけではなく,人によるタスク選定が重要なのかなと感じた.このタスクの選定までも自動化できたらかなり便利になるだろうなと思う.

次にやること

  • Pytorchのチュートリアル
  • OpenNMTについて調べる
  • 対話システムのサーベイ論文を読む
  • BERTについて調べる
  • 少しずつ自作していく

VagrantとDockerを用いたC++勉強のための環境構築方法

背景

  • AtCoderの解説動画のプログラムがC++なのでそれを理解するため
  • C++のようなC系の言語をちゃんとやったことがないのでやりたくなったため

環境構築

  • train_cppフォルダを作成し,cdでこの中に移動
mkdir train_cpp
cd train_cpp
  • マウント用にshareフォルダに作成し,その中にtrain_srcフォルダも作成
mkdir share
cd share
mkdir train_src
  • train_cppにVagrantfileを作成し以下のように記述
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
    config.vm.box = "bento/ubuntu-18.04"
    config.vm.synced_folder "./share", "/home/vagrant/share"
    config.vm.define "train_cpp" do |machine|
    machine.vm.network "private_network", ip: "192.168.1.1"
    end
end
  • vmを作成
vagrant up # vm作成
vagrant ssh # vmに接続・アクセス
FROM ubuntu:18.04
ENV DEBISN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -y build-essential
  • shareフォルダ内にdocker-compose.ymlを作成し,以下の内容を記述する
version: '3.7'
services:
  train_cpp:
    build:
      context: .
      dockerfile: Dockerfile
    image: train_cpp
    container_name: train_cpp
    volumes:
    - type: bind
      source: "./train_src"
      target: "/train_src"
  • 以下のコマンドを実行しイメージとコンテナを作成
sudo su
docker-compose build 
docker-compose up
  • 作成したコンテナにアクセスする方法
sudo su
docker-compose run train_cpp bash

感想

  • やっぱり環境構築は時間がかかった.単純に仮想マシンに直で用意すればすぐだったはず......
  • ただ,dockerの勉強にはなったのでそこは良かった.

次にやるとよいことは?

参考ページ

Vagrntで複数VMのネットワーク設定をしつつホストとの共有フォルダの設定方法

概要

  • ホストとvmでファイルを共有するために以下三つの手順を行なった
    • Vagrantfile の設定
    • vagrant-vbguest のインストール
    • CentOS7のカーネルアップデート

背景

前提

Vagrantfile の設定

  • 以下のような内容をVagrantfileに記述する
    • もし,新たにVMを作成する場合には任意のディレクトリを作成後,vagrant init コマンドでVagrantfileを先に作成する.
  • Vagrantfileと同じディレクトリにファイル共有フォルダ(ここではshare)を作成する
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vargrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.8"
  # 以下の一行でホストとvmとの共有フォルダの設定
  config.vm.synced_folder "./share", "/home/vagrant/share"

  # これより以下はVMの例.具体的には2台のVMをIP指定をする設定.
  config.vm.define "任意の文字列" do |machine|
    # ホストオンリーアダプター
    machine.vm.network "private_network", ip: "任意のIPアドレス", auto_config:false
    # 内部ネットワーク
    machine.vm.network "private_network", ip: "任意のIPアドレス", virtualbox__intnet: "任意の内部ネットワーク名"
  end

  config.vm.define "任意の文字列" do |machine|
    # ホストオンリーアダプター
    machine.vm.network "private_network", ip: "任意のIPアドレス", auto_config:false
    # 内部ネットワーク
    machine.vm.network "private_network", ip: "任意のIPアドレス", virtualbox__intnet: "任意の内部ネットワーク名"
  end
end
  • 上記のように一行記載するだけ.vmの設定は以前のまとめより引用.
  • vagrant reload コマンドを実行しvmを再起動する.
    • もし,vmを生成していない場合には,vagrant upコマンドで作成して立ち上げる.

vagrant-vbguest のインストール

  • 以下のコマンドでvagrant-vbguestをインストールしてホストとVMのファイル共有に必要なGuestAdditonを入れる
vargrant plugin install vagrant-vbguest

CentOS7のカーネルアップデート

確認作業

  • vagrant reload コマンドを実行
  • 完了後,vagrant ssh vm名でログインし,フォルダが共有されていることを確認する.

参考先

VagrantでCentOS7のホスト・ゲスト間とVM間ネットワークの設定

概要

  • vagrantで構築した複数のCentOS7の仮想マシンのホストオンリーアダプターと内部ネットワークの設定方法のまとめ.

背景

  • mac m1でPythonで作る対話システムを学んでいるとopenNMTが使えない場面が出たため,Windowsで行なうことにした.
  • 環境を作るところからだが,ただこれまでと同じように作っても面白くないと思い,ちゃんとやった事のないvagrantとdockerで環境を構築しようと考えた.
  • そこで一時的に対話システムを止めてDockerの本を読んで勉強し始めた.
  • が,思ったよりもvagrantでdockerの本用の環境を作成するのに時間がかかったのでまとめる.

Vagrantでの設定

  • 以下のようなVagrantfileを作成
  • 任意の文字列と任意のIPアドレスは重複しないように設定する
  • 任意の内部ネットワーク名は同じ文字列を設定にする
#-*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.8"

  config.vm.define "任意の文字列" do |machine|
    # ホストオンリーアダプター
    machine.vm.network "private_network", ip: "任意のIPアドレス", auto_config:false
    # 内部ネットワーク
    machine.vm.network "private_network", ip: "任意のIPアドレス", virtualbox__intnet: "任意の内部ネットワーク名"
  end

  config.vm.define "任意の文字列" do |machine|
    # ホストオンリーアダプター
    machine.vm.network "private_network", ip: "任意のIPアドレス", auto_config:false
    # 内部ネットワーク
    machine.vm.network "private_network", ip: "任意のIPアドレス", virtualbox__intnet: "任意の内部ネットワーク名"
  end

end

CentOS7での設定

  • VMに vargrant ssh vm名 でログインして管理者権限で以下のコマンドを実行
# 上記のVagrantfileのように記述すればeth1がホストオンリーアダプター
# eth2が内部ネットワーク
nmcli device connection eth1
nmcli device connection eth2

# ログインしているVMのVagrant fileで設定したホストオンリーアダプターのIPアドレスを任意のIPアドレスと置換する
nmcli con mod eth1 ipv4.addresses "任意のIPアドレス/24"
# ログインしているVMのVagrant fileで設定した内部ネットワークのIPアドレスを任意のIPアドレスと置換する
nmcli con mod eth1 ipv4.addresses "任意のIPアドレス/24"

nmcli con mod eth1 ipv4.method "manual"
nmcli con mod eth2 ipv4.method "manual"

nmcli device disconnection eth1
nmcli device disconnection eth2

nmcli device connection eth1
nmcli device connection eth2
  • 設定後,pingをホストからVMに,VMからVMに打って疎通確認をして問題なければ完了

Pythonで作る対話システムの3-3までやってみた

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Pythonでつくる対話システム [ 東中 竜一郎 ]
価格:2970円(税込、送料無料) (2021/4/25時点)


背景

  • 言語処理を使ったシステムを何か作ってみたくなったため
  • いきなり自力では作れないので,何か写経してシステム作成イメージが欲しかった

やったこと

  • 3.3章までの写経.個人的に使いやすくするために使用するデータの置き場所を一つのフォルダにまとめ,使えるように元のコードを編集した.コードはこちらです.

概要

  • 非タスク型指向である用例ベース方式について書かれている
  • 新たに利用するのは,Pytorch,GoogleColab,ElasticSearch.
    • Pytorch:BERTの利用
    • GoogleColab:GPUを用いたモデルの構築
    • ElasticSearch:対話文の検索
  • 用例ベースとは?
    • 入力文と応答文のセット(用例)を元にする方式
    • ルールベースの課題点を解決するために生まれた方式
      • ルールベースは自由に条件を設定し制御しやすいが,条件を拡張する際のコストが高い
  • 入力文に対する用例からの応答文決定には,類似度や対話破綻スコアなどが用いられている
    • 入力文との類似度比較対象は?
      • 用例の入力文・応答文・両方を用いる場合があり,どれが一番良いと言うものはない
        • 求める結果によってどれを選ぶのか考え,工夫することが必要
    • 類似度は?
      • ElasticSearchの検索結果のスコア:大きい方が良い
      • 文同士の単語頻度ベクトルコサイン類似度:0から1の値をとり,1に近いほど類似していることを意味する
      • レーベンシュタイン距離(編集距離):得られる値である編集回数が少ないほど類似していることを意味する
      • Word Mover's Distance (WMD):比較する文を構成する単語の類似度をもとに計算する方法
    • 対話破綻スコアは?
      • 返答文が破綻していない程度を表しており,1であればよく,0に近い程破綻していることを意味する

感想

  • 発話ではなく,応答文との類似性に重きを置く方法を知り驚いた.
  • 発話と応答それぞれとの類似度を掛け合わせる方法もあり,どちらかの類似度が低ければスコアが低くなるので,なるほどと感じた
  • 複数のラベルがついているデータについての前処理として正例の頻度の割合で編集する点が勉強になった.
  • Pytorchを使うのが初めてであったため,Kerasくらい使えるようになっておきたい.
  • モデル構築時にGPUを使う事による処理待ち時間が予想よりもはやく驚いた.

次にやること

  • 3.4を進める
  • WMDの理解
  • Pytorchの勉強
[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Pythonでつくる対話システム [ 東中 竜一郎 ]
価格:2970円(税込、送料無料) (2021/4/25時点)


Pythonで作る対話システムを3-1から3-2までやってみた

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Pythonでつくる対話システム [ 東中 竜一郎 ]
価格:2970円(税込、送料無料) (2021/4/25時点)


背景

  • 言語処理を使ったシステムを何か作ってみたくなったため
  • いきなり自力では作れないので,何か写経してシステム作成イメージが欲しかった
  • タスク指向型の部分は写経して確認したので,非タスク指向の方も進める

やったこと

  • 3-1から3-2までの確認・写経
  • 今回もプログラム内に利用するには登録が必要なAPIがあったが,個人的に登録が面倒なので登録なしでターミナル上に似たような結果が得られるようにした.

概要

  • 非タスク指向型対話システムとは?
    • 対話することが目的のシステム
  • このシステムは必要?
    • 必要:雑談によって,タスクが向上したとの研究報告がある
    • 対話に必要な情報が得られる
  • ルールベース方式
    • 入力された文に対する返答をまとめたファイルを事前に作成
      • マークアップ言語のArtifical Intelligence Markup Language (AIML) を用いてルールをまとめる
    • ルールに基づいて返答を返す

変更した内容

  • 今回もチャットアプリを使用せず,プログラムを実行したターミナルで対話が行われるようにした.
  • 以下は編集したソースコード.ロードしているaiml.xmlこちらで公開されている.
import aiml
import MeCab
from telegram_bot import TelegramBot

class AimlSystem:
    def __init__(self):
        # AIMLを読み込むためのインスタンスを用意
        self.kernel = aiml.Kernel()
        # 形態素解析器を用意
        self.tagger = MeCab.Tagger('-Owakati')

    def initial_message(self):
        # aiml.xmlを読み込む
        self.kernel.learn("data/aiml.xml")
        return {'utt':'はじめまして,雑談を始めましょう', 'end':False}

    def reply(self, dic_input):
        utt = dic_input['utt']
        utt = self.tagger.parse(utt)
        # 対応するセッションのkernelを取り出し,respondでマッチするルールを探す
        response = self.kernel.respond(utt)
        # print(utt, response)
        return {'utt': response, 'end':False}

if __name__ == '__main__':
    system = AimlSystem()
    dic_input = system.initial_message()
    #print('dic_input', dic_input)
    print("bot>"+dic_input['utt'])

    while True:
        raw_input = str(input("me>"))
        dic_input['utt'] = raw_input
        dic_input = system.reply(dic_input)
        print("bot>"+dic_input['utt'])

感想

  • ルール通りに動いているだけとわかっていても対話してくると,機械的ではない対話をしているような感覚があって面白かった.
  • チャットAPIを使わない方法も公開してくださっている事に今更気づいた...次回からこちらで勉強していく.

次にやること

  • 非タスク試行型対話システムである3.2章以降を進める
[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Pythonでつくる対話システム [ 東中 竜一郎 ]
価格:2970円(税込、送料無料) (2021/4/25時点)


Pythonで作る対話システムの2章までやってみた

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Pythonでつくる対話システム [ 東中 竜一郎 ]
価格:2970円(税込、送料無料) (2021/4/25時点)


背景

  • 言語処理を使ったシステムを何か作ってみたくなったため
  • いきなり自力では作れないので,何か写経してシステム作成イメージが欲しかった

やったこと

  • 2章までの写経
  • プログラム内に利用するには登録が必要なAPIがあったが,個人的に登録が面倒なので登録なしでターミナル上に似たような結果が得られるようにした.

概要

  • 対話とは,情報交換の結果生じる変化の過程を意味する
  • 対話システムの意義
    • 音声入力であれば,声のみで使用可能になり便利になる
    • 直感的に使用可能になり,操作方法の学習が不必要になる
    • コミュニケーションを通して,幸せを提供する
  • 対話システムの課題
  • 言外の意味理解
  • マルチモーダル情報の扱い
    • マルチモーダル情報とは,テキストや身振りなどの複数のモダリティをまとめたもの
    • モダリティとは,テキストのような対話に使用される情報種類の単位
  • シンボルグラウンディング(記号接地)問題
    • シンボルグラウンディングとは,指示語が何を示しているのかを外科医の情報と対応づけること
  • フレーム問題
    • フレームとは,返答を考える際に考慮する範囲のこと
  • 対話システムのタイプ
    • タスク指向型
    • 非タスク指向型
  • タスク指向型対話システムとして,天気応答システムを作成
    • 対話行為タイプをSVMで,コンセプトをCRFで推測
    • 対話行為タイプの推定モデルでは,学習データにTF-IDFを使用
  • 強化学習

変更した内容

  • チャットアプリを使用せず,プログラムを実行したターミナルで対話が行われるようにした
  • 天気情報については,天気予報 API(livedoor 天気互換)を利用させていただきました
  • 詳細な変更箇所はまとめられていない.変更したコードは,Githubにまとめている

感想

  • 対話行為タイプでは,分散表現を使用してみてもよさそう
  • 別のタスクを追加してみて理解を深めたい
  • 強化学習は,別で勉強する

次にやること

  • 非タスク試行型対話システムである3章を進める