そういえば最近Mac Book Proを新しくしたのでPython環境が整っていなかった。今まではpyenv + pyenv-virtualenvでバージョン管理してたんですが、最近ではPython公式がPipenvを推してるらしいのでpyenv + pipenvという構成にしてみた。
$ mkdir rasa-sample $ cd rasa-sample $ pipenv install
ぼくの環境ではpyenvでpython3.7.3を先にインストールしていたので、pipenvの仮想環境も3.7.3で構築されたみたい。
公式のチュートリアル動かしてみる
公式ドキュメント
Rasa-xなるよく分からんもんをインストールしろと書いてあるけどいらなそうなのでrasaだけインスコします。
--skip-lockはPipfile.lockを更新しないオプションです。これをつけないとパッケージ一個インストールするのに Locking... って表示されて数分待たせてしまう。
チーム開発するときは必ずpipenv lock
してからpushしましょう。
$ pipenv install rasa --skip-lock
pipenvを使う場合、仮想環境に入る必要があるっぽい。これでrasaコマンドとかも使えるようになる。
$ pipenv shell
公式のチュートリアル
だーっとファイルが生成されます。rasaを使うために必要なファイルやデータファイルが一通り生成される模様。
$ rasa init --no-prompt
$ tree . . ├── Pipfile ├── Pipfile.lock ├── __init__.py ├── actions.py ├── config.yml ├── credentials.yml ├── data │ ├── nlu.md │ └── stories.md ├── domain.yml ├── endpoints.yml ├── models │ ├── 20190706-102404.tar.gz └── rasa_core.log
教師データっぽいのをのぞいてみる。markdownで書かれてるのが面白い。
$ cat data/nlu.md ## intent:greet - hey - hello - hi - good morning - good evening - hey there ## intent:goodbye - bye - goodbye - see you around - see you later ## intent:affirm - yes - indeed - of course - that sounds good - correct ## intent:deny - no - never - I don't think so - don't like that - no way - not really ## intent:mood_great - perfect - very good - great - amazing - wonderful - I am feeling very good - I am great - I'm good ## intent:mood_unhappy - sad - very sad - unhappy - bad - very bad - awful - terrible - not very good - extremely sad - so sad%
なんかよくわからんけど会話できた。すげえ。
$ rasa shell 2019-07-06 10:26:27 INFO root - Starting Rasa Core server on http://localhost:5005 Bot loaded. Type a message and press enter (use '/stop' to exit): Your input -> hello Hey! How are you?
Intent分類と固有表現抽出をしたかったので、別に会話できる必要はないんだが。
Rasa NLUのみを動かす
公式ドキュメントに書いてあった。
https://rasa.com/docs/rasa/nlu/using-nlu-only/
これでNLUだけ動かせる。hello! nice to meet you.
と入れたらintent:greetであると判別された。
$ rasa shell nlu NLU model loaded. Type a message and press enter to parse it. Next message: hello! nice to meet you. { "intent": { "name": "greet", "confidence": 0.656333863735199 }, "entities": [], "intent_ranking": [ { "name": "greet", "confidence": 0.656333863735199 }, { "name": "goodbye", "confidence": 0.5116747617721558 }, { "name": "mood_unhappy", "confidence": 0.026658378541469574 }, { "name": "affirm", "confidence": 0.0 }, { "name": "deny", "confidence": 0.0 }, { "name": "mood_great", "confidence": 0.0 } ], "text": "hello! nice to meet you." } Next message:
ふむ大体のカラクリはわかった。今度は飲食店のおすすめを聞くintent分類と固有表現抽出をしてみたい。
data/rlu.mdに下記を追加。
## intent:restaurant - [渋谷](location)で美味しい[イタリアン](restaurant_type)ない? - [和食](restaurant_type)食べたいんだけど、[六本木](location)におすすめある? - 今度[麻布](location)行くんだけど、[フレンチ](restaurant_type)のお店教えて
config.ymlをちょっと修正。
こちらを参考にした。
https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part2.html
残念ながらこの辺はまだあんまり理解できてないが、固有表現抽出するにあたってどんなモジュールを使って処理するかを選択してる。これ変えるだけで色々調整できるのは素敵。
# Configuration for Rasa NLU. # https://rasa.com/docs/rasa/nlu/components/ language: en # pipeline: supervised_embeddings pipeline: - name: "tokenizer_whitespace" - name: "ner_crf" - name: "ner_synonyms" - name: "intent_featurizer_count_vectors" - name: "intent_classifier_tensorflow_embedding" # Configuration for Rasa Core. # https://rasa.com/docs/rasa/core/policies/ policies: - name: MemoizationPolicy - name: KerasPolicy - name: MappingPolicy
学習して試してみる。
$ rasa train nlu
ぴゃーーー
$ rasa shell nlu NLU model loaded. Type a message and press enter to parse it. Next message: 渋谷の美味しい和食 { "intent": { "name": null, "confidence": 0.0 }, "entities": [], "intent_ranking": [], "text": "\u6e0b\u8c37\u306e\u7f8e\u5473\u3057\u3044\u548c\u98df" }
日本語対応するにはどっかしらいじらないといけないようだ。仕方ないので今回は英語で。
data/nlu.md
**## intent:restaurant** - Isn’t it delicious Italian in Shibuya? - I would like to eat Japanese food, but is it recommended for Roppongi? - I’m going to Azabu next time, but tell me a French shop
$ rasa train nlu
ちゃんとintent: restaurant
と認識しましたね!
$ rasa shell nlu NLU model loaded. Type a message and press enter to parse it. Next message: I want to eat Italian in Shibuya { "intent": { "name": "restaurant", "confidence": 0.9497830271720886 }, "entities": [], "intent_ranking": [ { "name": "restaurant", "confidence": 0.9497830271720886 }, { "name": "affirm", "confidence": 0.09771481156349182 }, { "name": "goodbye", "confidence": 0.08525433391332626 }, { "name": "greet", "confidence": 0.05800335854291916 }, { "name": "mood_great", "confidence": 0.0 }, { "name": "deny", "confidence": 0.0 }, { "name": "mood_unhappy", "confidence": 0.0 } ], "text": "I want to eat Italian in Shibuya" }
次回は日本語対応してみたいと思います。