50
Data-Intensive Text Processing with MapReduce (Ch4 Inverted Indexing for Text Retrieval) 2010/10/03 shiumachi http://d.hatena.ne.jp/shiumachi/ http://twitter.com/shiumachi

Data-Intensive Text Processing with MapReduce ch4

Embed Size (px)

DESCRIPTION

This document is written about "Data-Intensive Text Processing with MapReduce" Chapter 4.This chapter describes how to design inverted index with MapReduce algorithm.

Citation preview

Page 1: Data-Intensive Text Processing with MapReduce ch4

Data-Intensive Text Processing with MapReduce

(Ch4 Inverted Indexing for Text Retrieval)

2010/10/03shiumachi

http://d.hatena.ne.jp/shiumachi/http://twitter.com/shiumachi

Page 2: Data-Intensive Text Processing with MapReduce ch4

Agenda

● 4章 テキスト検索のための転置インデックス● 4.1 Webクローリング● 4.2 転置インデックス● 4.3 転置インデックスの基本実装● 4.4 転置インデックスの改良版● 4.5 インデックス圧縮● 4.6 Retrievalには使えるの?● 4.7 まとめ(より深く勉強したい人への案内)

Page 3: Data-Intensive Text Processing with MapReduce ch4

Chapter 4Inverted Indexing for Text Retrieval

4章テキスト検索のための転置インデックス

Page 4: Data-Intensive Text Processing with MapReduce ch4

Web検索● Webって結構でっかいよ

● 数百億ページ● テキストだけで数百TB

● でもユーザは検索を待ってはくれない● せいぜい数百ms

● Web 検索というのは非常に特殊だけど不可欠なlarge-data problem

Page 5: Data-Intensive Text Processing with MapReduce ch4

Web検索の3要素● crawling, indexing, retrieval● crawling と indexing は性質的に似ている

● リアルタイム性は必要ない● オフラインで処理可能● 要スケーラビリティ

● retrieval は全く逆● リアルタイム性が要求される● 突然のクエリ増加にも耐えられる必要がある

Page 6: Data-Intensive Text Processing with MapReduce ch4

転置インデックス● Web検索における標準的なデータ構造● term に対し、document と payload のリストが割り当てられて構成されている

● この章のメイン。後述

Page 7: Data-Intensive Text Processing with MapReduce ch4

4.1 Webクローリング

Page 8: Data-Intensive Text Processing with MapReduce ch4

なんでクローリングの話?● Webページのデータなんて金出せば買えない?

● 学術目的ならカーネギーメロン大学に問い合わせれば一応手に入る(25TBほど)

● でも現実のWebデータは更新され続けてるわけだし、これじゃ到底用をなさない

● クローラなんて作るの簡単じゃない?● html → →ページを取得 リンク取得 リンク先のページ

→ →……を取得 リンク取得 だけ● 概念的にはそれでOKだが、実際作るとなるといろいろ問題が発生する

Page 9: Data-Intensive Text Processing with MapReduce ch4

クローリング、ここに注意● Webサーバに高負荷かけないエチケット

● librahack を思い出そう● クロール先のスコアリング

● スパム避けして優先順位つける● Webはコピーされた文書がいっぱいなので、どれがクロールするのに適切かを見極める

● 更新頻度のパターンを分析する● 普通は分散クラスタを組むので障害対策は万全に● Webは多言語。英語・日本語・中国語混じってて当たり前● とても書ききれないので詳しくは自分で調べろ

Page 10: Data-Intensive Text Processing with MapReduce ch4

4.2 転置インデックス

Page 11: Data-Intensive Text Processing with MapReduce ch4

転置インデックスの構造

● 1 つの term に対し、<doc-id,payload> のリストが並ぶ● payload は千差万別

● その term が文書に出てくる頻度は比較的単純なもの● 出てくる位置とか、タイトルに出てくるかどうかとか、payload に入るものはプログラマ次第

payload (postingじゃないよ)

Page 12: Data-Intensive Text Processing with MapReduce ch4

検索の仕組み(ブーリアン検索)

天一  こってり

天一

こってり doc 100 1 doc 200 3 doc 300 4

doc 10 1 doc 100 2 doc 200 1

OR検索なら全てのドキュメントが対象になるが、AND検索なら両方のキーワードが共通して登場するドキュメントのみ考慮する

普通は関連文書などをあらかじめ計算しておいて(アキュムレータ)、計算コストをさらに下げたりする

Page 13: Data-Intensive Text Processing with MapReduce ch4

インデックスも大変● インデックスは巨大なので普通はメモリに乗らない

● だからディスクに置いたりするのが普通● でもGoogleは全部メモリに乗せてるとか

● クローリングと同様、概要しか説明してないので興味があれば自分で調べること

Page 14: Data-Intensive Text Processing with MapReduce ch4

4.3 転置インデックスの基本実装

Page 15: Data-Intensive Text Processing with MapReduce ch4

MapReduceだとメチャ簡単です● 通常転置インデックスは巨大なので、実装しようと思うとメモリ管理とかもろもろしなきゃいけないので大変

● しかしMRならそんなことを気にしなくても大丈夫

● 大学1年生レベルでも簡単に実装できます● 上級生なら1週間あれば書けるでしょ

Page 16: Data-Intensive Text Processing with MapReduce ch4

図4.2 MapReduceによる転置インデックス実装 今回は payload を頻度で出している。

一目でわかる通りとても単純。

Page 17: Data-Intensive Text Processing with MapReduce ch4

図4.2 の解説● Map

● ワードカウントして <term,<文書id, count>>で出力してるだけ

● count の部分が payload。別に他のものに変えても構わないし、それはとても簡単

● Reduce● Mapからきたデータのvalueをposting list にして出力してるだけ

● 具体例は図4.3にある

Page 18: Data-Intensive Text Processing with MapReduce ch4

図4.3 MapReduceによる転置インデックス作成(具体例)

Page 19: Data-Intensive Text Processing with MapReduce ch4

4.4 転置インデックスの改良版

Page 20: Data-Intensive Text Processing with MapReduce ch4

やっぱりメモリに乗りません● 図4.2 のコードは、ポスティングデータがメモリに乗ることが前提● スケールしないのでなんとかしよう

● value-to-key conversion パターンを使う

<term t, <docid, f>>

<<term t, docid>, f>

Page 21: Data-Intensive Text Processing with MapReduce ch4

図4.4 MapReduceによる転置インデックス実装(改良版)value-to-key conversion パターンを実装したもの。

Page 22: Data-Intensive Text Processing with MapReduce ch4

図4.4 の解説● Map については前述の通り

● ただしPartitioner は自作する必要がある(同一termが同一reducerに集まるようにしなければならない)

● Reduce● 現在のtermと一つ前のtermが異なっていたら、ある

termの処理が完了しているとみなしてEmit()● データ末尾のtermの場合はClose処理内でEmit()

Page 23: Data-Intensive Text Processing with MapReduce ch4

ドキュメントの長さ● ほぼ全ての検索モデルで必須● MRにおける計算方法は2つ

● in-mapper combining パターンを使ってメモリ上に長さを持っておき、CLOSE処理時にサイドデータとして書き出す– 通常これがメモリあふれを起こすことはない(らしい)

● 特殊なkey-valueペアを持たせておき、これだけ別処理が走るようにする(3.3 での * みたいに)

Page 24: Data-Intensive Text Processing with MapReduce ch4

4.5 インデックス圧縮

Page 25: Data-Intensive Text Processing with MapReduce ch4

インデックス圧縮● ナイーブな実装は d-gap

● 数値そのものを保存するのではなく、ソートした上でその差分だけを保存

● うまく一定のデータ単位に収めると、速度・サイズともに効率のいい圧縮ができる

1, 2, 4, 7, 12, 17, ...

1, 1, 2, 3, 5, 5, ...

Page 26: Data-Intensive Text Processing with MapReduce ch4

バイト単位コード、ワード単位コード

● 数値を表すのに1ワードで表すと圧縮にならない(後述)

● 1バイト、1ワードのうち数ビットを区切り位置指定用予約スペースにし、残りをうまく切り分けてやると効率よくデータを収めることができる

Page 27: Data-Intensive Text Processing with MapReduce ch4

そのままだと圧縮にならない?● 4バイト符号なしint型を考える

● ソートして差分をとっているため負数は考えなくていい

● 差分の最大値は当然2^32-1、つまり上記int型の最大値に等しい

● よって、1通りのデータ形式で表そうと思ったらやっぱり4バイト必要になる

Page 28: Data-Intensive Text Processing with MapReduce ch4

varInt 法

必要なバイト数だけ使おう

1 1 1 1 1 1 1 1

終端フラグ1 で終端を示す

値保持領域7bit分のデータを保持

例) 127, 128 の場合

1 1 1 1 1 1 1 1

0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0

127までなら1バイトで表せる

Page 29: Data-Intensive Text Processing with MapReduce ch4

varInt 法の改良(group varInt)

GoogleのJeff Deanが開発。varIntより高速ある1バイト全部を、続く数バイトの内訳を示すのに使う

次の値が1バイトであることを示している

0 0 0 1 1 0 1 100〜11で1〜4を表している

この例の場合、続く4つの値はそれぞれ1バイト、2バイト、3バイト、4バイトとなる

Page 30: Data-Intensive Text Processing with MapReduce ch4

Simple-9

4バイトの上位4bitをフラグとして、残り28bitを9通りの方法で分割する

1 1 1 1 1 1 1 1

フラグ28bitを指定された方法で分割

値保持領域28bit分のデータを保持

111 1…

Page 31: Data-Intensive Text Processing with MapReduce ch4

Simple-9 のフラグ [4] 上位bit 符号の個数 符号のビット長0000 28 1

0001 14 2

0010 9 3

0011 7 4

0100 5 5

0101 4 7

0110 3 9

0111 2 14

1000 1 28

最適化するにはDPを使う必要があるが、tsubosakaさんによると0.2%ほどしか圧縮率

が改善しなかったため実用的ではないらしい [4]

Page 32: Data-Intensive Text Processing with MapReduce ch4

ビット単位コード● バイト単位コード

● 高速● 無駄ビットが多い

● ビット単位コードだと無駄ビットが出ない● 1つの値を表すビット範囲を示すのにprefixコードを使う● prefix-free コードとも呼ばれるらしい。どっちやねん

Page 33: Data-Intensive Text Processing with MapReduce ch4

図4.5 bit-aligned code における prefix コードの一例

Page 34: Data-Intensive Text Processing with MapReduce ch4

unary code(alpha code)

● 0からスタート● 1を示している。1が最小値。他のprefixコードも同じ

● 10, 110, 1110, ... と続く(それぞれ2, 3, 4)

● 見ての通り効率メチャ悪いのでこのまま使われることはない● が、他のコーディングスキームの一部となっている

Page 35: Data-Intensive Text Processing with MapReduce ch4

Elias Gamma Code

unary code + binary code の組み合わせ 以下の例は 9 を表している

1 1 1 0 0 0 1

unary code3bit が後ろに続くことを示している

binary code000 = 1 なので

これは 2 を表している

いくつかの gamma code をまとめて別の gamma code で表す delta code というのもある

大きい数値を扱う場合は delta の方がいい

Page 36: Data-Intensive Text Processing with MapReduce ch4

Golomb code

パラメータを用いた符号化 以下はパラメータ b = 10 で 32 を表したとき

1 1 1 0 0 0 1

unary code値をbで割ったときの商32/10 の商は3

binary code000 = 1 なので

これは 2 を表している

バイナリコード部分はパラメータや値によってビット数が変わる(が、説明大変なので省略)

パラメータが2のべき乗のときRice code という

Page 37: Data-Intensive Text Processing with MapReduce ch4

ゴロム符号と d-gap

d-gap に適用するときの最適なパラメータは以下の式で算出できる

N:ドキュメントの数df: ある term の document frequency

Page 38: Data-Intensive Text Processing with MapReduce ch4

符号化の速度比較● エンコードはGolomb(Rice)が一番速く、group

varInt が一番遅い● デコードは全く逆

● group varInt 最速、ビット符号化が遅い● Riceはその中では最速、Golombが一番遅い(group

varInt の 1/10)

Page 39: Data-Intensive Text Processing with MapReduce ch4

MapReduce と Golomb コード● Golomb の最適パラメータの計算には df が必要

● 事前に計算しておく必要がある● 鶏が先か卵が先か

● メモリに載らないから圧縮しようとしてるのにその計算をするのにメモリに載せなきゃいけない

● in-mapper combining パターンと order inversion パターンを使って解決しよう

Page 40: Data-Intensive Text Processing with MapReduce ch4

in-mapper combining で df を出す

<<term t, docid>, tf f>

<<term t, *>, df e>

1つのmapタスクで処理した文書集合におけるdfはin-mapper combiningを使えば算出可能(単に出現した文書数をカウントアップするだけ)

この * つき出力を order-inversion で各termの一番最初に 来るようにすれば、トータルの df を得た上で b を計算

可能

Page 41: Data-Intensive Text Processing with MapReduce ch4

4.6 Retrievalには使えるの?

Page 42: Data-Intensive Text Processing with MapReduce ch4

big data における検索● リアルタイム処理が要求されるので

MapReduceはどの道無理● 以下MapReduce ……全く出てこない

● でも分散させるのは一緒● 分散の方法は2つ

● ドキュメントを分割し、それぞれのサーバで全てのterm を持つ

● term を分割し、それぞれのサーバで全てのドキュメントを持つ

Page 43: Data-Intensive Text Processing with MapReduce ch4

図4.6 ドキュメント分割とterm分割を表した図縦に3分割するとドキュメントの分割になり、横に3分割するとtermの分割になる

Page 44: Data-Intensive Text Processing with MapReduce ch4

ドキュメントの分割● 長所

● レイテンシが短くなる● 短所

● 全サーバにクエリを投げるので負荷が高くなる

Page 45: Data-Intensive Text Processing with MapReduce ch4

termの分割● 長所

● トータルのディスクアクセスの量が少ないため高スループット

● 短所● レイテンシ長い● クエリ評価が複雑になる● クラスタ全体のハードウェア障害耐性が低い

● 結局はドキュメント分割の方に分がある● Googleが採用してるのもドキュメント分割

Page 46: Data-Intensive Text Processing with MapReduce ch4

ドキュメント分割の方法● クオリティで分割

● 優先度の高いページをまとめたインデックスを作っておき、優先度の高い方から順にアクセスしていく

● コンテンツで分割● 多分どんな種類のコンテンツかということだと思う

Page 47: Data-Intensive Text Processing with MapReduce ch4

他にも考えなきゃいけないことがいっぱい

● サーバは地理的に分散している場合がある● 一番近いサーバを選択する手法

● 検索して返すのはドキュメントIDだけだが、これは何も意味がない● 文書サーバを別に立て、IDからメタデータを引けるようにする必要がある

● クエリも投入頻度が異なる● 頻出クエリ用のサーバを上位に位置づけることで負荷低減

Page 48: Data-Intensive Text Processing with MapReduce ch4

参考文献

Page 49: Data-Intensive Text Processing with MapReduce ch4

1. Facebook has the world's largest Hadoop cluster!, Facebook has the world's largest Hadoop cluster!, http://hadoopblog.blogspot.com/2010/05/facebook-has-worlds-largest-hadoop.html

2. ユーティリティコンピューティング, wikipedia, http://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0

3.Hadoop, Tom White, オライリー・ジャパン, 2009

4.Simple-9 – について解説 tsubosakaの日記, http://d.hatena.ne.jp/tsubosaka/20090810/1249915586

Page 50: Data-Intensive Text Processing with MapReduce ch4

Thank you !