アンケートご協力のお願いgihyo.jpでは,2010年度に向けて豪華プレゼントが当たる読者属性アンケートを実施しております。ご協力ください。

gihyo.jp » DEVELOPER STAGE » 連載 » 検索エンジンはいかにして動くのか? » 第7回 転置索引の構築

検索エンジンはいかにして動くのか?

第7回 転置索引の構築

はじめに

これまで,転置索引の構造や具体的なデータ構造を見てきました。今回は,検索したいテキスト文書から,どのようにこの構造を構築するかを説明していきます。

ディスクベースの構築方法

第3回では,表を作成しそれを転置させることで転置索引を構築しました。実際にコンピュータに処理をさせる場合も,メモリ上の2次元配列で同様に構築することが可能となります。しかし,通常の転置索引は非常に疎な表となるため,この方法ではメモリを使いすぎてしまいます。また,リンクリストなどのメモリ上でのデータ構造を用いることにより,上記の方法と比較して少ないメモリ量で構築することもできます。

これらの方法はいずれも,対象とする文書集合を変換した転置索引が実メモリに収まる場合にのみ可能となる方法となります。しかし多くの場合,転置索引は実メモリよりも大きくなります。そのような場合はディスクを用いた構築方法が必要となり,効率的に行うには少し工夫が必要です。ここでは 後者の場合を想定して(※1),ディスクベースの構築方法について説明していきます(※2)。

今回はSort-based InversionとMerge-based Inversionと呼ばれる2つの方法を紹介します。

※1)
近年は,大量のメモリを持つマシンも存在しますが,それでも実メモリ量よりも多くの文書を扱うケースが一般的であるという考えからです。
※2)
この場合は説明の簡略化のため,文書レベルの転置リストを対象に説明しています。単語レベルの転置リストの場合も同様の手順となります。

Sort-based Inversionによる構築

Sort-based Inversionによる構築手順は,リスト1に示す疑似コードのようになります。文書ごとにレコード<t, d, f(d,t)>を生成し,ディスクに追記していきます(9行目)。ここで,tは単語ID,dは文書ID,f(d,t)はdにおけるtの出現頻度となります(※3)。

その後,各レコードを単語IDの昇順に,単語IDが同じ場合は文書IDの昇順にソートします(12行目)(※3)。あとは,ソート後のファイルを先頭から見ていくと各単語IDとそれを含む文書IDのリストを取得できるので, それらで各ポスティングリストを構築します(14~16行目)。また,ポスティングリストを圧縮する場合は15行目の段階で行います。図1に,サンプルデータでの構築の様子を示します。

※3)
マージソートや,ブロック単位でメモリに読み込みソートし最後にマルチウェイでマージする方法などが挙げられます。

リスト1 アルゴリズム1:Sort-based Inversion

 1: file = NewFile()
 2: dictionary = NewHash()
 3: while all documents have not been processed do
 4:  D = GetDocument()
 5:  for all token ∈  do
 6:    if term(token) ∉ dictionary then
 7:       postings list = AddToDictionary(dictionary, term(token))
 8:    end if
 9:    WriteRecordToFile(TermID(token),DocID(token),Freq(token), file)
10:  end for
11: end while
12: ExternalSort(file)
13: inverted_file = NewFile()
14: for all term ∈ file do
15:   ConstructPostingList(term, inverted_file)
16: end for

図1 サンプルにおけるSort-based Inversionでの構築

図1 サンプルにおけるSort-based Inversionでの構築

Merge-based Inversionによる構築

Merge-based Inversionによる構築も同様に疑似コードを使って説明します(リスト2)。

この方法では,ソートベースの方法とは異なり,辞書ではターム自体をキーとし,メモリ上で可能な限り辞書と転置リストを構築します(6~19行目)。文書中の中にタームが存在しなければ,そのつど辞書に登録します(9,10行目)。また,ここでは各ポスティングリストは倍々に領域を増やしてポスティングを追加できるようにしています(14~16行目)。メモリ上での構築後,タームを辞書順にソートし,ディスクに書き出します(20,21行目)(※4)。

この作業を全文書を処理できるまで繰り返し,最後に書き出された複数のファイルをマルチウェイでマージすることにより,最終的な索引が構築されます(23行目)。また,ポスティングリストを圧縮する場合は23行目のステップで行われます。図2に,マージベースの転置での構築処理の流れを示します。

※4)
この疑似コードではハッシュで辞書を構築しているので書き出す時にソートしていますが,順序を持った木構造などで辞書を管理している場合は,ソートのステップは省略できます。

リスト2 アルゴリズム2:Merge-based Inversion

 1: n ← 0
 2: while all documents have not been processed do
 3:   nn + 1
 4:   filen = NewFile()
 5:   dictionary = NewHash()
 6:   while free memory available do
 7:     D = GetDocument()
 8:     for all token ∈ D do
 9:       if term(token) ∉ dictionary then
10:          posting_list = AddToDictionary(dictionary, term(token))
11:       else
12:         posting_list = GetPostingList(dictionary, term(token))
13:       end if
14:       if full(posting_list) then
15:          posting_list = DoublePostingList(dictionary, term(token))
16:       end if
17:       AddToPostingsList(posting_list, docID(token))
18:     end for
19:   end while
20:   sorted terms ← SortTerms(dictionary)
21:   WriteBlockToDisk(sorted terms, dictionary, filen)
22: end while
23: MergeBlocks(file1,...,filen, filemerged)

図2 Merge-based Inversionでの構築の流れ

図2 Merge-based Inversionでの構築の流れ

Sort-based Inversion vs. Merge-based Inversion

ここではアルゴリズムの細かい解析は省略しますが,両者を比べた場合,一般的にはMerge-based Inversionによる構築方法の方が効率的であると考えられています。Sort-based Inversionではすべての辞書をメモリ上に保持するため,扱う文書数が多くなる場合には問題となり,また,ディスクベースでソートを行うためI/Oコストも大きくなります。

構築方法の種類

転置索引の構築には,大きく分けて以下の2種類の構築方法があります。

  • 静的な構築方法(offline index construction, offline approarch)
  • 動的な構築方法(online index construction, online approarch)

静的な構築方法では,入力データに対して構築処理を行い,それらの処理の完了時に検索可能となるように構築する方法となります。一方,動的な構築方法では,索引構造を常に検索可能,かつ,最新の状態に保つように構築する方法になります。

つまり,静的な方法は文書の到着(作成)から索引への反映までに多くの時間が許容できる場合に用いられ,動的な方法は,検索可能になるまでの待ち時間をほんの少ししか許容できない場合に用いられる方法であると言えます。これまで説明してきた方法は,静的な構築方法となります(※5)。文書集合があまり変化しない場合や,変化してもそれが反映されるまでに時間がかかっても良い場合は通常,静的な方法で索引の構築を行います。

※5)
ここでは触れませんが,Googleが開発したMapReduceによる転置索引の構築処理も基本的には静的な構築方法となります。

一方,新鮮度(freshness)が重要な文書集合も存在します。たとえば,Web上のニュースやブログなどの場合,新しい記事は古い記事よりも重要度が高いので,新しい記事が追加されたら,すぐに索引に反映させたいと思います。そのような場合には動的な構築方法が選ばれます。動的な構築方法については,連載の後半の方で扱う予定です。

まとめ

今回は,文書から転置索引の構造を構築する方法について説明しました。多くの文書から索引を構築したい場合は,ディスクを使った構築方法が必要であり,代表的な2種類の方法について疑似コードを用いてアルゴリズムを紹介しました。これらの方法により,利用可能な実メモリよりも大きな転置索引が構築できるようになります。また,これらの方法は静的な構築方法と呼ばれ,一般的な文書集合で広く用いられています。

参考文献
  • [1]Inverted files for text search engines, Justin Zobel, Alistair Moffat, ACM Computing Surveys (CSUR), 2006
  • [2]Introduction to Information Retrieval, C. D. Manning, P. Raghavan, H. Schutze , Cambridge University Press, 2008
  • [3]Managing Gigabytes: Compressing and Indexing Documents and Images, Ian H. Witten, Alistair Moffat, Timothy C. Bell, Morgan Kaufmann Publisher, 1999

著者プロフィール

山田浩之(やまだひろゆき)

日本IBM株式会社を経て,ヤフー株式会社等で検索エンジンの開発に従事。現在は大学院でデータベース・情報検索の研究を行う。また,オープンソースで全文検索エンジンLuxやデータベースマネージャLux IOの開発を行っている。

コメント

コメントの記入

パスサポ

多数の情報処理技術者試験対策書籍の発行実績を誇る技術評論社がお届けする,資格試験合格サイト「めざせ! 情報処理試験 パスサポ」が開設されました。

ピックアップ

サクセスストーリーに続く,快適サーバー運用管理のヒント!

データの増大,煩雑な管理,システムダウン,セキュリティなど,迫りくる課題からシステム管理者の負担を軽くするポイントを解説します。

gihyo.jp インフラエンジニア情報局

ネットワークやITにかかわるあらゆる業種で必要とされるインフラエンジニアに向けた技術情報や心構え,その魅力について多角的に紹介。

テストエンジニア ステーション

いま,ITに関わるあらゆる開発業務で注目されつつあるテスト系エンジニアをターゲットにしたコンテンツサイトを展開します。

一行クイックアンケート

gihyo.jpで取り上げてほしいネタは?

※検索はページ右上の検索ボックスをご利用ください。

その他の連載

キーパーソンが見るWeb業界

本連載はWeb Site Expert/gihyo.jpとの連動企画です。阿部淳也, 長谷川敦士, 森田雄のお三方による,Web業界をテーマにした座談会です。

きたみりゅうじの聞かせて珍プレー

ソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。みなさんからの投稿もお待ちしてます!

ActionScript 3.0で始めるオブジェクト指向スクリプティング

野中文雄氏が,簡単なスクリプトは書いたことがあるという初級者を対象に,ActionScript 3.0の基本からクラス定義までを解説します。

まだ間に合う「ITパスポート」受験対策 原山先生の短期合格塾

この連載では,4月18日のITパスポート試験の受験に向けて,短い期間で効率良く受験対策を行う方法や,確実に得点するための裏ワザなどを伝授していきます。

Ubuntu Weekly Recipe

Ubuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。

C/C++プログラマのためのDTrace入門

よくカーネルのチューニングや解析で活用されるDTraceですが,実はユーザプログラムの開発においても非常に有用です。連載ではC/C++プログラマやテストに関わる方向けにDTraceの使い方を解説します。

Blogopolisから学ぶ計算幾何

計算幾何学は,図形に関するアルゴリズムを研究するコンピュータサイエンスの一分野です。本連載では,ビジュアルブログ検索エンジン「Blogopolis」で採用されている計算幾何のアプローチを例に取り上げながら,計算幾何の初歩を実践的に学習します。

検索エンジンはいかにして動くのか?

本連載では, 今や誰もが利用している検索エンジンの中身を,全体の仕組みやデータ構造,アルゴリズムから分散インデックスまで,最近の研究事例も交えて紹介します。

連載一覧

gihyo.jp

  • DEVELOPER STAGE
  • ADMINISTRATOR STAGE
  • WEB+DESIGN STAGE
  • LIFESTYLE STAGE
  • SCIENCE STAGE
  • NEWS & REPORT

書籍案内

  • 新刊書籍
  • 書籍ジャンル一覧
  • 書籍シリーズ一覧
  • 新刊ピックアップ
  • ロングセラー
  • 電脳会議

定期刊行物一覧

  • Software Design
  • WEB+DB PRESS
  • Web Site Expert
  • 組込みプレス