【AmiVoice API Private・SDK】実用的な「ルールグラマ」を作ってみた【実践編】
大倉尭
皆さん、こんにちは!
「ルールグラマ」シリーズの3本目となります。今回は「基本編」に続き、ルールグラマの実用的な書き方を解説します。「基本編」の内容が前提となりますので、初めてルールグラマを作成する方は先に「基本編」をご覧ください。
また、そもそも「ルールグラマって何?」という方は、こちらの記事をご覧ください。
※なお、ルールグラマを使った音声認識には、AmiVoice API PrivateまたはAmiVoice SDKで「ルールグラマエンジン」を使用する必要があります。ルールグラマを使った開発にご興味のある方は、個別相談会からお申し込みください。
複数単語の認識
直列(単語列)
「基本編」では1単語(例えば「AmiVoice」)のみが認識できるルールグラマを作成しましたが、複数の単語を認識したい場合も多いと思います。単語列(単語を直列に並べたもの)を認識させたい場合は、単語のあいだを半角スペースで区切って記述します。例えば、「音声認識 は AmiVoice」という単語列を認識したい場合は、以下のように記述します。
public <sample> = 音声認識\おんせーにんしき は\わ AmiVoice\あみぼいす;
※本記事のサンプルでは、ヘッダ行およびグラマ名定義行(「基本編」のサンプルにおける1行目・2行目)は省略します。
このように書くと、「おんせーにんしき わ あみぼいす」という発話について、「音声認識 は Amivoice」という認識結果を返します。認識結果の出力例は以下のようになります。
{
"results": [
{
"tokens": [
{
"written": "音声認識",
"confidence": 1,
"starttime": 300,
"endtime": 1480,
"spoken": "おんせーにんしき"
},
{
"written": "は",
"confidence": 1,
"starttime": 1480,
"endtime": 1660,
"spoken": "わ"
},
{
"written": "AmiVoice",
"confidence": 1,
"starttime": 1660,
"endtime": 2380,
"spoken": "あみぼいす"
}
],
"confidence": 1,
"starttime": 0,
"endtime": 2640,
"tags": [],
"rulename": "sample",
"text": "音声認識はAmiVoice"
}
],
"utteranceid": "20240111/15/018cf74837d50a30105894c4_20240111_154914",
"text": "音声認識はAmiVoice",
"code": "",
"message": ""
}
こちらにもあるように、「単語単位の結果」「発話区間の結果」「全体の結果」に分かれています。また、ルールの記述通りに単語が区切られて出力されていることがわかります。
なお、上記のようにルールを記述した場合、「あみぼいす」だけ発話しても何も出力されません(「AmiVoice」だけの認識結果は返ってきません)。ルールグラマの大原則は「1発話が1つのpublicルールに合致すると認識結果が返される」であり、上記のルールは「音声認識 は Amivoice」という単語列全体で1つの「publicルール」になるからです。
また、単語のあいだを半角スペースで区切るのは、半角スペースで区切るとそこで多少の間(ま)が認められるためです。仮に、
public <sample> = 音声認識はAmiVoice\おんせーにんしきわ.あみぼいす;
のように、「音声認識はAmiVoice」で1単語となるルールグラマを作ったとすると、「おんせーにんしきわあみぼいす」を一息で言わないと認識されにくくなります。単語のあいだを区切っておけば、「おんせーにんしきわ、あみぼいす」のように発話しても正しく認識してもらいやすくなります。
また、サンプルでは「音声認識」で1単語としています。出力は「音声認識」で1単語としたいが、「音声」と「認識」のあいだに間(ま)を空けてもよいようにしたい場合は、
public <sample> = 音声認識\おんせー_にんしき は\わ AmiVoice\あみぼいす;
のように、読みに“_”(半角アンダースコア)を入れてください。(「基本編」では、読みに使える文字はひらがな・カタカナ・”ー”(長音文字)・”.”(半角ピリオド)のみと説明しましたが、”_”も使えます)
並列
「はい」と「いいえ」などのように複数の単語を並列して認識したい場合は、以下の2通りの書き方があります。
パターン①:”|”(半角バーティカルバー)でつなぐ
public <answer> = (はい | いいえ);
並列したい単語同士を”|”でつなぎます。この場合、「はい」と発話すれば「はい」を、「いいえ」と発話すれば「いいえ」を認識結果として返します。3個以上の単語を並列する場合も同様です。単語列を並列することも可能です。
どの単語(列)を並列するかがわかるよう、半角カッコで囲んでください。カッコを忘れると、意図した通りの認識結果を得られない場合があります。
パターン②:publicルールを複数記述する
public <yes> = はい;
public <no> = いいえ;
先ほどの説明で、ルールグラマの大原則は「1発話が1つのpublicルールに合致すると認識結果が返される」と書きました。publicルールは複数書くことが可能で、いずれかのpublicルールに合致すれば認識結果を返します。
①の方が1行で書けますが、並列の数が多くなるとルールが見にくくなるかもしれません。ルールの見やすさや管理のしやすさなどを考慮して使い分けてください。
直列と並列の組み合わせ
直列と並列を組み合わせた例を以下に示します。どのような発話を認識できるか考えてみてください。
public <name> = (田中\たなか | 鈴木\すずき) さん;
これは「田中」と「鈴木」の並列と、「田中 or 鈴木」と「さん」の直列を組み合わせたものです。したがって、「田中 さん」と「鈴木 さん」の2つの発話を認識できます。
上記の例で注意してほしいのが並列のカッコです。以下のようにカッコを書き忘れてしまうと、発話が意図した通りに認識できません。
public <name> = 田中\たなか | 鈴木\すずき さん;
このように書いてしまうと、「田中」と「鈴木 さん」の並列認識とみなされてしまい、「田中 さん」と発話しても認識結果が出力されません。並列のカッコの書き忘れに注意してください。
省略可能
先ほどの例は「田中 さん」と「鈴木 さん」の2つの発話を認識できました。ここで、「田中 さん」「鈴木 さん」だけでなく、「さん」のない「田中」「鈴木」だけでも認識させたい場合、以下のように書くことができます。
public <name> = (田中\たなか | 鈴木\すずき) [さん];
単語(列)を“[ ]”(半角ブラケット)で囲むと、その単語(列)が省略されても認識されます。
この記事の最初に示した「音声認識 は AmiVoice」という単語列を認識するルールグラマでは、「あみぼいす」だけ発話しても何も出力されない、という説明をしました。この「省略可能」の書き方を使うと、「音声認識 は AmiVoice」と「AmiVoice」の両方を認識できるルールグラマを以下のように書くことができます。
public <sample> = [音声認識\おんせーにんしき は\わ] AmiVoice\あみぼいす;
当然ですが、”[ ]”を書き忘れたり、誤って”( )”で囲ったりしても省略可能にはならないので、書き忘れや囲う部分の誤りには注意してください。
おわりに
本記事では、実践的なルールグラマの書き方を解説しました。もう1本、さらに発展的なルールグラマの書き方を解説する記事で「ルールグラマ」シリーズは完結の予定です。
ルールグラマはAmiVoice API Private・SDKで提供されている機能ですが、より手軽にAmiVoice APIの音声認識を試してみたい開発者の方がいましたら、ぜひ https://acp.amivoice.com/ を試してみてください。毎月音声60分までは全エンジン無料で使えます。
ここまでお読みいただき、ありがとうございました!
この記事を書いた人
-
大倉尭
新卒でアドバンスト・メディアに入社。
音声認識の精度向上のための研究開発に携わった経験から、このブログをはじめ、アドバンスト・メディアの技術力をアピールする仕事に挑戦中。
趣味は旅行(主に鉄道)・読書(主に小説)・ボードゲームなど。