Information Retrieval and Web Search まとめ(8): ポスティングリストの圧縮
前回は、検索インデックスで使用する辞書の圧縮について扱った。今回は、ポスティングリストの圧縮について解説する。
この記事は Information Retrieval and Web Search Advent Calendar 2020 の8日目の記事です。
ポスティングリストの圧縮
- ポスティングファイル(ポスティングリストが収められたファイル)は辞書よりも少なくとも10倍、しばしば100倍以上大きい
- ポスティングの docID を小さくする
- Reuters-RCV1 (80 万文書) では docID に 32 ビット(4バイト)の整数値を使った
- ビットまでは普通に小さくできる
- docID を 20 ビットよりも小さくするのが今回のゴール
- ほとんどの文書に登場するような単語 ("the" など) はもっと小さくしたい
差分符号化
- ポスティングリストでは docID を昇順で保存する
- 例:
computer: 33, 47, 154, 159, 202, ...
- 例:
- docID の差分 (gap) だけを保存すれば十分
33, 14, 107, 5, 43, ...
- ほとんどの差分は 20 ビットよりも小さく保存できるはず
- とくによく出てくる単語は
可変長符号化
- "arachnocentric" のようなレアな単語のポスティングリストには ~20 bits/gap 使ってもよい
- "the" のような単語には ~1 bit/gap にしたい
- それぞれの差分 (gap) について、できるだけ少ないビットで符号化したい
- 可変長符号化 (variable length encoding) が必要
- 可変長符号化では、小さい数字に対して小さなコードにできる
単進符号
- 単進符号 (unary code) は、数
n
を、連続したn
個の1
と、最後の 1 つの0
で表現する3
1110
40
11111111111111111111111111111111111111110
P(n) = 2^(-n)
のときには最適- 普通のユースケースではあまり有用ではない
ガンマ符号
- ガンマ符号 (γ code) は、差分 (gap)
G
を、 length と offset のペアで表現する - offset は
G
を2進数にしたあと、先頭の1
を削ったもの13
-->1101
(2進数) -->101
- length は offset の長さを単進符号でエンコードしたもの
13 (offset 101)
の length は3
-->1110
- ガンマ符号は length と offset を繋げたもの
13
のガンマ符号は1110101
ガンマ符号の特徴
G
は ビットでエンコードされる- offset は ビット
- length は ビット
- ガンマ符号は奇数個のビットからなる
- あらゆる分布の数値で使える
P(n) ~ 1/(2n^2)
のとき最適
- ガンマ符号はパラメータがない
ガンマ符号の速度
- コンピュータはワード境界をもつ(8, 16, 32, 64ビット)
- ワード境界をまたぐ操作は遅い
- ビット単位での操作はとても遅い
- 現代的な方法は、バイトやワードにアライン (align) した符号化を使っている
- 可変バイトエンコード(後述)のほうが高速
Variable-Byte (VB) 符号
- Variable-Byte (VB) 符号 は、差分 (gap)
G
を、バイト単位で符号化していく- 7ビットのデータと、1ビットの継続ビット (continuation bit)
c
の並び(最上位ビットが継続ビットc
) - (継続ビットと言っているが、実際には最後のバイトのときだけこのビットが
1
になるので、ストップビットと言ったほうが意味的には通る気がする)
- 7ビットのデータと、1ビットの継続ビット (continuation bit)
G
が 127 以下なら、7ビット以下で表現できるので、その7ビットに継続ビットc = 1
をセットして終わり- そうでないなら、
G
の低位の 7 ビットをエンコードしたあと、高位のビットは同じアルゴリズムでエンコードする- 最後のバイトの継続ビットは
1 (c = 1)
- それ以外の継続ビットは
0 (c = 0)
- 最後のバイトの継続ビットは
Group Variable Integer 符号
- Google で使用されていた符号化方式
- Jeff Dean, keynote at WSDM 2009 and presentations at CS276
- 5 ~ 17 バイトのブロック内に 4 つの整数値を符号化
- 先頭バイト
- 4 つの 2ビットの長さを入れる
L1 L2 L3 L4
, それぞれ 1, 2, 3, 4 のいずれかの数値が入る- それぞれが、あとに続く4つの整数値のバイト長を表現している
- そのあと、
L1 + L2 + L3 + L4
バイト(4 ~ 16 バイトの範囲)の4つの数値をエンコード- それぞれの数値は 8/16/24/32 ビット(1 ~ 4 バイト)
- VB 符号より2倍ほど速いらしい
- ビットマスクの操作が不要なのでデコードが速い
Simple-9
- Simple-9 [Anh & Moffat, 2004] は、ワード (32 ビット) でアラインされた数値符号化で、複数の数値符号化を使い分ける
- 4 バイト (32 ビット) ごとにブロック化して符号化する
- 最上位の 4 ビットをレイアウト (layout) といい、残りの 28 ビットの符号化方法(全9種類)を指定するのに使用する
0
: 1つの 28 ビットの数値1
: 2つの 14 ビットの数値2
: 3つの 9 ビットの数値(+ 1つのスペアビット)3
: 4つの 7 ビットの数値4
: 5つの 5 ビットの数値(+ 3つのスペアビット)5
: 7つの 4 ビットの数値6
: 9個の 3 ビットの数値(+ 1つのスペアビット)7
: 14個の 2 ビットの数値8
: 28個の 1 ビットの数値
- ビットマスクを使って効率的にデコードできる
- Simple-16 は 16 種類の符号化を使うバージョン
- 他にも 64 ビットワードへの拡張など
講義資料
- Index Compression (pdf)
- Postings Compression
参考資料
- IIR chapter 5
- MG sections 3.3-3.4
- Compression of inverted indexes for fast query evaluation (Scholer et al. 2002)
- Inverted index compression using word-aligned binary codes (Anh and Moffat 2005)
- Variable byte codes
- Inverted index compression and query processing with optimized document ordering (Yan et al. 2009)
- Word aligned codes