LoginSignup
4
1

More than 3 years have passed since last update.

【Dialogflow】一問一答でFAQに答えるチャットボット

Last updated at Posted at 2020-05-11

最近、Webサイトの右下に出てくるチャットボットをよく見ますよね。
本稿では以前にAutoMLで分類した飲食店のFAQをDialogflowに取り込んで精度を見てみます。

実装方針

  • FAQの1つを1つのIntentに割り当てる
  • Intent名は連番とする
  • レスポンスはLabel名とする

データのインポートに関する注意

FAQのIntentを手動で投入してくのは骨が折れるので、インポート機能を使います。
しかし、このインポート機能がまた不便で、JSONファイルしかインポートできません。
そしてさらに不便なことに、JSONファイルを一括でアップロードする機能がありません。
仕方がないので、Agent単位でインポートする方法をとります。
AgentファイルをZIPでDLするとIntentフォルダに1Intentに対して、メタ情報と学習フレーズが別々のJSONファイルで保存されています。
なので、CSVからこの2つのJSONに変換するスクリプトを書きます。
今回は学習フレーズと回答しか考慮しないため、以下の必要最低限のフィールドのみでJSONを作成します。

No Response UserSays1 UserSays2 ... UserSays10
1 toilet お手洗いはどこですか お手洗いはありますか ... トイレはどこ

のような、1行1IntentのCSVデータから

name.json
{
  "name": "No",
  "responses": [
    {
      "messages": [
        {
          "type": "message",
          "speech": [
            "Response"
          ]
        }
      ]
    }
  ]
}

name_usersays_ja.json
[
  {
    "data": [
      {
        "text": "UserSays1"
      }
    ]
  },
  {
    "data": [
      {
        "text": "UserSays2"
      }
    ]
  }
]

の2つのJSONファイルを作成します。

GASでJSONファイルを作成

CSVをスプレッドシートにインポートして、この記事を参考にJSONをZIPで固めて保存します。

function toIntents() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const blobs = new Array();
  for (let i = 2; i <= sheet.getLastRow(); i++) {
    const name = ('000' + (i-1)).slice(-3);
    // name.jsonの作成
    const intent = {
      "name": name,
      "responses": createResponses(sheet.getRange(i, 2).getValue()),
    }
    const intentBlob = Utilities.newBlob(JSON.stringify(intent, null, 4),'application/json',name + '.json');
    blobs.push(intentBlob);
    // name_usersays_ja.jsonの作成
    const userSays = createUserSays(sheet, i);
    const userSaysBlob = Utilities.newBlob(JSON.stringify(userSays, null, 4),'application/json',name + '_usersays_ja.json');
    blobs.push(userSaysBlob);
  }
  const folder = DriveApp.getFolderById('hogehoge');
  const zip = Utilities.zip(blobs, 'jsons.zip');
  folder.createFile(zip);
}

function createResponses(speech) {
  return [
    {
      "messages": [
        {
          "type": "message",
          "speech": [
            speech
          ]
        }
      ]
    }
  ]
}

function createUserSays(sheet, rowNo) {
  const userSays = new Array();
  for (let i = 3; i <= 12; i++) {
    userSays.push({
      "data": [
        {
          "text":sheet.getRange(rowNo, i).getValue()
        }
      ]
    })
  }
  return userSays;
}

データのインポート

データができたら実際にインポートします。
前述しましたが、Agent単位でインポートします。
まずはAgentファイル群をZIPでダウンロードします。
歯車の設定をクリックします。
1.png
タブのExport and Importより、EXPORT AS ZIPをクリックします。
すると、Agentファイル群をZIPで手に入れることができます。
2.png
Angetフォルダの中のintentsフォルダに先ほど作成したJSONを全て格納して再びZIPで圧縮します。

tree
├── agent.json
├── intents
│   ├── 001.json
│   ├── 001_usersays_ja.json
│   ├── 002.json
│   ├── 002_usersays_ja.json
│   ├── 003.json
│   ├── 003_usersays_ja.json
│   ├── 004.json
│   ├── 004_usersays_ja.json
│   ├── 005.json
│   ├── 005_usersays_ja.json
│   ├── 006.json
│   ├── 006_usersays_ja.json
│   ├── 007.json
│   ├── 007_usersays_ja.json
│   ├── 008.json
│   ├── 008_usersays_ja.json
│   ├── 009.json
│   ├── 009_usersays_ja.json
│   ├── 010.json
│   ├── 010_usersays_ja.json
│   ├── Default\ Fallback\ Intent.json
│   ├── Default\ Welcome\ Intent.json
│   └── Default\ Welcome\ Intent_usersays_ja.json
└── package.json

再び圧縮したZIPをRESTOREします。
3.png
Intentsを見てみると、無事取り込めたことが確認できると思います。
4.png
試しに、学習フレーズそのままで話しかけてみると、無事返ってきました!
5.png
しかし、学習フレーズには存在せずAutoMLでは精度を出してくれた「ニコチン最高!」を与えてみると、残念ながらFallback Intentに落ちてしまいました。
6.png

終わりに

エクセルで管理できるような単純な一問一答FAQであれば、簡単に取り込むことができました。
ただし、一括で取り込むのが超メンドクサイ...Googleさん、もう少しどうにかなりませんか?
もっとスマートな取り込み方法があれば教えてください。
また、FAQは色々な聞き方があるので、学習フレーズを全てを網羅するのは難しいですよね。少しでもフレーズから外れてしまうと、Fallback Intentに落ちてしまいます。未知のワードに関しては、AutoMLよりも弱いかも?
そこで、以前記事にした構文を分割することで、1Intentで全てのFAQを対応してしまおう!という構成に落ち着きました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1