背景
それはすべて、飛行機で典型的なアメリカのコメディを見たときに始まりました- 「なぜ、彼?」(Eng。Why彼?2016) 。 そこでは、音声アシスタントが家のキーキャラクターの1人にインストールされました。 ちなみに、この映画のボットは客と反抗的に話すことができ、時には呪いをかけるだけでなく、中央暖房からトイレの水洗いまで、家全体と周辺地域を制御することができました。 映画を見た後、似たようなものを実装するというアイデアを得て、コードを書き始めました。
図1-同じフィルムのフレーム。 天井の音声アシスタント。
開発開始
最初の段階は簡単でした-Google Speech APIは音声認識と音声合成に接続されていました。 Speech APIから受信したテキストは、手動で記述された正規表現パターンを介して処理され、一致した場合、チャットボットと話している人の意図を決定します。 regexpで定義された意図に基づいて、1つのフレーズが対応する回答リストからランダムに選択されました。 人によって話された文がどのパターンにも該当しない場合、ボットは、「私は単なるコンピューターではないと思うのが好きです」など、あらかじめ用意された一般的なフレーズを言いました。
明らかに、各インテントに対して多くの正規表現を手動で登録するのは骨の折れる作業です。そのため、検索の結果、いわゆる「 単純ベイズ分類器 」につまずきました。 ナイーブと呼ばれるのは、使用されたときに、分析されたテキスト内の単語が互いに関連していないことが理解されるためです。 それにもかかわらず、この分類器は良い結果を示します。これについては以下で説明します。
分類子を書く
そのため、分類子に行を挿入しても機能しません。 入力文字列は次のように処理されます。
図2-入力処理図
各段階で詳しく説明します。 トークン化では、すべてが簡単です。 トライトは、テキストを単語に分解したものです。 その後、いわゆるストップワードは、受信したトークン (ワードの配列)から削除されます。 最終段階はかなり難しいです。 スタンミングは、特定のソースワードのワードベースを取得しています。 さらに、単語の基礎は常にその語根ではありません。 ロシア語にStemmer Porterを使用しました (以下のリンク)。
数学の部分に移りましょう。 すべてが始まる式は次のとおりです。
P(I|D)=P(D|I)∗P(I)/P(D)、ここでI−インテント(意図)、D−文書
P(I|D) -これは、特定の入力行に他の単語の意図を、その人が私たちに言ったフレーズに割り当てる確率です。 P(I) -意図の確率。これは、トレーニングセット内の文書の総数に対する意図に属する文書の数の比率によって決定されます。 文書確率- P(D)=1 したがって、破棄します。 P(D|I) -文書と意図の関係の確率。 彼女は次のように署名します。
P(D|I)=P(w1、w2...wn)|I)=∑niP(wi|I)、
どこで wi -文書内の対応するトークン(単語)
より詳細に記述します。
P(wi|I)=(count(wi、I)+α)/(count(I)+α∗uniqueWords)
ここで:
カウント(wi、I) -トークンがこのインテントに割り当てられた回数
α -アンチゼロ化アンチエイリアス
カウント(I) -トレーニングデータの意図に関連する単語の数
uniqueWords -トレーニングデータ内の一意の単語の数
トレーニングのために、 「hello」、「howareyou」、「whatareyoudoing」、「weather」などのシンボリック名を持ついくつかのテキストファイルを作成しました。 たとえば、helloファイルの内容を示します。
図3-テキストファイル「hello.txt」の内容の例
すべてのJavaコードはGithubで利用できるため、学習プロセスについては詳しく説明しません。 この分類子を使用するスキームのみを示します。
図4-分類子のスキーム
モデルをトレーニングした後、分類に進みます。 訓練データでは、いくつかの意図的変数を特定したため、得られた確率 P(I|D) いくつかあります。
どちらを選択するのですか? 最大値を選択してください!
classify(I1、I2、I3....In|D)=argmaxP(Ii|D)
そして今、最も興味深い分類結果:
いや | 入力文字列 | 特定の意図 | 本当ですか? |
1 | こんにちは、元気ですか? | ホワレヨウ | はい |
2 | 友人を歓迎してうれしい | なんだか | いや |
3 | 昨日はどうだった | ホワレヨウ | はい |
4 | 外の天気は? | 天気 | はい |
5 | 明日はどんな天気ですか? | なにこれ | いや |
6 | すみません、立ち去る必要があります | なにこれ | いや |
7 | 良い一日を | さようなら | はい |
8 | お互いを知りましょうか? | お名前 | はい |
9 | こんにちは | こんにちは | はい |
10 | あなたを歓迎してうれしい | こんにちは | はい |
最初の結果は少しがっかりしましたが、その中に疑わしいパターンがありました。
- フレーズNo. 2とNo. 10は1つの単語が異なりますが、結果は異なります。
- 誤って定義されたインテントはすべて、 whatdoyoulikeとして定義されます 。
この問題は、 平滑化パラメーター( α )0.5から0.1まで。その後、次の結果が得られます。
いや | 入力文字列 | 特定の意図 | 本当ですか? |
1 | こんにちは、元気ですか? | ホワレヨウ | はい |
2 | 友人を歓迎してうれしい | こんにちは | はい |
3 | 昨日はどうだった | ホワレヨウ | はい |
4 | 外の天気は? | 天気 | はい |
5 | 明日はどんな天気ですか? | 天気 | はい |
6 | すみません、立ち去る必要があります | さようなら | はい |
7 | 良い一日を | さようなら | はい |
8 | お互いを知りましょうか? | お名前 | はい |
9 | こんにちは | こんにちは | はい |
10 | あなたを歓迎してうれしい | こんにちは | はい |
結果は成功したと考えており、 正規表現の以前の経験を考えると、特にトレーニングデータのスケーリングに関しては、単純ベイズ分類器がはるかに便利で普遍的なソリューションであると言えます。
このプロジェクトの次のステップは、テキスト内の名前付きエンティティを定義するモジュール( 名前付きエンティティ認識 )の開発と、現在の機能の改善です。
続けてくれてありがとう。
文学
ウィキペディア
ストップワード
ポーターステマー