目次


電話番号や頭字語など、口述された言葉を対象にした自動音声会話アノテーションを作成する

Sphinx-4、カスタム辞書、そしてテキスト処理ツールを使って会話から関連データを抽出する

Comments

カーネギー・メロン (Carnegie Mellon) 大学の Sphinx プロジェクトでは、開発者およびユーザーを対象としたオープン・ソースの音声認識ツールを作成しています。この記事では Sphinx-4 のコード・ベースを使用し、一般的な文字と数字で構成された非常に小さな辞書の自動認識を行います。認識された音声情報をテキストに変換して、そのテキスト・ストリングを例えば電話番号や頭字語などの特定のデータ構造に合わせて処理することで、音声会話を自動的に説明するアノテーションを作成することができます。

このプロジェクトを実装すると特に役立つ分野の 1 つとして、電話会議アノテーションのアプリケーションが挙げられます。開発会議に次回参加するときに、この会話アノテーターを作動させてみてください。そうすれば、会議で口にされた電話番号から該当する個人を自動的に検索したり、頭字語がどの曜日を指すのかを Web 検索エンジンに照らし合わせたりして確認できることがわかります。話に出てきた最新の頭字語や従業員認識番号の関連情報を調べるために作業を中断してそれらのデータを入力する必要はありません。このような雑務の大部分は、Sphinx-4 とこの記事で作成する会話アノテーターが代わりに引き受けてくれます。

必要条件

ハードウェア

Sphinx は大量のリソースを消費することから、このソフトウェアを有効に活用するには処理速度の優れたハードウェアが必要となります。有効なパフォーマンスにはかなりの専用メモリーを要するため、Sphinx アプリケーションを実行するマシンとしては少なくとも 1 GB の RAM を搭載した Intel® Pentium® 4 クラスを予定してください。一方、テキストを処理するハードウェアの要件は取るに足らないものなので、同じマシンで実行しても音声認識処理のパフォーマンスに影響することはありません。

ソフトウェア

この記事で作成するアプリケーションは、Linux® または Microsoft® Windows® が動作するハードウェアで実行することができます。Sphinx-4 は最近の JDK と Apache Ant を利用してカスタム文法プロセッサーを作成します。また、Perl および関連する任意の検索モジュールも必要です。以上のソフトウェア・パッケージの詳細とダウンロード情報については、「参考文献」セクションのリンクを参照してください。

Sphinx-4 のインストール手順

Sphinx は音声認識のタイプと機能によって、さまざまな形式で提供されます。この記事で使用するのは、最近のリリースのなかでもっともユーザーと開発者に使いやすい Sphinx-4 パッケージです。Sphinx-4 のインストールは気後れするような作業になりかねないので、インストール・ガイドから抜粋した以下のステップに従ってください。

  1. Apache Ant をダウンロードして解凍します。
  2. Sun JDK をダウンロードして解凍します (この記事を書いている時点では、V1.6.0_02 が最新リリースのようです)。
  3. Sphinx-4 ソース・パッケージをダウンロードして解凍します。このパッケージに含まれるデモ・プログラムの 1 つを記事の目的に合わせて変更することになります。
  4. 以下のコマンドで環境変数を設定します。
    export ANT_HOME=${PWD}/apache-ant-1.7.0
    export JAVA_HOME=${PWD}/jdk1.6.0_02
    export PATH=${PATH}:${ANT_HOME}/bin

    Windows の場合には、コントロール パネル > システム > 詳細設定 > 環境変数に進んで環境変数を設定します。
  5. sphinx4-beta ディレクトリーに移り、次に lib サブディレクトリーに移ります。
  6. jsapi.sh シェル・スクリプトを実行して JSAPI バイナリー・ライセンスを有効にします。Sphinx-4 はバイナリー・ランセンスで JSAPI のサポートを提供するため、使用条件に同意する必要があります。
  7. uudecode をインストールして JSAPI に必要なコンポーネントを解凍するよう求められる場合があります。たいていの Linux ディストリビューションには何らかの形で uudecode が含まれているパッケージがあるため、まずは使用可能なパッケージを調べて uudecode のインストールが必要かどうかを判断してください。Windows の場合は、jsapi.exe ファイルをダブルクリックして使用許諾条件に同意します。
  8. Sphinx4 のメイン・ディレクトリーに戻ります。
  9. コマンド ant を実行します。これによって、ビルド・プロセスが開始します。

「BUILD SUCCESSFUL」というステータス・メッセージが表示されれば環境が正しく設定されたことになるので、変更ステップに進んでください。これ以外のメッセージを受け取った場合は、ビルド・ディレクトリーと環境変数を確認するか、または Apache Ant および Sphinx-4 の資料でお使いの環境に応じた詳しいインストール手順を調べてください。

不特定話者の音声から文字と数字を抽出するための方策

音声認識は通常、不特定話者の音声で豊富な語彙を認識するには 2 年から 10 年かかる技術だと見なされています。複数の話者が出席し、しかも音声が重なったり、世界各地のアクセントや広範な技術用語、口語表現も伴う会議でのアノテーション処理は、市場に出回っている消費者レベルのソフトウェアには不可能と言っていいでしょう。そこで Sphinx、具体的には Sphinx-4 パッケージでは、不特定話者というコンテキストでごく限られた (ただし実用的な) 語彙を確実に認識するために必要なすべてのオプションを提供しています。

この記事では限られた語彙として A から Z の文字、そして 0 から 9 の数字を指定しました。私たちの方策は、これらの文字または数字が声に出されたすべての場所を単に抽出することです。この手法は一般的に単語スポッティングと呼ばれますが、現在 Sphinx-4 では単語スポッティングをサポートしていません。それでもなお、発言されたすべての言葉を文法に含まれるいずれかの単語に強制的に一致させるという方法で同じく有益な結果を得ることができます。一致候補として有力な文字と数字のリストを取得しさえすれば、あとは標準的なテキスト処理ツールと情報の検索を適用して有益な情報を抽出することができます。

辞書のカスタマイズと Hello World サンプルの変更

辞書ファイルの作成

疑似的な単語スポッティング用のセットアップを作成する最初のステップは、必要な辞書ファイルを作成することです。Sphinx-4 のディレクトリー・ツリーには、bld/models/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/dict/ という名前のディレクトリーがあり、ここには 2 つの辞書ファイル、alpha.dict と digit.dict が含まれています。一見すると、この 2 つの辞書ファイルを組み合わせれば目的のファイルになるように思えますが、そういうわけにはいきません。私たちの辞書ファイルは、同じディレクトリーにある cmudict.0.6d ファイルから作成する必要があります。

必要な辞書ファイルを作成するには、bld/models/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/dict/ ディレクトリーに移動し、以下のコマンドを実行します。

perl -ne 'print if( /^[A-Z]\ / )'                       cmudict* >  alN.dict
perl -ne 'print if(/^(ZERO|ONE|TWO|THREE|FOUR)[ (]/)'   cmudict* >> alN.dict
perl -ne 'print if(/^(FIVE|SIX|SEVEN|EIGHT|NINE)[ (]/)' cmudict* >> alN.dict

リスト 1 に、単純な文字と数字で作成された alN.dict ファイルを示します。これが、辞書を構成する唯一のファイルです。

リスト 1. alN.dict 辞書ファイルからの抜粋
...
W                    D AH B AH L Y UW
X                    EH K S
Y                    W AY
Z                    Z IY
FOUR                 F AO R
ONE                  HH W AH N
ONE(2)               W AH N
THREE                TH R IY
...

Hello World サンプルの変更

Sphinx-4 には、音声認識の分野でのほとんどすべてのニーズに対応する数多くの構成オプションが用意されています。この記事のサンプル・アプリケーションにもっとも効率的な方法は、既存の Hello World サンプルを変更することなので、Sphinx-4 のルート・ディレクトリー下にある demo/sphinx/helloworld ディレクトリーの helloworld.config.xml ファイルを編集します。リスト 2 に示す 1 行を変更して、さきほど作成した alN.dict 辞書ファイルが使用されるようにしてください。

リスト 2. helloworld.config.xml の変更
original (line 114):
        <property name="dictionaryPath"
   value="resource:/edu.cmu.sphinx.model.acoustic.WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.
Model!/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13d
Cep_16k_40mel_130Hz_6800Hz/dict/cmudict.0.6d"/>

new:
        <property name="dictionaryPath"
   value="resource:/edu.cmu.sphinx.model.acoustic.WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.
Model!/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13d
Cep_16k_40mel_130Hz_6800Hz/dict/alN.dict"/>

同じディレクトリーにある hello.gram 文法ファイルにも変更が必要です。リスト 3 のように変更して、辞書ファイルに含まれる文字と数字だけが選択されるようにします。

リスト 3. hello.gram の変更
original:
public <greet> = (Good morning | Hello) 
( Bhiksha | Evandro | Paul | Philip | Rita | Will );

new:
public <greet> = ( zero | one | two | three | four | five | six |seven | eight | nine | 
a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | 
w | x | y | z) * ;

さらに、HelloWorld.java ファイルには以下のような表示上の変更を加えます。

リスト 4. HelloWorld.java の変更
original (line 59):
    System.out.println
        ("Say: (Good morning | Hello) " +
                     "( Bhiksha | Evandro | Paul | Philip | Rita | Will )");

new:
    System.out.println
        ("Listening for letters and numbers");

以上の変更がすべて完了したら、変更後のサンプルをビルドして実行します。それには Sphinx-4 のホーム・ディレクトリーからコマンド ant を実行してください (この場合も「BUILD SUCCESSFUL」メッセージによって、変更が正しく行われたことが通知されます)。更新されたサンプルを実行するには、コマンド $JAVA_HOME/bin/java -mx312m -jar bin/HelloWorld.jar を使用します (Linux の場合)。Windows の場合に使用するコマンドは、java -mx312m -jar bin/HelloWorld.jar です。サンプルを実行して、このセンテンスを声に出して読んでください。「The phone number for IBM tech support is one eight zero zero four two six seven three seven eight」。以下のような出力が表示されるはずです。

f o nine r four i b m x a four t one eight zero zero four two six seven three seven eight

テキストの処理

ご覧のように、口述されたセンテンスは似たような文字と数字に処理されます。「IBM」という文字と電話番号の数字は正しく認識されましたが、他の単語については特定の音にもっとも近いさまざまな文字や数字に誤って分類されています。

これらの誤った一致候補を認識するには、数千語からなる辞書を使えば済む話だと思っている読者もいることでしょう。実のところ、Sphinx-4 には豊富な語彙が収録された辞書と言語モデルが用意されています。それなのになぜ、残りの「The phone number for tech support is」の部分や、発声される可能性のある他の単語を認識するようにデモ用のサンプルを構成しないのかおわかりですか?

その答えは、Sphinx-4 は優れているものの、完璧ではないからです。数十万もの単語を認識するように辞書ファイルを拡張すると、単純な数字と文字のマッチング効率は大幅に下がることになります。これは、Sphinx-4 の「demo」ディレクトリーにある他のプログラムを試すか、あるいは既存のサンプルを変更して大規模な辞書ファイルと拡大した文法リストを使うようにしてみればわかることです。利用可能なオープンソースのシステムで有意義なアノテーション・システムを開発する方法としては、文字と数字だけのテキストを事後処理してデータを整えるほうが、はるかに簡単です。

2 つの単純なルールを使うと、比較的簡単に出力テキストから頭字語と電話番号を抽出できるようになります。その 1 つは、3 つの連続した文字は頭字語として判断するというルール、そしてもう 1 つは 5 桁以上の数字はまとめて 1 つの電話番号として判断するというルールです。リスト 5 から 7 に、このようにして抽出と検索を実行する annotateAcrNum.pl プログラムのコンポーネントを記載します。

リスト 5. annotateAcrNum.pl のコンポーネントその 1 — メイン・プログラム・ロジック
#!/usr/bin/perl -w
# annotateAcrNum.pl - extract and lookup acronyms and numbers from speech 
#                     recognition text output
use strict;
use Yahoo::Search;
use Net::Dict;
$|=1;  # non buffered output for better user feedback

my %numHash =
("zero" => "0",
"one"   => "1",
"two"   => "2",
"three" => "3",
"four"  => "4",
"five"  => "5",
"six"   => "6",
"seven" => "7",
"eight" => "8",
"nine"  => "9" );

while( my $line = <STDIN> )
{
  print "$line" if( $line =~ /(Start|You said:)/ );

  next unless ( $line =~ /You said:/ );
  my @words = split " ", substr($line,9);  # ignore the "You said:" prefix

  my @numArr = ();
  my @letArr = ();

  foreach my $chunk ( @words )
  {
    if( length($chunk) == 1 )
    { 
      phoneNmSearch(@numArr) if( @numArr > 4 );
      @numArr = ();

      push @letArr, $chunk;

      if( @letArr > 2 )
      { 
        acronymSearch( @letArr );
        shift( @letArr );
      }

    }elsif( length($chunk) > 1 )
    { 
      push @numArr, $numHash{$chunk};
      @letArr = ();
    }#if length greater
  }#for each word

  phoneNmSearch( @numArr ) if( @numArr > 4 );
  acronymSearch( @letArr ) if( @letArr > 2 );

}#while stdin

上記のメイン・プログラム・ロジックは、前述の単純な基準と一致する文字および数字のストリングを検索し、変更後の Hello World コードが出力した音声認識テキストの行ごとに、文字だけの配列と数字だけの配列を作成します。文字の配列を検索するために使用するのは、以下に説明する acronymSearch サブルーチンです。ストリング「i b m x」から「ibm」と「bmx」の両方を検索するために、文字の配列は頭字語が検索されるたびにシフトされることに注目してください。数字の配列は、このような位置のシフトを行わない代わりに、検索可能な最大の数字を使用して Web 検索を実行します。

リスト 6. annotateAcrNum.pl のコンポーネントその 2 — acronymSearch
sub acronymSearch
{
  my $dict = Net::Dict->new('dict.org');

  my $str = @_; $str =~ s/ //g;

  my $eref = $dict->define($str);
  next if ($eref eq "" );
  foreach my $entry (@$eref)
  {   
      my ($db, $definition) = @$entry;
      next if (   !(defined($definition)) || !(defined($db))  );
      if( $db =~ /(wn|vera|gazetteer|foldoc)/ ){ print "$db: $definition\n" }
  }#for each definition

}#acronymSearch

acronymSearch サブルーチンは配慮の効いた Net::Dict モジュールを活用するので、単に辞書サーバーを指定して、使用可能なさまざまなデータベースで検索するようにクエリーを指定してください。正規表現 /(wn|vera|gazetteer|foldoc)/ は、出力を比較的簡潔な記述を提供するデータベースに制限します。dict.org で使用できる他のデータベースのほうが頭字語空間の表現に優れていると思ったら、この正規表現による制限を取り除く必要があります。

リスト 7. annotateAcrNum.pl のコンポーネントその 3 — phoneNmSearch
sub phoneNmSearch
{
  my $str = @_; $str =~ s/ //g;
  if( length($str) == 11 )
  {
    $str =~ /(\d)(\d\d\d)(\d\d\d)(\d\d\d\d)/;
    $str = "$1-$2-$3-$4\n";
  }elsif( length($str) == 10 )
  {
    $str =~ /(\d\d\d)(\d\d\d)(\d\d\d\d)/;
    $str = "$1-$2-$3\n";
  }elsif( length($str) == 7 )
  {
    $str =~ /(\d\d\d)(\d\d\d\d)/;
    $str = "$1-$2\n";
  }
  print "Results for: $str\n";

  my @results = Yahoo::Search->Results(Doc => "$str", AppId => "PhNmLookup" );
  warn $@ if $@; # report any errors
  
  my $recCount = 0;
  for my $res (@results)
  {   
      print "Title: ", $res->Title, " \n";
      print $res->Summary, "\n";
      print $res->Url, "\n";
      print "\n";
      last if( $recCount > 1 ); # print first 3 results only
      $recCount++;
  }#for each result

}#phoneNmSearch

検索エンジンによっては、数字をさらに電話番号のフォーマットにすることで検索結果の正確さを飛躍的に改善することができます。例えば、phoneNmSearch サブルーチンの最初の部分は 18004267378 を 1-800-426-7378 に、4152042 を 415-2042 に変更します。このように少し変更して電話番号のフォーマットになったものが、Jeffrey Friedl の重宝な Perl モジュール、Yahoo::Search を使った Yahoo! 検索パラメーターでクエリーとして使用されます。

早速、カスタムの Sphinx-4 音声認識プログラムと annotateAcrNum Perl プログラムを使って会話にアノテーションを付けてみてください。実行するコマンドは、$JAVA_HOME/bin/java -mx312m -jar bin/HelloWorld.jar | perl annotateAcrNum.pl です (Linux の場合)。Windows の場合は java -mx312m -jar bin/HelloWorld.jar | perl annotateAcrNum.pl を使用します。

図 1 は、Vector Linux の「端末」でのアノテーターのセットアップからの出力です。下線付きリンク・テキストを使って Web 検索結果に基づくページを起動できることに注意してください。

図 1. Vector Linux の 端末での会話アノテーターのスクリーン・ショット
CVector Linux の 端末での会話アノテーターのスクリーン・ショット
CVector Linux の 端末での会話アノテーターのスクリーン・ショット

まとめ、その他のサンプル

この記事で検索用に選んだクエリーとデータベースのタイプは、有効なアノテーションを示す一般的な例でしかありません。人によっては Web での検索に Google を使ったほうが効率的だと思う場合もあります。また、電話番号の検索を従業員の住所録にリンクすることも可能です。認識された文字と数字から、高度な規則に従ったデータを抽出する方法にも、同様のオプションを使用することができます。例えば、会話のなかで IP アドレスや従業員認識番号により重点が置かれる場合もありますが、この記事で説明した手法を使えば、ドットで区切られた IP アドレスや固有の ID を抽出して検索結果を独自のデータベースにリンクすることができます。

Sphinx-4 には音声認識の有効性を高めるオプションも豊富に用意されています。あなた自身とあなたのチームのメンバーを対象にトレーニングした独自の音響モデルを作成して精度を一層高めるのも一考です。辞書ファイルを何万もの一般的な話し言葉に拡大して、Sphinx-4 のリアルタイム音写性能をテストしてみてください。


ダウンロード可能なリソース


関連トピック

  • XML-RPC で C++ アプリケーションを Web サービス対応可能にする」を読んでください。この記事は、C++ メソッドをサービスとして公開するためのステップバイステップのガイドです。
  • オープン・ソース技術を使用して開発し、IBM の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、developerWorks Open source ゾーンを参照してください。
  • Sphinx-4 の詳細を調べてダウンロードしてください。
  • Sphinx-4 をビルドするための Apache Ant を入手してその詳細を学んでください。
  • このプロジェクトでは、SE バイナリー・エクストラクター V1.6.0_02 の JDK ファイルを使用しました。
  • アノテーション用 Perl スクリプトは、CPAN で入手できる Net::Dict および Yahoo::Search モジュールを利用します。
  • ご使用のシステムに Perl がインストールされていない場合は、Perl.org から入手してください。
  • IBM 製品の評価版をダウンロードして、DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を使ってみてください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=276288
ArticleTitle=電話番号や頭字語など、口述された言葉を対象にした自動音声会話アノテーションを作成する
publish-date=11132007