LUISによる自然言語処理

# 自然言語とは

人間が日常的に使用している言語。
プログラミング言語などの人工言語と対比した言葉とのこと。

# 自然言語処理って？

自然言語をコンピューターで処理すること。また処理をさせるための一連の技術のこと。
はい。意味がいまいち分かりません。

たとえば、
「山田さんの今の予定は？」
という文があった場合、
人間であれば「山田さんの現在の予定を聞いている」と理解出来るはずです。
その他にも
「山田さんのスケジュールは？」
「山田さんは今何してる？」
なども文は違いますが「山田さんの現在の予定を聞いている」と理解出来ます。

しかしコンピューターはそのままではこれらの文を読み込ませても「山田さんの現在の予定を聞いている」ということを理解出来ません。

このコンピューターではそのままでは理解出来ない自然言語の内容を分析・解析し内容を理解することを自然言語処理と理解してもらえればいいかと思います。

# 自然言語処理をどうやって行う？

自然言語を分析・解析し内容を理解させるとは言ってもどうしたらいいのでしょうか？
解析や分析方法は色々ありますが、自分自身で実装なりなんなりするのは正直厳しいです。
そこで既にリリースされているサービスを利用します。
自然言語処理のサービスも色々あるのですが、今回はMicrosoftの[LUIS](https://www.luis.ai/)を利用します。

# LUISって

Microsoftが提供する自然言語処理を行うサービス。
Language Understanding Intelligent Serviceの略称。
しかしGAしたタイミングでLanguage Understandingになったのに略称はLUISのまま。
ちょっと意味が分からないｗ

LUISの機能としては主に2つです。

- 自然言語の文がどのような意味なのか振り分ける。
- 文中の単語が何を意味する単語なのかを振り分ける。

ぱっと見、違いが無いように思えますが、
「山田さんの現在の予定を聞いている」
という文を処理させた場合、

- Intentの認識 - 予定を聞いている文と振り分けるのが一番目の機能
- Entityの認識 - 文中の「山田」を名前(名字)を意味する単語と振り分けるのが二番目の機能です。

# 前提条件

※本内容は2018年02月07日時点での内容です。

- Microsfotアカウント
- Azureポータルから取得出来るサブスクリプションキー ※新規にLUISポータルからサインインすると無料キーが貰えるので無理に取得しなくてもいいです。

LUISの作業自体は[LUISポータル](https://www.luis.ai/)から全て行います。
BotFrameworkはGAしたタイミングでAzureポータルに統合されたので、
今後LUISもAzureポータルに統合される可能性はあります。

# 実際にやってみる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/36223275-5187-ec1e-b091-53c5476edccb.png)

LUISポータルにアクセスし、サインイン。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/53ee1b87-a717-ab7e-6219-9c12209a93ea.png)

サインインするとMy Appsの画面に遷移するので、**Create new app**をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/cfb84831-02df-3adb-c911-68835969eeac.png)

Appの名前と自然言語処理を行う言語を指定し**Done**をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/bc1b2e36-4c7d-e15a-5720-9e47870cded3.png)

作成したAppの画面に遷移します。

## Intentの設定

Intentの項目が表示されているので、**Create new intent**をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/c1c746ee-48a6-37c1-037c-e7d2e84562b4.png)

Intentの名前を指定し、**Done**をクリック。
今回は「予定を聞く」文脈を認識させたいので「ScheduleSearch」にしています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/3a41cadd-a089-2443-af39-129222f7cdfa.png)

Intent **ScheduleSearch** の画面に遷移します。
ここで「Type about 5～」の記載のあるテキストボックスに予定を聞く例文を入力していきます。
書いている通り5例ほど入力します。

「佐藤さんの予定は」
「鈴木君は何してる」
「高橋様のスケジュールは」
「田中くんって何してる」
「伊藤さんの予定教えて」

※例文ですが1人で考えるには限界があるので、複数人で考えると比較的楽になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/9fc00923-fd6b-b6ae-36d8-59b79c9f41f8.png)

例文入力後、例文を学習するために**Train**ボタンをクリック。
Training後は隣のTestボタンが有効になっているのでクリックして試していきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/c9bc782a-51bb-25b1-18d1-dbd3d90d4ff5.png)

次の例文でテストを実施した結果です。
「渡辺さんは何してる？」
Top Scoring intentがScheduleSearchで0.88となっています。
スコアは0～1からで入力した文がIntentに一致している確度です。
LUISは88%、例文がSchduleSearchと一致していると判断しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/65c33d82-881e-0eac-22ae-aecb14e64402.png)

次の例文でテストを実施した結果です。
「山本さんのスケジュール教えて」
Top Scoring intentがScheduleSearchで0.58となっています。
LUISは58%、例文がSchduleSearchと一致していると判断しています。

このように5例ほどの文ではスコアにバラつきが出るので、色々なパターンを学習させて
行く必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/e6c07487-1eaf-b744-d74c-73f666170f0e.png)

次の例文でテストを実施した結果です。
「こんにちは」
Top Scoring intentがScheduleSearchで0.66となっています。
人が読めばあいさつですが、LUISは63%、例文がSchduleSearchと一致していると判断しています。
一つ前の例文より一致していると判断しています。

このような一致して欲しくない文が一致している場合は、EditからIntentを変更しScheduleSearchの文として判断しないようにさせることが可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/adb68713-a9fa-2f85-c3a0-483ddd906fb2.png)

デフォルトで用意されているIntent **None** に変更することで、
ScheduleSearch以外として学習させます。

## Entityの設定

Intentを設定することで、「予定を聞く」文脈の文を認識させることが出来るようになりました。
しかし、「誰の」予定を聞いているかはまだコンピューターは理解出来ていません。
Entityの設定をすることで「誰の」の部分を理解させていきます。

Entitiesのメニューで一から作成することも可能ですが、
既にIntentを入力済みのため、そこから設定していきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/3d21abcf-b2e7-4e10-edea-07c51d505e50.png)

入力済みのIntentは単語や文節単位で分割されています。
分割された文字列をクリックすると、コンテキストメニューが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/e4c59870-cd6f-1522-f3ca-726cb69f07c7.png)

Search or CreateにEntityの名前を入力します。
ここでは名字のEntityを作成するので、名前は「LastName」にします。
初めてEntityを作成するので**Create new entity**をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/e1a4fe61-a8ef-ae9b-0fd3-6ac67df2f754.png)

入力した名前とEntity typeが指定されているので**Done**をクリック。
Entity typeについては公式の[Entities in LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-concept-entity-types)を参照。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/cb6e4fdc-804a-df09-d44c-ea2cdfadddd5.png)

その他の例文の名字部分もEntityの設定をしていきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/f2a77a1f-5d84-c757-938d-23eb9cc835d2.png)

**Train**をクリックし、再度学習させます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/59067237-c6c7-06b4-15be-a420801f03f8.png)

Training後は再度テストを実施します。
前回と同じ例文を入力すると、前回のテストでは認識していなかった
「渡辺」をLastName Entityとして認識しています。

Entityを設定したことにより、
「誰の」「予定を聞く」という文脈を理解出来るようになりました。

## LUIS Appの公開

「誰の」「予定を聞く」という文脈を理解出来るLuis Appを作成しましたが、
このままでは外から利用することが出来ないので公開をします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/4e76edf9-3a5b-2698-8f4f-a5990ff3ec6a.png)

PUBLISHメニューを開き、公開設定(Production or Staging)、Timezoneを指定し、**Publish to production slot**をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199859/052ff5b3-28a0-15e1-5853-fa05656b934b.png)

公開したLUIS AppはPUBLISHメニューの下にあるResources and KeysのURLからREST APIとして使用出来ます。
またMicrosoftのBotサービスであるBotFrameworkからはKey Stringの値とSETTINGメニューから参照できるApplication IDを使用してLUIS Appを使用出来ます。

# 実際に作ってみて

- 用意されている機能により思いのほか簡単に自然言語処理を行うことが出来る。
- 認識させたい文脈は比較的簡単に認識してくれる。
- 逆に認識させたくない文脈のチューニングが難しいのではと感じる。

次はLUIS AppをBotFrameworkから利用する場合とREST APIを利用する場合を書く予定。