音声処理におけるオープンソース標準への移行

Python を使用して語彙目録のフラット・ファイルを XML に変換する

多くのオープンソース・プロジェクトは FOSS (Free and Open Source Software) 標準が登場する前に開始されたものであるため、これらのプロジェクトの構成ファイルやリソース・ファイルは単純なフラット・テキスト・ファイルです。これらのファイルを関連するオープンソース標準に対応した形式に変換することで、プロジェクト間での互換性、柔軟性、信頼性を高められる可能性があります。その好例が音声認識における語彙目録です。この記事では Python を使用して、既存の語彙目録のフラット・ファイルを PLS (Pronunciation Lexicon Specification) で定義される XML フォーマットに変換し、その新しい PLS ファイルを再度フラット・ファイルに戻す方法について説明します。さらに、XML フォーマットを使用して語彙目録に情報を追加する方法や、語彙目録の保守を厳密に行う方法についても詳しく説明します。また、Unicode などの問題や、音響モデルの生成にデータを使用しつつ新しい語彙目録を他の XML ファイルとマージする方法についても取り上げます。

Colin Beckingham, Writer and Researcher, Freelance

Colin Beckingham はカナダのオンタリオ州東部に住むフリーランスの研究者であり、ライターであり、プログラマーでもあります。キングストンの Queen's University で学位を取得している彼は、園芸、競馬、教育、行政サービス、小売業、旅行/観光業などにも関わってきました。彼はデータベース・アプリケーションの作成者であり、数え切れないほどの新聞記事や雑誌記事、オンライン記事を執筆しており、また Linux でのオープンソース・プログラミングや VoIP、音声制御アプリケーションも研究しています。



2012年 9月 13日

はじめに

十分に確立された多くのソフトウェア・プロジェクトでは、何年かは大きな問題もなく構成ファイルやリソース・ファイルにフラット・テキスト・ファイルを使用してきました。しかしプロジェクトの規模が大きくなり、複雑になるにつれ、厳密さと適応性を高める必要が出てきます。XML を使用するとともに、明確な標準に従った XML のアプリケーションを使用することで、異なるプロジェクト間や異なるプラットフォーム間での (Unicode などの領域における) 互換性、堅牢性、拡張性に関するメリットを得られる可能性があります。

頻繁に使用される略語

  • HTK: Hidden Markov Model Toolkit
  • PLS: Pronunciation Lexicon Specification
  • XML: eXtensilble Markup Language

フラット・テキスト・ファイルを関連するオープンソース標準に対応した形式に変換することで、柔軟性と信頼性も高めることができます。この記事ではその好例として、音声認識における語彙目録を取り上げます。皆さんのオープンソース・プロジェクトでリソース・ファイルを XML に移行するかどうかにかかわらず、機能を失うことなく XML 標準を採用することができます。

この記事では、語彙目録のフォーマットをフラット・ファイル・フォーマットと PLS (Pronunciation Lexicon Specification) フォーマットとの間で容易に移行する方法について説明します。サンプルを示しながら、カスタマイズした語彙目録を PLS フォーマットで要求されるフラット・ファイルに保存し、そこからデータを抽出する方法について説明します。


語彙目録のサンプル

語彙目録は音声認識ツールで使用される単語リストです。語彙目録には、単語が視覚的にどのように出力されなければならないか (つまりどのようなグラフィックとして描画されなければならないか) についての情報と、音素を使用してどのような音声として出力されるのかについての情報が含まれます。HTK (Hidden Markov Model Toolkit: 隠れマルコフ・モデル・ツールキット) で通常使用される語彙目録は、さまざまな音声制御プロジェクトで広く使用されています (「参考文献」を参照)。リスト 1 は VoxForge の HTK 語彙目録から抜粋したものです。

リスト 1. VoxForge の HTK 語彙目録からの抜粋
AGENCY  [AGENCY]        ey jh ih n s iy
AGENDA  [AGENDA]        ax jh eh n d ax
AGENT   [AGENT] ey jh ih n t
AGENTS  [AGENTS]        ey jh ih n t s
AGER    [AGER]  ey g er
AGES    [AGES]  ey jh ih z

この記事のコードをコピー・アンド・ペーストする場合にはタブを 1 つ追加してください

語彙目録を取得する場合は、ソースから直接取得することをお勧めします。この記事は HTML で表示されるため、タブ区切りが空白で置き換えられています。この記事からコピー・アンド・ペーストする場合には、間にある複数の空白を 1 つのタブ区切り (\t) で置き換える必要があり、そうしないとスクリプトが動作しません。

リスト 1 のファイルはタブで区切られた以下の 3 つのフィールドで構成されています。

  • その単語のことを一般的に表現するときのラベル
  • その単語の視覚的な出力 (つまり画面での表示) を角括弧で囲ったもの (書記素)
  • Arpabet (「参考文献」を参照) の音素を 1 つの空白で区切って並べたシーケンスで、その単語がどのような音声として出力されるのか表したもの

上記の例では、発音は英語の発音であるため、音素は ASCII (American Standard Code for Information Interchange) 文字で難なく網羅されています。

CMU Sphinx プロジェクト (「参考文献」を参照) も同じような方法で語彙目録 (CMU Sphinx の用語では辞書) を格納します。リスト 2 はその抜粋です。

リスト 2. CMU Sphinx の語彙目録からの抜粋
agency  EY JH AH N S IY
agenda  AH JH EH N D AH
agendas AH JH EH N D AH Z
agent   EY JH AH N T
agents  EY JH AH N T S
ager    EY JH ER

リスト 2 には 2 つのフィールドしかなく、単語または書記素と、それを音素で表したもののみで構成されています。この 2 つの語彙目録のサンプルには以下のように微妙な違いがあります。

  • 単語と音素は、一方が小文字で、他方は大文字です。
  • 音素にわずかな違いがあります。
  • 句読点 (コンマ、感嘆符など) の扱い方が少し異なります。

この辞書の全体を調べるには、PocketSphinx の最新のダウンロードに含まれる cmu07a.dic ファイルを参照してください (「参考文献」を参照)。

語彙目録は単語の具体的な発音を記述するものであるため、特定の人々または方言に合わせてファイルを編集する必要があるかもしれません。すると時間の経過と共に、カスタマイズした独自の語彙目録として知識資本が構築されます。フラット・ファイルはテキスト・エディターで容易に編集できますが、間違いも起こしやすくなります (そのファイルにとって標準的な区切りとは異なる区切りを使ってしまう、非 ASCII 文字を挿入してしまう、フィールドの順序を誤る、レコードのソート方法を誤る、必要な場所に大括弧を入れ忘れる、など)。

フラット・ファイルには、小さな欠点がもう 1 つあります。カスタマイズしたファイルを作成すると、他の音声関連プロジェクトとの互換性がなくなります。PLS のように標準的な XML フォーマットの語彙目録を両方のプロジェクトで認識することができれば、その語彙目録を即座に両方のプロジェクトで共有することができます。


PLS (Pronunciation Lexicon Specification)

PLS には単純な基本フォーマットがあります (リスト 3)。

リスト 3. PLS の基本フォーマット
<?xml version="1.0" encoding="UTF-8"?>
<lexicon version="1.0" 
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon 
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
      alphabet="ipa" xml:lang="en-US">
  <lexeme ...>
    <grapheme>...</grapheme>
    <phoneme ...>...</phoneme>
  </lexeme>
</lexicon>

この XML には、複数の lexeme 子要素を含めることができるルート要素 lexicon が記述されています。各 lexeme には複数の grapheme 要素と複数の phoneme 要素を含めることができます。PLS の仕様では、発音文字体系を示す alphabet 属性を無効にすることはできますが、xml:lang 言語属性を無効にすることはできません。従って、異なる言語の語彙素を格納するには、必ず別の PLS 語彙目録ファイルが必要になります。この語彙目録のデフォルトの発音文字体系は ipa です。ipa は音声を表現するための IPA (International Phonetic Alphabet: 国際音声記号) 系を指します (「参考文献」を参照)。IPA で表現した音素はマルチバイトの Unicode 文字である一方で、HTK も Sphinx もプレーン ASCII コードを使用しています。こうしたことに関して考慮すべき重要な事項については、記事の後の方で説明します。

PLS 仕様を使用することによるメリットは、より厳密な構造を追加することができ、より多くの情報を格納できることです (品詞や具体的な発音文字体系など)。品詞の詳細は、英語では重要です。英語の場合、同じ綴りの単語 (同形異義語) でも、その単語の文法上の役割によって発音が異なるからです。例えば、形容詞としての perfect の発音は動詞としての perfect の発音とは異なります。これは強勢の場所が異なるからです。このように属性に格納された追加情報を利用することで、必要に応じてファイル全体の中から特定のレコードを抽出することができます。この方法を使用すると、いくつもの phoneme 要素の中から特定のアルファベットを検索することができます。

PLS 語彙目録は、使用される音声ツールと関係する詳細を抽出できる語彙目録情報のデータベースと考えることができます。リスト 4 は PLS フォーマットの例です。

リスト 4. 1 つの単語を PLS フォーマットで記述した例
<?xml version="1.0" encoding="UTF-8"?>
<lexicon version="1.0" 
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon 
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
      alphabet="ipa" xml:lang="en">
  <lexeme role="noun">
    <grapheme>agency</grapheme>
    <phoneme alphabet="x-htk-voxforge">ey jh ih n s iy</phoneme>
    <phoneme alphabet="x-cmusphinx">EY JH AH N S IY</phoneme>
  </lexeme>
</lexicon>

リスト 4 の例は 2 つの音素表現を持つ可能性のある1 つの単語のみを格納しています。alphabet 属性を指定すると、複数の phoneme 文字列のうちの 1 つを抽出することができます。lexeme 要素は nounrole 属性を示します。この情報は有益ですが、この単語は名詞として使用されるのみであり、複雑な発音のシナリオはないため、この場合には冗長な情報です。

2 つの異なるソースの phoneme 表現を並べて配置することで、微妙な違いをすぐに判別することができます。この情報が音声認識の問題を解決するために役立つ場合があります。

CMU Sphinx や HTK では、PLS 語彙目録を直接使用することはできませんが、HTK ツールキットの simon (「参考文献」を参照) フロントエンドでは PLS 語彙目録を直接使用することができます。単純に HTK または Sphinx を使用している場合には、情報を失うことなく容易にプレーン・テキストから PLS への変換とその逆変換を行えることが確実でなければなりません。

以下のセクションでは、Python を使用してフラット・ファイルから PLS へ変換する方法、そして逆に PLS からフラット・ファイルに戻す方法について説明します。ここでは、カスタマイズされた情報が語彙目録のフラット・ファイルに格納されているものとします。


PLS に変換する

リスト 5 のコードは Python を使用していますが、これと同じことをする方法は他にもたくさんあります (一例として、「参考文献」に挙げた XSLT (Extensible Stylesheet Language Transformations) に関する developerWorks のチュートリアルを参照してください)。ソース・ファイルが大規模で誤りや不整合を含みがちな場合はなおのこと、どこに問題があるのかについての情報が即座に得られるように、細かなステップごとに XML の堅牢性をチェックするライブラリーを使用したいと考える人もいます。以下の例では XML のチェックを最後のステップで行っており、これはフラット・ファイルが適切な構造であることをある程度確信していることの現れです。

リスト 5. PLS に変換する
from elementtree.ElementTree import parse
import string as str
import sys
import cgi
#
# call with 
#	python flat2pls.py vox
# or 
#	python flat2pls.py spx
#
if len(sys.argv) == 2:
  src = sys.argv[1]
else:
  exit("wrong args")
#
outfile = "mylex"+src+".pls"
print "out is "+outfile
out = open(outfile,"w")
out.write('<?xml version="1.0" encoding="UTF-8"?>\n\
<lexicon version="1.0"\n \
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"\n\
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n \
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon\n \
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"\n\
      alphabet="ipa" xml:lang="en">')
# now the lexemes
if src == "vox":
  f = open("vf.lex","r")
  for line in f:
    line = str.strip(line)
    word = str.split(line,"\t")
    #gr = str.strip(word[1],"[]")
    gr = cgi.escape(word[0])
    out.write('\n\
  <lexeme>\n\
    <grapheme>'+gr+'</grapheme>\n\
    <phoneme alphabet="x-htk-voxforge">'+word[2]+'</phoneme>\n\
  </lexeme>')
else: # src is sphinx
  f = open("cmu.dic","r")
  for line in f:
    line = str.strip(line)
    word = str.split(line,"\t")
    gr = cgi.escape(word[0])
    out.write('\n\
  <lexeme>\n\
    <grapheme>'+gr+'</grapheme>\n\
    <phoneme alphabet="x-cmusphinx">'+word[1]+'</phoneme>\n\
  </lexeme>')
# ended lexemes
out.write('\n</lexicon>\n')
out.close()
# now check the output is ok
tree = parse(outfile)
lexicon = tree.getroot()
mylexcount = 0
for lexeme in lexicon:
  mylexcount += 1
print 'Found %(number)d lexemes' % {"number":mylexcount}

リスト 5 はまず、XML 構文解析ライブラリー elementtree (「参考文献」を参照) のモジュールと、いくつかのサポート・ライブラリーをインポートしています。別のディストリビューションの ElementTree をインポートする場合には、そのモジュールをどのようにインストールするかによって少し異なる構文になるかもしれません。このサンプル・コードは openSUSE から引用したもので、ソースから ElementTree モジュールをインストールしていますが、Ubuntu の場合は「from xml.etree.ElementTree import parse」と記述する必要があるかもしれません。str モジュールを使用すると文字列を多少操作することができ、sys モジュールを使用するとファイルにアクセスすることができ、cgi モジュールを使用すると XML のデータの処理に欠かせない極めて重要なエスケープ・ルーチンが提供されます。このコードはコマンドライン・インターフェース (CLI) の引数を取得することを想定しており、その引数によって CMU Sphinx フォーマットから変換するのか HTK/VoxForge から変換するのかを指定します。このサンプル・コードは次に、出力用のファイルを開き、PLS に適した XML の先頭部分を書き込みます。この時点では Unicode 文字を格納するわけではないため、プレーン ASCII のみで書き込めるようにファイルを開けば十分です。

この時点で、リスト 5 のコードは以下の内容を実行します。

  • ソース・ファイルを 1 行ずつ処理し、フィールドを別々の文字列に分割し、lexeme コンポーネント、grapheme コンポーネント、phoneme コンポーネントを書き込みます。
  • 入力データが VoxForge の語彙目録のデータの場合には、属性 alphabet="x-htk-voxforge" が指定された phoneme を特定し、入力データが Sphinx の語彙目録のデータの場合には、属性 alphabet="x-cmusphinx" が指定された phoneme を特定します。
  • 音素の大文字/小文字の区別を保持します。

最初のフィールドがインポートされる時点では、そのフィールドにはアンパサンド (&) のように cgi.escape() によってエスケープしないと XML で問題を引き起こす文字が含まれている可能性があります。

最後に、このコードは以下のことを行います。

  • 終了タグを書き込みます。
  • PLS ファイルを閉じ、その PLS ファイルを XML ファイルとしてリロードします。
  • lexeme 要素をカウントしながら、その XML ファイルを読み取ります。
  • lexeme のカウントを出力します。

lexeme のカウントが出力されると、その XML は堅牢かつ整形式であるとみなされます。

リスト 6 は VoxForge の HTK 語彙目録から変換した結果の抜粋です。

リスト 6. VoxForge の HTK 語彙目録から変換した結果の抜粋
...
<lexeme>
  <grapheme>AGENDA</grapheme>
  <phoneme alphabet="x-htk-voxforge">ax jh eh n d ax</phoneme>
</lexeme>
<lexeme> 
  <grapheme>AGENT</grapheme>
  <phoneme alphabet="x-htk-voxforge">ey jh ih n t</phoneme>
</lexeme>
...

PLS から変換する

PLS フォーマットからフラット・ファイルへの変換も容易にできることを知っておくことは重要です。リスト 7 のコードは前提として、語彙目録が PLS フォーマットのファイルに格納されており、音声認識プロジェクトでは HTK フォーマットまたは CMU Sphinx フォーマットのフラット・ファイルのみを使用できるものとしています。

リスト 7. PLS から変換する
from elementtree.ElementTree import parse
import string as str
import sys
#
# call with 
#	python pls2flat.py x-htk-voxforge > mylexicon
# or 
#	python pls2flat.py x-cmusphinx > mylexicon.dic
#
if len(sys.argv) > 1:
  alpha = sys.argv[1]
#
if alpha == "x-htk-voxforge":
  tree = parse("mylexvox.pls")
else:
  tree = parse("mylexspx.pls")
lexicon = tree.getroot()
for lexeme in lexicon:
  for child in lexeme:
    #print child.tag
    if child.tag[-8:] == 'grapheme':
      if alpha == 'x-htk-voxforge':
	gr = str.upper(child.text)
	print gr,"\t","["+gr+"]","\t",
      else:
	gr = child.text
	print gr,"\t",
    if child.tag[-7:] == 'phoneme':
      if child.get('alphabet') == alpha:
	print child.text

この簡単なスクリプトでは、elementtree ライブラリーを使用して PLS XML ファイルを構文解析し、ルート要素を特定し、そのルートの子の語彙目録に繰り返し処理を行って graphemephoneme を検索し、それらの値を適切なフォーマットでテキスト・ファイルに書き込みます。スクリプトでは、名前空間接頭辞がタグによって返されるため、タグの中の最後の 8 文字が grapheme であるかどうかを調べ、grapheme の場合はあらためて HTK 用に 3 つのフィールドのフォーマットを作成するか、CMU Sphinx 用に 2 つのフィールドのフォーマットを作成します。


Unicode を使用したマージと処理

リスト 8 のスクリプトは 2 つの PLS ファイルを使用し、両方の元ファイルの情報を含む 1 つの共通 PLS ファイルを作成しています。また、VoxForge の phoneme 文字列を Unicode に変換し、alphabet="ipa" attribute 属性で識別される別の phoneme 要素の中に、その Unicode 版を格納しています。

リスト 8. マージと Unicode
#! /usr/bin/python -u
# -*- coding: utf-8 -*-
#
# challenge is to merge two pls files
# given two pls files, merge them into one
# 
import elementtree.ElementTree as ET
from elementtree.ElementTree import parse
import string as str
import codecs
import cgi
#
treevox = ET.parse("mylexvox.pls")
treespx = ET.parse("mylexspx.pls")
#
lexvox = treevox.getroot()
lexspx = treespx.getroot()
#
phons = { 'aa':u'ɑ','ae':u'æ','ah':u'ʌ','ao':u'ɔ','ar':u'ɛr','aw':u'aʊ',
'ax':u'ə','ay':u'aɪ','b':u'b','ch':u'tʃ','d':u'd','dh':u'ð','eh':u'ɛ',
'el':u'ɔl','en':u'ɑn','er':u'ər','ey':u'eɪ','f':u'f',
'g':u'ɡ','hh':u'h','ih':u'ɪ','ir':u'ɪr','iy':u'i','jh':u'dʒ','k':u'k','l':u'l',
'm':u'm','n':u'n','ng':u'ŋ','ow':u'oʊ','oy':u'ɔɪ','p':u'p','r':u'r','s':u's',
'sh':u'ʃ','t':u't','th':u'θ','uh':u'ʊ','ur':u'ʊr','uw':u'u','v':u'v',
'w':u'w','y':u'j','z':u'z','zh':u'ʒ','sil':'' }
#
def to_utf(s):
  myp = str.split(s)
  myipa = []
  for p in myp:
    myipa.append(phons[p])
  return str.join(myipa,'')
#
outfile = "my2lexmrg.pls"
out = codecs.open(outfile, encoding='utf-8', mode='w')
#
out.write('<?xml version="1.0" encoding="UTF-8"?>\n\
<lexicon version="1.0"\n \
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"\n\
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n \
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon\n \
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"\n\
      alphabet="ipa" xml:lang="en">')
#
# scan the two pls, create dictionary
voxdict = {}
for lexeme in lexvox:
  gr = str.lower(lexeme[0].text)
  ph = lexeme[1].text
  voxdict[gr] = {ph,}
#
for lexeme in lexspx:
  gr = lexeme[0].text
  ph = lexeme[1].text
  if gr in voxdict:
    voxdict[gr].add(ph)
  else:
    voxdict[gr] = {ph,}
#
for gr in sorted(voxdict.iterkeys()):
  out.write('\n\
  <lexeme>\n\
    <grapheme>'+cgi.escape(gr)+'</grapheme>')
  #print "%s: %s" % (key, voxdict[key])
  for ph in sorted(voxdict[gr]):
    alph = 'x-htk-voxforge' if ph.islower() else 'x-cmusphinx'
    out.write('\n\
    <phoneme alphabet="'+alph+'">'+ph+'</phoneme>')
    if ph.islower():
      phipa = to_utf(ph)
      out.write(u'\n\
    <phoneme alphabet="ipa">'+phipa+'</phoneme>')
  out.write('\n\
  </lexeme>')
# done, close files
out.write('\n</lexicon>')
out.close()
# now check the output is ok
tree = parse(outfile)
lexicon = tree.getroot()
mylexcount = 0
for lexeme in lexicon:
  mylexcount += 1
print 'Found %(number)d lexemes' % {"number":mylexcount}

このスクリプトは、まずシバン (#!) 式で始まり、2 行目では Python インタープリターに対する特殊なインジケーターによって、このコードが Unicode 文字を含むことを示しています。続いて、elementtreecodecscgi など、Unicode を扱う場合に便利なモジュールをインポートしています。そして Python インタープリターに対して 2 つの PLS ファイルの場所と、それらのファイルのルート要素を指定しています。

phons 変数には、CMU Arpabet のコードから等価な Unicode の組み合わせへのマッピングを含む特殊な辞書を格納します。この辞書によって既存の phoneme 文字列を Unicode に変換します。このマッピングは、目的に合わせて自由に変更することができます。例えば、皆さんは CMU Arpabet における ‘aa’ に相当するものを Unicode で表現する場合、a の音を伸ばす u'ɑ:' の方が適切と思うかもしれません。

このスクリプトで定義されている唯一の関数 to_utf() は、ASCII Arpabet の文字列を Unicode に変換します。この基本となるコードの最後の部分では、出力を格納するためのファイルが Unicode を確実に受け付けられるように指定して、このファイルを開きます。そして、開いたファイルに PLS の先頭部分を書き込みます。

これで、ファイルを処理する準備が整いました。ファイルを処理するには 2 つの特殊な内部用 Python 辞書を作成 (そのうち 1 つは elementtree ライブラリーを使用して各 PLS ファイルをスキャンすることで作成) します。ここでは、語彙素の最初の子が grapheme であり、2 番目の子が phoneme であることを前提としています。このスクリプトは最初のファイルのレコードをすべて、新たに作成するマージ辞書に追加しています。2 番目のファイルをスキャンする際、新たに作成したマージ辞書に既にキーが存在する場合には、そのキーの音素セットに追加します。キーが存在しない場合には、そのマージ辞書に新しいキー項目を作成します。ループの最後に達すると、新たに作成したマージ辞書には、両方の元ファイルのキーと、それに関連付けられた 1 つまたは 2 つの phoneme 文字列の集合が含まれるようになります。

今作成したマージ辞書から、新しい PLS ファイルを書き出します。この辞書をスキャンしながら、phoneme 同士を区別するための alphabet 属性を追加します。既存の音素の書き出しを終えたら、CMU Arpabet 文字列に相当する新しい phoneme 文字列を Unicode で作成します。CMU Arpabet 文字列については必要に応じて、HTK のファイルまたは Sphinx のファイル (あるいはその両方) から取得することができます。

最後に、ルート要素を閉じ、ファイルを閉じ、先ほどと同じように再度ファイルを構文解析して整形式性を確認します。

その結果はリスト 9 のようになるはずです。

リスト 9. 辞書をマージした結果
...
  <lexeme>
    <grapheme>agenda</grapheme>
    <phoneme alphabet="x-cmusphinx">AH JH EH N D AH</phoneme>
    <phoneme alphabet="x-htk-voxforge">ax jh eh n d ax</phoneme>
    <phoneme alphabet="ipa">ədʒɛndə</phoneme>
  </lexeme>
  <lexeme> 
    <grapheme>agendas</grapheme>
    <phoneme alphabet="x-cmusphinx">AH JH EH N D AH Z</phoneme>
  </lexeme>
  <lexeme> 
    <grapheme>agent</grapheme>
    <phoneme alphabet="x-cmusphinx">EY JH AH N T</phoneme>
    <phoneme alphabet="x-htk-voxforge">ey jh ih n t</phoneme> 
    <phoneme alphabet="ipa">eɪdʒɪnt</phoneme>
  </lexeme>
  <lexeme>
    <grapheme>agent's</grapheme>
    <phoneme alphabet="x-cmusphinx">EY JH AH N T S</phoneme>
  </lexeme>
...

マージされた PLS 辞書があれば、XSL (Extensible Stylesheet Language) を適用するか、その他の任意の処理を適用することにより、必要とされる結果を (それがフラット・ファイルであろうが、新しい固有の PLS ファイルであろうが) 生成することができます。このファイルには理論的には、他の phoneme 文字列 (他の言語からの phoneme 文字列であっても) も格納することができます。ただし、その使い方は PLS 仕様の標準的な使い方ではありません。

これまで Kai Schott 氏は PLS に関する数多くのことを行っており、ドイツ語をはじめとするさまざまな言語で、既にいくつかのファイルがダウンロードできるように準備されています (「参考文献」を参照)。


未解決の問題

フラット・ファイルから大量の情報を得ることができますが、以下の問題は解決できていません。

複数の書記素から選択する
場合によると、同じ言語で 1 つの単語に対して複数の綴りを扱わなければならないことがあります。どちらの綴りでも単語の役割と音素は同じであるため、同じ語彙素に複数の書記素が含まれます。しかし PLS には、phoneme 要素の alphabet 属性のように grapheme 要素に属性を追加できる仕組みはありません。
頭字語
語彙目録に頭字語が含まれることがよくあります。PLS は頭字語に関して、<alias> という lexeme の子要素で対応しています。フラット・ファイルから自動的に PLS を作成するためには、語彙目録の中の頭字語を実際の単語と区別する手段が必要です。その情報はフラット・ファイルには必ずしも含まれていません。
役割と品詞
頭字語の場合と同様、フラット・ファイルには role 属性を PLS に含めるための品詞情報が含まれていません。

まとめ

この記事では、フラット・ファイル・フォーマットと PLS フォーマットとの間で非常に容易にフォーマットを移行できることを学びました。語彙目録を PLS フォーマットで格納することには潜在的なメリットがあります。オープンソース・プロジェクトでは、リソース・ファイルを XML に移行する場合もありますが、移行しない場合もあります。それはプロジェクト・マネージャーの判断です。コミュニティーで一般的に受け入れられている最善の方法でリソースを評価し、適用できるのはプロジェクト・マネージャーのみです。

その一方で、皆さんの作業の中で、機能を失うことなく XML 標準を採用することができます。音声認識に使用される語彙目録と辞書の場合、カスタマイズした語彙目録を PLS フォーマットで格納すると、クロスプロジェクトの適用性、堅牢性、実用性を高めることができます。また必要に応じて、要求されるフラット・ファイルの中に容易にデータを抽出することもできます。

参考文献

学ぶために

  • W3C の 「発音辞書仕様 (PLS)」: 語彙素、書記素、音素に関して理解してください。
  • 国際音声記号 (International Phonetic Alphabet): ウィキペディアの項目を読み、この音声表記体系について、これらの体系と等価な Arpabet の体系や Unicode の体系を含めて学んでください。
  • HTK: 隠れマルコフ・モデルを作成し、操作するための移植の容易なツールキット、HTK (Hidden Markov Model Toolkit) について学んでください。
  • CMU Sphinx: カーネギーメロン大学が音声認識用に開発したオープンソースのツールキットについて学んでください。
  • ElementTree: Python のための XML ライブラリー、ElementTree についての資料を読んでください。
  • simon: この音声認識プラットフォームについて学んでください。
  • Kai Schott 氏のブログ「Testing simon」: さまざまな言語用に作成された数種類の PLS ファイルについて調べてください。
  • Analyze with XSLT, Part 1: Analyze non-XML data with XSLT」(Chuck White 著、developerWorks、2003年12月): このチュートリアルは XSLT を使用して XML を処理する方法について解説しています。
  • 著者の Colin Beckingham が developerWorks に寄稿した他の記事 (2009年3月から現在まで): XML、音声認識、XQuery、PHP、その他の技術に関する記事を読んでください。
  • New to XML には、XML を学ぶために必要なリソースが豊富に用意されています。
  • developerWorks の XML ゾーン: DTD、スキーマ、XSLT など、XML の領域でのスキルを磨くためのリソースが豊富に用意されています。XML の技術文書一覧には、広範な話題を網羅した技術記事やヒント、チュートリアル、技術標準、IBM Redbooks が豊富に用意されています。
  • IBM XML certification: XML および関連技術において IBM 認定技術者になる方法を参照してください。
  • developerWorks の Technical events and webcasts: これらのセッションで最新情報を入手してください。
  • developerWorks は Twitter を利用しています。今すぐ developerWorks のツイートをフォローしてください。
  • developerWorks podcasts: ソフトウェア開発者のための興味深いインタビューや議論を聞いてください。
  • developerWorks on-demand demos: 初心者のための製品インストール方法やセットアップのデモから、上級開発者のための高度な機能に至るまで、多様な話題が解説されています。

製品や技術を入手するために

  • VoxForge: 音響モデルを作成し、また音声認識モデルの作成方法を学んでください。
  • CMU Sphinx: この音声認識ツールキットを入手してください。
  • Python: ダウンロード・リンクを含め、このプログラミング言語に関する情報を入手してください。
  • IBM 製品の評価版: IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Open source
ArticleID=834264
ArticleTitle=音声処理におけるオープンソース標準への移行
publish-date=09132012