Solr を利用した 多言語検索の最適化

ベイシス・テクノロジー株式会社
〒102-0084
東京都千代田区二番町9−6
バウ・エプタ3F
TEL:03-3511-2947
FAX:03-3511-2948
[email protected]
Solr を利用した
多言語検索の最適化
再現率、適合率、精度
はじめに
現在、検索アプリケーションのユーザーは、検索エンジンが多言語間でシームレスに機能することを期待して
います。検索エンジンは、多言語にまたがる文書コーパスに対して任意の言語でクエリーを実行し、高品質の
結果を返すことができなければなりません。
このホワイトペーパーでは、検索アプリケーションのエンジニアを対象に、Apache™ Solr を多言語検索アプリ
ケーション用にカスタマイズする方法について具体的なアドバイスを段階的に示します。まず、多言語テキスト
処理の問題点およびそれらが適合率や再現率に与える影響について概観してから、問題を解決するオープ
ンソースのツールと商用ツールについて説明します。最後に、多言語検索エンジンで適合率と再現率を最大
化する拡張性の高いソリューションを実現するための 3 つの可能なアーキテクチャーの長所と短所について
論じます。
多言語検索における問題
検索エンジンの背後にある基本的なデータ構造は逆引き索引(単語から、その単語が含まれている文書へ
のマッピング)です 。そのため、検索アプリケーションの適合率と再現率は、索引時とクエリー実行時にテキ
ストに適用される自然言語処理(NLP)パイプラインの品質によって決まります。多言語検索は、NLP パイプ
ライン内のアルゴリズムがどの言語でも同じではないため、言語学的な観点からは難しいものです。(一部
の NLP サブプロセスは、ある種の言語では大きく異なります)。このホワイトペーパーでは、自然言語処理
アルゴリズムの説明ではなく、Solr での多言語検索の実行に焦点を合わせますが、特定のアプローチが不
十分である理由を理解するにはこの分野について調査することが重要です。
1
多言語検索は、NLP パイプライン内のアルゴリズムがどの言語でも同
じではないため、言語学的な観点からは難しいものです。
言語判別
多くの場合、NLP パイプラインの最初のステップとして、文書の言語を判別する必要があります。これは、後
続の NLP サブプロセスがテキストの言語に依存しているためです。通常、言語判別は索引付け時にのみ実
行されます。これは、クエリー時の短いテキスト文字列に対する言語判別アルゴリズムの精度が、索引付け
られる長い文書の場合と比較してかなり低い傾向があるためです。
トークン化
トークン化とは、テキストの文字列を単語に分割することを指します。英語は比較的トークン化しやすい言語
です。空白を単語境界として使用すれば、ほぼトークン化できます。ただし、「can't」を構成要素の単語「can」
と「not」にトークン化する場合など、例外はあります。英語のように簡単な言語ばかりではありません。中国
語や日本語では単語間に空白はありません。韓国語では、空白による単語間の分割が一貫して行われず、
書き手によってバラバラです。
語形の正規化
テキストが単語に分割された後に、各単語に語形正規化アルゴリズムが適用されます。語形正規化とは、
単語を正規形に変換する NLP プロセスを指します(例えば、「are」、「is」、「being」をすべて「be」に変換しま
す)。索引時とクエリー時の両方でこの正規化を実行することで、検索エンジンの再現率 が向上します。こ
れは、単語の一変化形のクエリーで、その単語のどれかの変化形が含まれている文書を見つけることがで
きるためです。
2
ステム化と基本形化が、単語のさまざまな変化形を正規化するために検索エンジンで利用される 2 つの主
要なアプローチです。
- ステム化: 単語の末尾から文字を取り除いて原形を抽出する単純なルールベースのアプローチです。
- 基本形化: コンテキストに基づいて単語の基本形を判別します。
適合率と再現率がともに向上するため、基本形化は、単純なステム化アプローチよりも望ましい手法で
す。例えば、「President Obama speaking on healthcare」を検索したユーザーは、恐らく、「President
Obama spoke on healthcare」が含まれている文書が見つかることを期待しているでしょう。索引時とクエ
リー時の両方で「speaking」、「spoke」、「has spoken」を基本形「speak」に基本形化することで、検索エン
ジンは関連するすべての結果を得ることができます。ステム化では、「spoke」から「speak」を得ることはで
きないため「spoke」に一致する自転車部品の「spoke」(スポーク)に関する不適切な検索結果が生成さ
れる可能性があります。欧州言語では、不規則な語尾や語形の変化が大量にあるため、基本形化が特
に重要になります。
複合語分解
ドイツ語、オランダ語、韓国語、北欧言語などの多くの言語では複合語を自由に使用します。再現率を上
げるために複合語は分解して各構成要素に分ける必要があります。ドイツ語の複合語
「Fließbandproduktionsleiter」(「組立ラインの生産マネージャー」)が好例です。求人掲示板でマネージャ
ー(Leiter)の職を探しているユーザーが単語「Leiter」を使用してクエリーを実行したときに、当該複合語
が含まれている文書が返される必要があると想定するのは妥当なことです。
Solr を多言語化する方法
では、Solr 環境内で多言語検索の複雑性を解決するための技法をどのように適用するかについて説明し
ます。残念ながら、単一のアプローチですべての事例に対応できるわけではありません。このホワイトペー
パーでは、多言語検索用に Solr を構成するためのいくつかのオプションを検討し、関連するトレードオフに
ついて説明します。
Solr の解析:Solr が言語を処理する方法
解析は、索引時とクエリー時の両方において、フィールドテキストからトークンが生成されるプロセスを記
述する、Solr の中心的な概念です。通常、1つのトークナイザーと複数のフィルターで構成されます。トー
クナイザーはフィールドテキストを語彙単位に分割します。フィルターは、トークンストリームを調べ、トー
クナイザーから出力されたトークンをそのまま保持したり、変換したり、破棄したり、新規トークンを作成し
たりします。この一連のトークナイザーとフィルターをそのフィールド型の解析チェーンと呼びます。多くの
場合、1 つのフィールド型では、原則として索引時とクエリー時で同じ解析チェーンが適用されます。
Solr の言語固有の解析チェーン
一般的に、言語ごとに異なる解析チェーンが必要になります。各解析チェーンでは、類義語や停止語のフィ
ルタリングは言うまでもなく、文節処理、基本形化/ステム化、複合語分解、文字正規化の固有のルールを
備えることになります。
例えば、Solr で利用できるフリーのステム化フィルターを利用してドイツ語テキストのフィールド型を定義
した場合、以下のようになります。
<fieldType name=”text_deu” class=”solr.TextField” positionIncrementGap=”100”
>
<analyzer>
<tokenizer class=”solr.WhitespaceTokenizerFactory”/>
<filter class=”solr.LowerCaseFilterFactory”/>
<filter class=”solr.SnowballPorterFilterFactory” language=”German”/>
<filter class=”solr.RemoveDuplicatesTokenFilterFactory”/>
</analyzer>
</fieldType>
SnowballPorterFilterFactory フィルターでは、ステム化を適用して、索引時とクエリー時に語形の正規化を実
現しています。前述のとおり、ステム化では、基本形化と比較して適合率と再現率が悪くなります。これは、
フリーのプラグインで構成した解析チェーンを利用した場合の制限です。Solr には、英語等ですぐに使用可
能な基本形化システムは付属していません。
Solr における言語判別
事前にコーパス内の文書の言語が分かっていない場合のために、Solr には使用可能な 2 つの言語判別シス
テムが用意されています。1 つは Tika の言語判別実装ベース、もう 1 つは LangDetect ベースのものです。
言語判別は UpdateRequestProcessor 内で実行されるので、すべての文書フィールドを閲覧でき、新規フィー
ルドの書き込みも可能です。これは、言語ごとにフィールドを定義する多言語検索アプローチ(後述)で特に役
立ちます。
文書の更新に適用される requestHandler に以下の UpdateRequestProcessor を追加した場合、Tika の言語
判別プログラムでは、content フィールドの値に基づいて言語が判別されます。言語は language フィールドに
入れられ、content フィールドは「content_eng」または「content_spa」のいずれかにマップされます。
<processor
class=”org.apache.solr.update.processor.TikaLanguageIdentifierUpdateProcessorFactory”>
<bool name=”langid”>true</bool>
<str name=”langid.fl”>content</str>
<str name=”langid.langField”>language</str>
<str name=”langid.whitelist”>en,es</str>
<bool name=”langid.map”>true</bool>
<str name=”langid.map.lcmap”>en:eng es:spa
</processor>
このようにサブフィールドにマップするように言語判別が設定されている場合、下流の解析で使用するフィー
ルドと型を定義する必要があります。例えば、以下のようにします。
<dynamicField name=”*_eng” type=”text_eng” indexed=”true” stored=”false” multiValued=”false”/>
<dynamicField name=”*_spa” type=”text_spa” indexed=”true” stored=”false” multiValued=”false”/>
<fieldType name=”text_eng” class=”solr.TextField” positionIncrementGap=”100”>
<analyzer>
<tokenizer class=”solr.StandardTokenizerFactory”/>
<filter class=”solr.LowerCaseFilterFactory”/>
<filter class=”solr.SnowballPorterFilterFactory” language=”English”/>
<filter class=”solr.RemoveDuplicatesTokenFilterFactory”/>
</analyzer>
</fieldType>
<fieldType name=”text_spa” class=”solr.TextField” positionIncrementGap=”100”>
<analyzer>
<tokenizer class=”solr.StandardTokenizerFactory”/>
<filter class=”solr.LowerCaseFilterFactory”/>
<filter class=”solr.SnowballPorterFilterFactory” language=”Spanish”/>
<filter class=”solr.RemoveDuplicatesTokenFilterFactory”/>
</analyzer>
</fieldType>
Solr における多言語検索の
2 つの基本的なアプローチ
言語ごとにフィールド型を定義した後にも、文書の索引付けおよびクエリー実行の方法にある程度の柔軟
性があります。ここでは、文書コーパスが多言語であるが、各文書はそれぞれ単一の言語で構成されてい
るものと想定します。以下の 2 つのアプローチに焦点を絞ります。
1. 言語ごとに個別のフィールド
2. 言語ごとに個別の Solr コア
言語ごとに個別のフィールド
言語ごとにフィールドを定義する Solr 構成は簡単に実装できます。フリーのトークナイザーやフィルターを
利用してテキストフィールド型を定義した場合でも、Rosette for Solr にパッケージされているもののような商
用プラグインを利用した場合でも、このアプローチでは対象とする言語ごとに別々のフィールドを作成します。
例えば、英語とチェコ語の書名とコンテンツを索引付けする(書名のみを格納する)ように Solr スキーマを
設定する場合の schema.xml は以下のようになります。
<field name=”book_title_ces” type=”text_ces” indexed=”true” stored=”true” multiValued=”false”
/>
<field name=”book_contents_ces” type=”text_ces” indexed=”true” stored=”false” multiValued=”false”
/>
<field name=”book_title_eng” type=”text_eng” indexed=”true” stored=”true” multiValued=”false”/>
<field name=”book_contents_eng” type=”text_eng” indexed=”true” stored=”false” multiValued=”false”
/>
では、検索アプリケーションの開発者は、この索引に対してどのようにクエリーを実行するでしょうか。それは、
個々のクエリーが一言語か複数言語かいずれに対して実行されるかによって異なります。
一言語内でクエリーが実行されるアプリケーションの例としては、ユーザーが言語設定を指定するニュース
検索 Web サイトが挙げられます。指定した言語でのみクエリーが実行され、当該言語の結果のみが必要と
されます。例えば以下のように、特定の言語のフィールドに対して単純にクエリーを実行します。
http://localhost:8983/solr/books/select?q=title_eng:dog
複数言語に対してクエリーを実行する必要がある場合もあります。例えば、電子文書ディスカバリーの事例
では再現率が最優先されるため、文書の言語に関係なく、特定の人名が含まれているすべての文書につい
てクエリーを実行することがあります。この場合、以下のように、クエリーで論理演算を使用します。
http://localhost:8983/solr/books/select?q=title_eng:Bill%20OR%20title_spa:Bill
あるいは、以下のように、DisMax/Extended DisMax クエリーパーサーを利用して、複数の言語ごとのフィー
ルドに対してクエリーを実行します。
http://localhost:8983/solr/collection1/select?q=Bill&defType=edismax&qf=title_eng%20title_spa
言語ごとに個別のコア
多言語データを索引付けする別の方法として、言語ごとに別々の Solr コアを作成することもできます。複数
のコアで同じフィールド名を使用し、コアごとに異なるフィールド型をフィールド名に関連付けます。これにより、
前のアプローチよりもバックエンドの複雑性が増します。それにもかかわらず、このアプローチを採用するの
にはどのような理由があるのでしょうか。主な理由は、多言語での大規模なクエリーのパフォーマンスです。
このアプローチでは各コアにヒットするサブクエリーを並行して実行できます。さらに、すべてのコアで同じフ
ィールド名を利用できるため、クエリーが単純になるという利点もあります。複数の言語ごとのフィールドに対
して大きな論理式や DisMax のクエリーを作成する必要がありません。
この手法を実装するには、まず、コアを定義する必要があります。コアとして collection_eng および collection_spa
を作成するものとします。
2 つのコアの違いは、core.properties のコア名と、フィールドに関連付けるフィールド型のみにします。今、
text フィールドだけが必要だとします。以下のように、collection_eng コアの schema.xml で、対応するフィ
ールド型を text フィールドに関連付けます。
<field name=”text” type=”text” indexed=”true” stored=”true” multiValued=”true”/>
collection_spa コアの schema.xml には、同じフィールド仕様が含まれますが、text 型にスペイン語テキス
ト用解析チェーンが含まれる点のみが異なります。
Solr の開始時に、文書をどちらかのコアに送信できます。以下のように、Solr の post.jar 索引付けツールを
利用して、これを行います。
java -Durl=http://localhost:8983/solr/collection_eng/update
-jar exampledocs/post.jar english_docs.xml
java -Durl=http://localhost:8983/solr/collection_spa/update
-jar exampledocs/post.jar spanish_docs.xml
一言語のクエリーの実行は単純です。以下のように、クエリーを該当するコアに送信するだけです。
http://localhost:8983/solr/collection_spa/select?&q=text:hola&wt=json&indent=true
複数の言語ごとのコアにまたがるクエリーは、以下のように、Solr の分散検索機能を利用して実行します。
http://localhost:8983/solr/collection_eng/select?shards=localhost:8983/solr/collection_
eng,localhost:8983/solr/collection_spa&q=text:hola&wt=json&indent=true
クエリーの「q」部分が前のアプローチより単純になっている点に着目してください。ただし、対象とするすべて
の言語コアを、shards パラメーターでクエリーに追加する必要があります。常にすべての言語コアに対してク
エリーを実行する場合、クエリーを単純にする代替方法として、クエリーで shards パラメーターを明示的に指
定しなくても済むように、以下のように、デフォルトの shards パラメーターを指定した requestHandler を定義す
ることもできます。
<requestHandler name=”search” class=”solr.SearchHandler” default=”true”>
<lst name=”defaults”>
<str name=”shards”><shard 1 URL>, <shard 2 URL>, ...</str>
</lst>
</requestHandler>
アプローチの比較
以下の表に、言語別フィールドのアプローチと言語別コアのアプローチの長所と短所を要約します。
長所
言語ごとに個別のフィールド
実装が非常に容易
Solr の言語判別 URP の利用
が容易
言語ごとに個別のコア
- クエリーを複数のコアに対して
並行して実行できるため、複
数言語にまたがるクエリーの
パフォーマンスが向上
短所
- 多数の言語での検索時
にクエリーのパフォーマ
ンスが低下
管理オーバーヘッドが増大
言語ごとに文書をシャード化す
る必要があるため、言語ごとに
個別のフィールドのアプローチ
と比較して、言語判別 URP と
容易に連携できない
もう一つのアプローチ
単一の多言語フィールド
Trey Grainger from CareerBuilder が開発して実際に使用しているもう一つのアプローチでは、対象とするす
べての言語のコンテンツを処理できる単一のフィールドを作成します。このアプローチは、前述のアプローチ
の望ましい品質を組み合わせたものです。複数のコアを管理しなくて済むため、管理が単純化すると同時に、
多言語での検索実行時に大きな dismax クエリーを使用しなければならないこともありません。それに加えて、
このアプローチでは、他のアプローチよりも複数言語が混在する文書の処理が容易になるという利点があり
ます。複数言語が混在する文書の場合、他のアプローチでは、データを複数のフィールドまたはコアに送信
する必要があります。
このアプローチのキーは、言語から具体的なフィールド型へのマッピング(例えば、eng → text_eng、spa
→ text_spa など)を定義した新しいメタフィールド型です。カスタムトークナイザーが、フィールドのテキスト
の前に付け加えられた言語コードを調べ(例えば、「eng|Solr is the popular, blazing fast open source…」)、
言語コードに対応したアナライザーを、言語コード部分以外のテキストに適用します。最後に、すべてのト
ークンをマージして重複を除去します。
このアプローチの欠点は、前述のステップを実行する Solr プラグインを手間をかけて開発する必要があるこ
とです。
ROSETTE を利用して言語処理の制限を克服
ここまで、フリーのトークナイザーとフィルターで構成された Solr 構成例について説明してきました。
このような解析コンポーネントは、言語処理機能が以下のように制限されています。
- ほとんどの言語では、フリーのステム化ツールがありますが、基本形化ツールはありません(日本語用
の Kuromoji 基本形化は例外)。基本形化と比較して、ステム化では適合率(「arsenal」(武器庫)と
「arsenic」(ヒ素)が同じステム)および再現率(「spoke」(speak の過去形)と「speak」が同じステムにならな
い)が低くなります。
- Solr の CJK(中国語、日本語、韓国語)用のトークナイザーは単純なバイグラムを利用しています。その
ため、(一文字の単語が索引付けされないので)適合率が低くなることがあり、また検索索引が肥大化しが
ちです。
- Solr で利用可能な複合語分解フィルターは辞書ベースであるため、複合語が広く使用される言語での
利用には適していません。
Rosette for Solr は、Basis Technology で開発した言語処理ツールを Solr プラグインとして利用で
きるようにしたもので、このような制限はありません。
例として、FST ベースの複合語分解、および語形の正規化にステム化ではなく基本形化を組み込んだドイツ
語テキストのフィールド型は、以下のように定義されます。
<fieldType name=”text_deu” class=”solr.TextField” positionIncrementGap=”100”>
<analyzer type=”index”>
<tokenizer
class=”com.basistech.rosette.lucene.BaseLinguisticsTokenizerFactory” rootDirectory=”<rootDirectory>”
language=”deu”
/>
<filter
class=”com.basistech.rosette.lucene.BaseLinguisticsTokenFilterFactory” rootDirectory=”<rootDirectory>”
language=”deu”
/>
<filter class=”solr.LowerCaseFilterFactory”/>
</analyzer>
<analyzer type=”query”>
<tokenizer
class=”com.basistech.rosette.lucene.BaseLinguisticsTokenizerFactory” rootDirectory=”<rootDirectory>”
language=”deu”
/>
<filter
class=”com.basistech.rosette.lucene.BaseLinguisticsTokenFilterFactory” rootDirectory=”<rootDirectory>”
language=”deu” query=”true”
/>
<filter class=”solr.LowerCaseFilterFactory”/>
</analyzer>
</fieldType>
Rosette for Solr では、40 カ国語を超える言語 のフィールド型が定義されています。
検索機能の拡張
言語判別、基本形化、複合語分解に加え、検索エンジンでは NLP ツールを利用して、文書内の固有表現
(名称)に関する検索の利便性を向上させることができます。
以下の理由のため、固有表現の検索は難題になりがちです(そのため、検索サービスを差別化できる可能も
あります)。
- 固有表現は、複数の言語で記述される可能性があります。
- 固有表現は、一般の単語よりもミススペルが生じやすい傾向があります。
- 同じ固有表現が多くの方法で記述される可能性があります。このため、基本形化と類似の言語学的手
法を固有表現に適用する必要があります(例えば、「Abe Lincoln」を検索した場合、
「Abraham Lincoln」が含まれている文書が見つかる必要があります)。
Rosette は、多言語検索アプリケーションの強化に役立つ以下の追加ソフトウェアツールを備えています。
ROSETTE
固有表現抽出モジュール
コーパスがテキスト文書で構成されている場合、固有表現抽出を利用して名称を抽出し、文書内
の名称に名称照合や名称翻訳などのツールを適用できます。
ROSETTE
名称照合モジュール
ある名称が与えられた場合、どのようにすれば、さまざまな形式や言語で表記された名称を照合
し、ミススペルや音声類推による表記に対応できるでしょうか。正規名のリストと名称照合すること
により、そのような機能を実現できます。
ROSETTE
名称翻訳モジュール
コーパスが多言語であったり、英語以外の形式の名称が含まれている場合、適切な言語への名
称翻訳を利用して、ユーザーのクエリーの中の名称を複数の言語の表記に自動的に展開できま
す。
ROSETTE
Rosette Entity Resolver
ある文書に含まれている「George Bush」が、米国の第 41 代大統領と第 43 代大統領のいずれを
指しているのか知りたい場合があります。 Rosette Entity Resolver は、文書に記述されている固
有表現から現実世界の対象を特定し、文書内の人物や事物に対するファセット検索、および関連
する固有表現知識ベースのデータを利用した検索結果への情報付与を実現します。
検索機能の拡張
多言語で検索するように Solr を拡張する際に、エンジニアは以下の 4 つの主な問題を解決しなければなり
ません。
(1) 言語判別を実行するタイミングと方法
(2) スペースで区切られていない言語(CJK など)のトークン化
(3) 語形を正規化する方法(ステム化を利用するのか、もっと優れた基本形化を利用するのか)
(4) 複合語分解の方法
エンジニアは、多言語システムのシステムアーキテクチャーを慎重に選択する必要もあります。このホワイト
ペーパーでは、2 つの最も一般的なアプローチの長所と短所について説明しました。1 つ目の言語ごとに個
別のフィールドを作成するアプローチでは、実装が単純であるという利点が得られますが、サポート対象の
言語数が増えるにつれてクエリーのパフォーマンスが低下します。2 つ目の言語ごとに個別の Solr コアを使
用するアプローチでは、多言語でのクエリーのパフォーマンスは向上しますが、文書を言語ごとにシャード化
する必要があるため、管理オーバーヘッドと複雑性が増します。CareerBuilder で利用されている 3 つ目の
アプローチでは、手間をかけて Solr プラグインを開発する必要がありますが、上記 2 つの基本アプローチ
の欠点を克服した上で、さらに複数言語混合文書の処理も可能になります。
多言語対応 Solr を稼働させるために、オープンソースのソフトウェアによる多言語テキスト処理コン
ポーネント(言語判別、n-グラムによるトークン化、ステム化)が利用可能です。適合率と再現率を向
上させる必要があるアプリケーションでは、Basis Technology の Rosette を採用すれば、トークン化、
基本形化、複合語分解に加え、多数の言語での拡張検索機能を Solr プラグインとして利用できます。
弊社製品の性能をお試しいただける、製品評価版をご提供しております。 ご希望の方は、下記ページ
のリクエストフォームよりお申し込みください。
評価版のお申込み: http://www.basistech.jp/text-analytics/product-evaluation/
1.ここでは、例示のために索引のキーを単語と呼んでいますが、任意の文字列にすることが可能です。厳密には単語ではない索引キーの例として、オー
トコンプリート機能の場合が挙げられます。この機能は通常、文書トークンの先頭から開始するすべての n-グラムを索引付けする(「hello」→「h」、「he」、
「hel」、「hell」、「hello」)ことで、検索索引内に実装されます。
2.再現率(感度とも呼ぶ)は、検索で返された結果のうちの関連性のある結果の割合として計算される情報検索指標です。
©2015 Basis Technology Corporation.“Basis Technology Corporation” , “Rosette” and “Highlight” are registered trademarks of Basis Technology
Corporation.“Big Text Analytics” is a trademark of Basis Technology Corporation.All other trademarks, service marks, and logos used in this document are
the property of their respective owners.(2015-02-17-OMLSWP)