370 likes | 555 Vues
IIR 輪講復習 #3 Dictionaries and tolerant retrieval. 3 章のテーマ. 正確にクエリを組み立てられないときに、ユーザーを助けるための機能 ワイルドカードクエリ typo 修正 ( もしかして ). 辞書検索のためのデータ構造. 辞書から語句を探す. ハッシュ or 探索木. 単純なハッシュは向いてない クエリの微妙な間違いを扱いづらい ワイルドカードの実現が難しい Web 検索だとサイズが大きすぎる 探索木が良い 二分探索木 O(log m) ~ O(m) / Rebalancing 問題 B 木
E N D
3章のテーマ • 正確にクエリを組み立てられないときに、ユーザーを助けるための機能 • ワイルドカードクエリ • typo 修正 (もしかして)
ハッシュ or 探索木 • 単純なハッシュは向いてない • クエリの微妙な間違いを扱いづらい • ワイルドカードの実現が難しい • Web 検索だとサイズが大きすぎる • 探索木が良い • 二分探索木 • O(log m) ~ O(m) / Rebalancing 問題 • B木 • 多分木の平衡木 • O (log m) • 一般的に外部記憶装置 (ブロックデバイス) 上での探索に向いている
ワイルドカードクエリ • Goo* • Goo, Good, Google, Goonies ... • 役立つ場面 • クエリのスペルが正確に分からないとき • スペルが複数の変形を含んでいる • 検索エンジンの処理が不透明なので「とりあえず全部」 • 外国語
mon* • trailing wildcard query • m, o, n とツリーを辿る • そこから先の子ノードを全部取る • mon* に対する term 群 W が決まる • 転置インデックスから W に含まれる term に紐尽くドキュメントを取得する
* 一つに対する単純なアプローチ • *mon • Reverse B-treeを作って辿る • lemon → root-n-o-m-e-l • se*mon • se を通常の B-tree から辿る → 集合W • mon を Reverse B-tree から辿る → 集合R • W ∩ R を取る (intersection)
もっと複雑な * に対するアプローチ • fi*mo*er • Permuterm indexes • k-gram indexes for wildcard queries
Permuterm (順序入れ替え語) index • hello$ を回転させてすべての回転パターンを作り、オリジナルにリンクする
Permuterm index からの探索 • m*n → m*n$ → n$m* • n$m* は trailing wildcard query。n$m* をツリーから探す
Permuterm Index の弱点 • 辞書が非常に大きくなる • 全 term の回転を作ったら当然巨大
K-gram indexes for wildcard queries • ワイルドカード用の k-gram • castle • $ca, cas, ast, stl, tle, le$ 単語境界
k-gram index • 全 term の k-gram を作る • 各 term は k-gram からポイントされる
k-gram index からの探索 • re*ve • $re AND ve$ • 3-gram index に対してクエリする • relive, remove, retrieve にヒット • post-filtering • red* は $red AND red のため retired が引っかかる。 • red* ではないので、除外する。
ワイルドカードクエリは高コスト • コストが高い • 特別なインデックスを引く • フィルタする • 転置インデックスを引く • Advanced な UI からしか使えないようにしている例が多い • 通常の機能に含めるとユーザーが意図せず * を使って、検索エンジンが過負荷になる
基本的な考え方 • 二つの文字の似てる度合い (クエリ間の距離) を定量化する • 辞書の中からクエリに近い単語を取得する • 取得した候補を「尤もらしさ」で絞り込む
尤もらしさ • 検索対象文書群での df (document frequency) • クエリログを使うなら、クエリログ中での尤度
文字列間の距離 • 編集距離 (Levenshtein 距離)
編集距離 (Levenshtein距離) • 二つの文字列がどの程度異なっているかを示す数値 • 文字の挿入, 削除, 置換で一方を他方に変形するための最小の手順回数 • 伊藤直哉, 伊藤直也 → 1 • 伊藤直, 伊藤直也 → 1 • 佐藤直哉, 伊藤直也 → 2 • 佐藤B作, 伊藤直也 → 3
編集距離の計算#1 • 求めたいもの ・・・ LD('apple', 'play') • LD('appl', 'play') • 挿入で LD('apple', 'play')になる • LD('appl', 'play')= LD('appl', 'play') + 1 (i) • LD('apple', 'pla') • LD('apple', 'play')から y 削除でこれになる、すなわち LD('apple', 'pla') は削除1回で LD('apple, 'play')と同じ • LD('apple', 'play')= LD('apple', 'pla') + 1 (ii) • LD('appl', 'pla') • 次の1文字置換で LD('apple', 'play')になる • ただし次の文字が等しい場合は置換が要らない • LD('apple', 'play')= LD('appl', 'pla') + 0 or 1 (iii)
編集距離の計算#2 • 再帰的な漸化式を得る • (i) LD(i, j) = LD(i-1, j) + 1 • (ii) LD(i, j) = LD(i , j-1) + 1 • (iii) LD(i, j) = LD(i-1, j-1) + 0 or 1 • 編集距離は上記 (i) ~ (iii) の最小値を既知の L(0, 0) から出発して再帰的に計算していけば良い
3章後半 • スペルミス修正 • 編集距離の計算方法はわかった • 入力との編集距離を辞書全体に総当たりで求めるのは非効率 → どうする?
辞書全体に編集距離を計算? • 20万語以上全てとの編集距離を計算 • 非現実的 • 距離を計算する対象をあらかじめ絞る • Nグラムインデックスを利用する
Nグラムインデックス • bi-gram • algorithm → al, lg, go, or, ri, it, th, hm • 全単語の bigram の索引を作る bo aboard boardroom border about or border morbid sordid lord rd aboard boardroom border ardent Introduction to Information Retreival #3 (P.56) より
Nグラムインデックスを使った修正候補の絞り込みNグラムインデックスを使った修正候補の絞り込み • 入力 "bord" → bo + or + rd • Nグラム索引で2回以上ヒットするもの • すなわち入力と「被り」が多いもの bo aboard boardroom border about or border morbid sordid lord rd aboard boardroom border ardent
Jaccard 係数で更に絞り込む • "bord" の修正候補に "boardroom" • 長い単語がノイズになりやすい • Jaccard 係数などで足切り • |A∩B| / |A∪B|
スペルミス修正まとめ • 入力に対してbigram索引で被りが多いものを候補として取得 • 取得した候補を Jaccard 係数で足切り • 各候補に対して編集距離を計算 • 距離が近いものほど正解である可能性が高い (同じ距離の物は df で優先度を決める) • 伊藤直哉に対し... • 伊藤直也 1 ← これ! • 佐藤直也 2
Context-sensitive spelling correction • "flew form Heathrow" • × flew, form, Heathrow 別々に修正する • 効率が悪い、flew を fled にされても困る • ○ "flew form" で頻度の高い候補を調べる • "flew from" が "fred fore" より高い etc.
Soundex index • 目的の言葉と同じような発音の語に間違えて typo してしまう • "phonetic hash" を利用して補正する → soundex • "Herman" → H655 • 似たような発音の単語は同じハッシュ値になる • アルゴリズム (Heuristic?)・・・ 本文にて解説 • soundex index • Nグラム索引同様に、キーが Soundex、値が term になっている索引
3章まとめ • "tolerant な検索" がテーマ • 辞書に B木やkグラム索引を使うとワイルドカードや部分一致検索ができる • スペルミス修正は辞書との編集距離を算出して実現できる • 計算対象の候補の足切りにkグラム索引、Jaccard 係数を利用した • 出現頻度も重要 (よく使われる語ほど正解) • 複数語(文脈依存)のスペルミス修正はフレーズに対して出現頻度比較を行う • Soundex index 等でもスペルミスを補正できる