Chainer-Slack-Twitter-Dialogueを動かすまでに試行錯誤したメモ

Chainerで学習した対話用のボットをSlackで使用+Twitterから学習データを取得してファインチューニング – Qiita を試そうとしたんですが、所詮フロントエンドエンジニア止まりでにわかプログラマーの私にとっては大変苦労したので、試行錯誤したメモを残します。
結果的にはなんとかSlackでbotが動くまでできました。

これから機械学習を行いたい方、上記のサンプルを動かそうとされて断念さた方のの一助になれば幸いです。

一応、筆者のプログラムレベルを書いときます。

  • python歴 2週間(基本、コードはコピペで済みます)
  • phpやJavaScriptをたまにかく
  • データベースは管理画面で見る程度
  • ターミナルはたまに使う程度(cd,ls,pwd,chmod,Ctrl+cのコマンド程度)

基本方針

上記ページを見ながら環境を構築し、動かしていきます。

環境構築

Chainer-Slack-Twitter-Dialogue をgithubからダウンロードして展開。
以下、展開したフォルダ内{myproject}での作業となります。

ライブラリのインストール

brewが使えなかったので pipを使いました。
権限ないとエラーで怒られたので sudo -H で実行

たぶん、スペルミスっぽい

これで大丈夫でした

Prepare the Data の準備

PreTrain
>[Wikipedia for Japanese]https://dumps.wikimedia.org/jawiki/latest/
Train
>[Dialogue Data]https://sites.google.com/site/dialoguebreakdowndetection/

上記は何かのコマンドと思って実行したら、、、全然違いました(汗)

それぞれのURLからデータを取って来いとのことでした。
Qiita記事中で丁寧なコメントのやり取りされてて助かりました(感謝)

https://dumps.wikimedia.org/jawiki/latest/
ここからはWikipediaのデータからタイトルデータで、僕はこの時点で
jawiki-latest-all-titles-in-ns0.gz (10MB)をダウンロード

解答したデータ jawiki-latest-all-titles-in-ns0 は {Chainer-Slack-Twitter-Dialogue}/word2vec/ 内に保存

https://sites.google.com/site/dialoguebreakdowndetection/
対話破綻検出チャレンジさんからは左メニューの 雑談対話コーパス の「4.ダウンロード」から projectnextnlp-chat-dialogue-corpus.zip をダウンロード。

ちなみにNTTドコモの雑談対話APIに使われてるんだとか。

動作確認用に wikipediaのデータを前処理

とにかくテスト用で動かすためにと、ご丁寧にランダムで5000件取得するスクリプトを用意してくれてました。

私は以下のコマンドを実行しました。

word2vec/jawiki-latest-all-titles-in-ns0-rnd5000 がテスト用のデータとして生成されます

Word2Vecのモデル作成

前のテスト用データを指定して実行

こんなエラーが。

–dataで指定したのに通ってない??

word2vec内のファイルword2vec_c.pyx、word2vec_load.py内で ‘test.txt’ がハードコーディングされていた。

以下のように対応。

jawiki-latest-all-titles-in-ns0-rnd5000 → test.txt にリネーム
パーミッションに書込権限を与えておく

hdf5ってライブラリがないから怒られたのでインストール

もう一度、実行

フォルダword2vec内に以下のファイルが生成された

word2vec_chainer.model
word2vec.model

どのファイルも10MB以上になっていた。
word2vec.model をテキストエディタで開くと数字の羅列。
1行目が「5000 300」となっていればたぶん成功。
(word2vec_chainer.model は開けなかった)

対話破綻コーパスからjson生成

ここも公式サイトの通りなんですが、日曜プログラマなの私にとってはプログラマ界隈の常識や当たり前のルールがわからず、かなり苦戦しました。
似たような人の手助けになれば幸いです。

1:data というフォルダを作成していただきます。

これはそのままで、作業フォルダ直下にフォルダ[data]を新規作成

{myproject}/data

2:対話破綻コーパスからjson形式のデータを取得して、下記のような形式で各対話のデータを保存したlistファイルを作成します。

この意味が全然わからずに苦労しました。
「listファイル」は拡張子なしのテキストファイルです。
僕がやった方法を順を追って書いていきます。

2-1:jsonを格納するdevフォルダを新規作成

{myproject}/dev/

2-1: 対話破綻コーパスをダウンロードし展開したらjsonファイルを探す

projectnextnlp-chat-dialogue-corpus/json/
├init100
├1407287164.log.json
└1407219916.log.json

└rest1046
├1404365812.log.json
└1407143708.log.json

2-3:jsonファイル群を {myproject}/dev/ に複製or異動

ディレクトリは不要で、jsonファイル群を全部devフォルダ直下に入れます。

2-4: jsonのパスを全て書いたlist(テキストファイル)を生成

{myproject}/list

現時点ではこのようなフォルダ構成になるはず

{myproject}
├ dev/ ←jsonファイル群
├ data/ ←空
├ list ←テキストファイル
├ word2vec/

3:下記のスクリプトでplayer_1とplayer_2に分けられます。
https://github.com/SnowMasaya/Chainer-Slack-Twitter-Dialogue/blob/master/data_load.py

3-1:上記pythonを実行

▼実行後

{myproject}
├ player_1 ← 生成
├ player_2 ← 生成

jsonから単語が抽出されたテキストファイルが生成されます。
このテキストに、次の”分ち書き”させる前に、好きな言葉を入れておくことで個性を出せそうです。

4:分けたデータは分ち書きが出来ていないのでmecab-ipadic-neologdを使用したmecabで分ち書きをして
各データの名前を下記のようにしてdataフォルダの直下に保存します。
player_1_wakati
player_2_wakati

“分ち書き”というのが最初わかりませんでした。
一言で言うと、文章から単語の区切りや分析を辞書から行うもので、環境の準備が必要でした。

4-1 : 分ち書きのための環境準備

参考サイト)スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その3 – Qiita

インストールの動作テスト : python
以下のコードをsample.pyとして保存

sample.py を実行

成功!

4-2: player_1、player_2を分ち書き

{myproject}
├ player_1
├ player_2

実行前にmecabのパスを確認

2ファイルを分ち書き実行

data/player_1_wakati をテキストエディタで開くと 単語間に半角スペースの区切りが入ったのがわかると思います。
英語だと必ず単語ではスペースが空きますが日本語では空かないからこの処理が必要なんですね。

しかし、web系のへたらプログラマとして、生成するファイルには拡張子を付けないのが気持ち悪いのは僕だけでしょうか…

Twitter,Slackの設定

Prepare enviroment.yml : twitterとSlackで設定用のファイルを新規作成する

{myproject}/twitter/enviroment.yml
{myproject}/slack/enviroment.yml

を作成して、それぞれにTwitter,Slackの必要なAPI情報とかmecabの辞書のパスを指定する
内容は参考サイトのそのままです、APIの取得リンクも参考になりました。

わからなかったのは、「mecab: your mecab dictionary」
結果として、mecabをインストールした時に指定した –dicdir のことだった。 mecab: /usr/local/lib/mecab/dic/mecab-ipadic-neologd

slack の botは事前に登録が必要

Slack で slackbot じゃない bot を作る | Covelline Developer Blog を参考にbotを作成。
作成したbotはテスト用のチャンネルに招待しておきます。

参考までに{myproject}/slack/enviroment.yml の中身

※ “channel” の先頭に “#” は入りません!コメント扱いされますw

slack/app.python でslackからデータ学習コメント受けた時にこんなエラーが出た人は見直してください。

Slackと連携

実行した後に、slack側でチャットすると、このターミナルにテキストが表示される(感動

応答の場合のキーワード: chainer:呼びかけの言葉
学習の場合のキーワード: chainer_train

slackから「chainer:テスト」と打つと以下のエラー

ChainerDialogue.srcvocab ってファイルがないとあるけど…どこで作るんだ??(後述で紹介)
ほんと全然わかってないのに突っ走るのって怖い。

EncoderDecoderModelForward.py の作成

ソースとQiitaの元記事GitHubのIntrodcutionのどこを見ても、手順がどこにも見当たらない。

GitHubのIntrodcution
2.対話のクラス
3.各値を設定

…これは自分で準備しろってこと??(ハンズオン??)

というわけで
{myproject}/EncoderDecoderModelForward.py を新規作成

中身は、GitHubのIntrodcutionのサンプル?なソースコードを順番にコピペ

「1.各種ライブラリ導入」のサンプルコード

#表示用に使用しています。
from util.functions import trace

「2.対話のクラス」のサンプルコード

class EncoderDecoderModelForward(EncoderDecoderModel):

EncoderDecoderModelForward.py の実行

とエラーが。
“word2vec/word2vec_chainer.model” が開けなかった??

を実行して word2vec_chainer.model を再生成。

この時、word2vec.model に書き込み権限がないと何故かエラーになってので書き込み権限(666)を付与したらOKだった。

このエラーが出たら、word2vec_chainer.model が生成失敗してる可能性大。
ちゃんとしていたら5000件のテストデータからでも10MB程度のデータになってる。
再生成して word2vec.model をテキストエディタで開くと1行目が「5000 300」となってるはず。

特にエラーが出なかったので成功??
(というかこのファイルだけでは何も起きない)

「4.実行」のために train.py を新規作成

これでいいのかわかりませんが、僕はこれで動きました。

  1. train.py を空で新規作成
  2. 「1.各種ライブラリ導入」「3.各値を設定」「4.実行」のサンプルコードを順番にコピペ
  3. 新規に作成した対話クラスを読み込ませるため、9行目辺りに追記

train.pyを実行すると処理が始まります(MacBook Airのファンが回り出します)

1時間ぐらい待つと作業フォルダ直下に以下のファイルが生成されてました。

ChainerDialogue.weights
ChainerDialogue.spec
ChainerDialogue.srcvocab
ChainerDialogue.trgvocab

やった!Slackのエラー時に出てた ChainerDialogue.srcvocab ができてる!
slack実行前にテスト。

動作テスト:bot同士の会話

train.py を複製して train-test.py

最後の方をテストコードに書き換えて保存

実行してみる

おおお!!!会話してる!!
放置すると永遠に会話するのでCtrl+Cで止めますw

1万回ぐらい会話してると同じ文章が出てきますが、これはサンプルデータが少ないからでしょうね。
それでも十分会話として成立してて面白い。

Slackでbotとやり取り

slack側からbotに 「chainer:テスト」とチャット送信するとbotが返信!! Slackとターミナルのスクリーンショット
slack/app.py のターミナルでslackのbotが動いてるのがわかります。

slack側からbotに 「chainer_train:テスト」とチャット送信するとエラー…

え、どこにこんなファイル作って書いてあるの??
とマニュアル見返しても見つからず…

{myproject}/twitter/内に
source_twitter_data.txt
replay_twitter_data.txt
を空ファイルで新規作成。
一応書き込み権限(666)を与えておく。

再びslack botを起動してchainer_trainで学習させてみる

おお!学習してくれたっぽい!
学習したどうかテストしてみたいので、chainerで呼びかけてみる。

あれ??
Slack側から何かエラーが出てる?

どうしたのかと思ってFinderを確認すると、以下のファイルのタイムスタンプが変わってて、容量が少なくなってた。

ChainerDialogue.spec
ChainerDialogue.srcvocab
ChainerDialogue.trgvocab

5000行ぐらい全部空行になってた。

ChainerDialogue.weights はタイムスタンプ変更されてたけど、30MBぐらいあった。

学習の追加に失敗したのかな??

ともかくSlackの応答botまで動かせたのでここまで。
player_1,player_2のテキストデータを上手く事前に準備していれば個性を保たせたbotを作れそうです。

苦労しましたがその分、動かせた時は達成感ありました。

改めてこの素晴らしいサンプルデータを公開してくれた GushiSnowさんに感謝です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


*