Wowgineer Notes

WowTechエンジニアの徒然開発日記

Wowgineer Notes

〜新たな"Wow"を生み出す〜

1週間で作って社内リリースしたヘルプボットを性能改善した話

お久しぶりです。WowTalkのAndroid開発担当している岡野です。

前回1週間でヘルプボット作って社内リリースした話を書きました。

その際にいくつか課題が出ましたので、今回は前回ほど専門的な内容ではありませんが、課題解決までのアプローチを書いていきたいと思います。

1.前回の課題点

前回作成したボットですが、欠点として単一のキーワードを送った時した回答できないという課題がありました。通常ユーザーがボットに質問する時には適当な長さの文章を送ってくると考えると使い物にならないですね。

この課題を解決するため下記の流れでアプローチしていきました。

  1. 文章の形態素解析によるキーワード抽出
  2. 形態素解析サービス/ツールの選定
  3. 記事の検索方法の変更 

1つずつ見ていきましょう。

2.文章の形態素解析によるキーワード抽出

形態素解析とはなんぞやというと方のためにお話しすると、要は文章を意味のある単語単位(形態素)で分割し、それぞれの品詞などを解析する作業です。

例文 Androidでログインができない
形態素で分割 Android/で/ログイン/が/でき/ない
品詞の抽出  名詞 / 助詞 / 名詞 /助詞 /動詞 / 助動詞

この中で意味のある単語=キーワードは「Android」「ログイン」= 名詞となることはわかると思います。あとはこのキーワードをうまくユーザガイドの検索ワードとして投げてあげるだけ。

3.形態素解析サービス/ツールの選定

SaaSサービス信者になりつつある自分はAWSにも形態素解析できるサービスがあるのではと探してみるとAmazon Comprehendというサービスがありました。

やったぜ(*´-`)...と思ったけどこれ、日本語に対応していなかった...orz

他にないかなと探してGoogle Cloud Platform(GCP)にもCloud Natural Language APIという似たようなサービスがあるそうです。

Googleさんなら日本語にも対応しているし安心かな。

f:id:okano4413:20191003114754p:plain

Cloud Natural Language Apiでの解析

ちゃんと日本語も解析できてるようです。

あとはコスト面が気になるので確認することにしました。料金のページを見ると構文解析を含むNatural Language Apiはユニット単位の課金らしいです。(以下抜粋)

 

Natural Language API の使用量は「ユニット」の数に基づいて計算されます。分析のためにこの API に送信される各ドキュメントのユニット数は、少なくとも 1 ユニットとなります。ドキュメントに 1,000 文字を超える Unicode 文字が含まれている場合(空白文字や、HTML / XML タグなどのマークアップ文字も含まれます)、1,000 文字 = 1 ユニットの複数ユニットとしてカウントされます。

たとえば、Natural Language API に送信する 3 件のリクエストそれぞれに、800 文字、1,500 文字、600 文字が含まれている場合、1 番目のリクエスト(800)が 1 ユニット、2 番目のリクエスト(1,500)が 2 ユニット、3 番目のリクエスト(600)が 1 ユニット、合計 4 ユニットとして課金されます。

Natural Language API の使用料は、使用された API の機能とその機能を使用して評価されたユニットの数に基づいて、月単位で計算されます。次の表に、請求月に分析されたユニットの総数に基づく 1,000 ユニットあたりの料金を示します。

つまり1000文字ごとに1ユニットが消費され、最低でも1回のリクエストで1ユニットが消費されるそうです。

通常チャットで質問する時には短文であることが多いため、これでは費用対効果が悪いと判断しました。無念。。。

このAPI、そこそこの長さの分を構文解析する時には有用だけど、今回みたいな短文向きではなさそうです(料金的な意味で)。

最後に以前Androidの開発の時にふと見つけたKuromojiというライブラリを思い出してnodeモジュールがないか探してみることに。ありました

最近はなんでもありますね。ほんと助かります。

f:id:okano4413:20191003121327p:plain

Kuromojiによる解析

 これなら日本語にも対応してくれてるし、料金も利用したLambdaのリソース分しかかからないので、(Lambdaの利用料金は実行時間と消費したメモリの量に依存するため)残念なコードを書かない限り料金も抑えれそうです。

 以下今回の調査のまとめです。

目的 文(sentence)を単語(word)に分割できる    
  amazon comprehend cloud natural language api Kuromoji
機能 構文解析
キーフレーズ抽出
感情分析
エンティティ分析
言語検出など
構文解析
エンティティ分析
感情分析
コンテンツ分類など
構文解析
長所 ・ドキュメントからそのドキュメントが何を指すものなのかを学習させることでユーザの真に知りたい内容や行いたい行動を抽出できる ・精度自体はAWSよりいいと思う。
・5000ユニットまで無料利用枠がある
・node moduleを
入れるだけですぐ利用できる
・Lambdaの無料利用枠を利用した計算ができる
短所 ・日本語で利用できる機能が少ない。
・文章の解析がメインとなるため、ボットのように短文で質問を行う場合は費用対効果が悪い
・1ユニットが1000文字で設定されているためAWSよりも費用対効果が悪い ・名詞を分割して解析するので自分でどこまでがまとまった単語なのか判定するロジックを追加する必要がある。
料金体系 10億文字まで
$0.0001/100文字
10億文字まで
$0.001/1000文字
Lambdaの利用枠内

4.記事の検索方法の変更

前回WP REST APIで検索を行う時、通常の質問形式や複数キーワードを投げても適切な回答が得られないという話をしました。これは

{domain}/wp-json/wp/v2/posts/?search="キーワード"

のクエリで検索した時に、完全一致で検索しようとするため、投稿のタイトルや本文内に質問文と同じものがなければ検索結果に出てこないことが原因でした。

またユーザの質問文に含まれるキーワードが必ずしもユーザガイドに含まれないこともあります。

例えば「トークの一覧」という言い方をする人と「トークのリスト」という人がいる場合にユーザガイド内の言い方が「トークの一覧」だったとすると後者の検索で「リスト」というキーワードに一致しなくなります。

このような揺らぎを少しでもなくすために、ある程度予測される表現については別途「タグ」として管理することにし、「タグ」による検索を行えるようにしました。

{domain}/wp-json/wp/v2/posts/?filter[tag]="キーワード1,キーワード2..."

こうすることでかなりの期待したものに近い結果が得られるようになりました。

f:id:okano4413:20191003143458p:plain

あとは細かいロジックの調整(連続する名詞を1つの単語として検索する、一致するキーワードが多い記事を優先して表示するなど)をして完成(?)と相成りました。

5.これからのお話

今回ユーザーガイドURLを取得するボットを作っていて気づいたのが、

「1つの記事の中で複数の機能を説明している」

記事があることです。

もちろん、全く関係のない機能を説明しているわけではないのですが、本来ユーザーが調べたい機能以外のことが多く存在していると、欲しい回答を探す手間が発生します。

せっかく回答の書かれたURLを教えてもらってもその回答がすぐにはわからないとストレスになってしまいますね。これは当社のユーザーガイド作成の至らない点です。。。

 

今後はユーザーガイドの改善もしながらボットの改善を目指して行けるようにも動いていきたいと思います。そしていつの日か、このボットが皆さんの前に現れてくれることを願います。

6.おわりに

今回の記事では、以前作成した「キーワードに一致する記事のURLを返却するボット」へのリクエストフォーマットを改善してより意味のあるURLを返すようにするための取り組みについて記載しました。内容としてはあまり専門的なものではなかったですが、結局はこういう地道なことの積み重ねでUXがよくなるのかなとも思っています。

 

次回はいい加減Androidについて記事を書きたいなと思いますので、その時は改めてよろしくお願いします。^^; 

参考URL

 

我々ワウテック技術開発部はこのような環境で開発をしています。
興味を持った方がいらっしゃればいつでもご連絡下さい。

f:id:wowtech-dev:20190313163146j:plain