Prog-G

岐阜大学プログラミングサークル

音声認識について

岐大祭2018 Unity Mobile

この記事は、岐大祭に向けてアドベントカレンダー的な記事を書く企画の 6 日目です。

私は音声認識を使ってキャラクターを動かすゲームを作ったので、主に音声認識について書いていこうと思います。 おそらく、他の記事よりかは初心者向けかと思われます。

ゲームの概要

このゲームは Unity で制作した、 Android 用のゲームです。 キリンのキャラクター 「ジラ太朗」 に音声で命令してゴールまで導くゲームです。 例えば 「すすめ」 と言ったら進むし、 「ジャンプ」 と言ったらジャンプします。 ムーンサルトさせたり、マシンガンを放ったりすることもできます。 いろいろとはっちゃけてます。

音声認識について

音声認識の方法について書いていこうと思います。 まず、一般的な Android アプリ開発では API を使うことで、簡単に音声認識ができます。 代表的な 音声認識の API として Speech Recognizer というものがあります。 このゲームでも使っています。

しかし、 Unity ではこれだけで音声認識をすることはできません。 一般的な Android アプリ開発が、 Java で行われるのに対し、 Unity は C# であるためです。 そこで Unity には ネイティブプラグイン という機能があります。 ネイティブプラグインを使うと、システムコールやサードパティのコードライブラリなどといった、元々 Unity で使用できない機能にアクセスできます。 これを利用して Speech Recognizer を Unity に適用します。 以下はネイティブプラグインの利用の流れの一例です。

  1. Eclipse, Android Studio などで Java コードを書く
  2. aar ファイル, xml ファイルを作成
  3. Unity に aar, xml ファイルを置く
  4. C# コードを書いてプラグインを適用

……なんでこんな大雑把なのかといいますと、実際はこんなことやってないんです。 というのもすでにこのようなことをやっている方がいまして、プラグインのサンプルがネットに公開されていたためです。 これをお借りして自分なりにアレンジして使用しました。 お借りしたものは こちら で公開されています。 そのため私から音声認識の実装方法に関して、これ以上言えることはありません。

ただ、 Unity は人口が多く、自分がやろうと思っていることをすでにやっている人がいて、やり方やサンプルが公開されているということはよくあることだと思います。 なので、まず何か公開されているものを探すのも1つの手だと思います。

言語処理について

音声認識 API を利用すれば、ある程度の言葉は認識できるようになります。 しかし、発音が似ている単語や辞書に登録されてない造語などは、誤認識されてしまう可能性があります。 API そのものを操作することはできないため、そのような単語を認識させるためには、言語処理をする必要があります。 一番簡単なやり方として、誤認識された文字を本来認識させたい文字に変換するやり方があります。

例: 「攻撃」 と認識させたいが、 「法的」 と誤認識されてしまうとき。

if (text == "法的")  // 法的という単語の時
{
  text = "攻撃";  // 攻撃という単語にする
}

ただ、このやり方だと長い造語などで何パターンもの誤認識が発生してしまう場合、有効とは言えません。 そういった場合、他の文字列の特徴と組み合わせてやれば良いです。 文字列の特徴の一例として長さがあります。

例: 「スピーチレコグナイザー」 と認識させたいが、 「スピーチで国内ザー」, 「スピーチでここのユーザー」, 「スピーチで国内画像」 などと誤認識されてしまうとき。

if (text.Contains("スピーチ") && text.Length >= 9)  // スピーチという単語が含まれていて、かつ9文字以上のとき
{
  text = "スピーチレコグナイザー";  // スピーチレコグナイザーという単語にする
}

上の例では、文字列の中に特定の文字があるかどうかを探索し、さらに文字列の長さを調べています。

以上が人間の手でできる簡単な言語処理の方法です。

考察・感想

ゲームを作ってみた感想をいくつか述べます。

まず、音声認識 API に関して、オンラインとオフラインでは認識の精度が全く違うと感じました。 例えば先ほどの例である 「スピーチレコグナイザー」 は、オンラインでは一発で認識できましたが、オフラインだと何度やっても認識できませんでした。 次に、 漢字, ひらがな, カタカナ が全く別物として認識されてしまうことが不便だと感じました。 こうなった場合、文字数の違いから言葉を識別することはできません。 例えば、 「こうげき」 と 「ほうてき」 では 4 文字中 2 文字の違いがあることになりますが、 「攻撃」 と 「法的」 では全く違う文字列になってしまいます。

私は、音声認識そのものの精度をあげるよりかは、言語処理のほうに興味をもったので今後いろいろと研究できたらいいなと思っています。

最終日は、そんな自然言語処理に関するお話です。