[メモ] Prioritized DCIのアルゴリズム

arxiv.org

ICLR2017

上記論文で提案されている効率的なk-nn手法、Prioritized DCIについてのメモ。

同じ著者らが提案したDynamic Continuous Indexing(DCI)の改良手法になる。

あくまでアルゴリズムを理解したかっただけなので理論保証や証明等は省く。
また理解が間違っているかもしれないのであしからず。

データ構造の構築

データ構造は mL個のバイナリツリー \{ T_{jl} \}_{j \in [m], l \in [L]}
 m Lは適当なインデックス。速度や性能に影響する。
 nは学習データの数。
またランダム射影をするための単位ベクトル集合 \{u_{jl}\}_{j \in [m], l \in [L]}も用意。

アルゴリズム

  • 事前に学習データを次元削減のため適当な方法(例えばNNとかで) \mathbb R^dに射影しておく
  • 各学習データポイントについて  u_{jl}内積をとる
  • その値をkey、学習サンプルとしてのインデックスをvalueとして対応するバイナリツリー T_{jl}に追加する

これにより n個のサンプルが追加されたバイナリツリーが mL個構築される。


クエリの検索

現在 L個のバイナリツリー集合が m個ある。
この L個のバイナリツリー集合からそれぞれ k_0個の候補点を抽出する。
結果的に(重複含む) Lk_0個の候補点が得られるのでここから近傍点を k個探索しそれを返す。

用意として L \times nの2次元配列 C L個の優先度付きキュー P_lをそれぞれ用意する。
またあらかじめクエリを \mathbb R^dに射影しておく。

 l \in L番目の優先度付きキュー P_lは、対応する T_l m個のバイナリツリーそれぞれから1つずつ最も距離の近いサンプルを取り出し、クエリとの差分の絶対値のマイナスを優先度として追加し初期化する。
つまり各 P_lには m個のデータが入っていて、距離の近い順に取り出せる状態になる。

ここから探索。
ある l \in Lについて。
 l番目の集合からの候補点が k_0に満たない場合に

  •  P_lから候補点 pを取り出し、対応する学習データのインデックス hから C_lの対応するインデックスのカウントを+1する(C[l][h] += 1のイメージ)。
  • もしカウントが mになったなら(C[l][h] == m)それを l番目の集合の候補点として追加する。
  • 今回のサンプルを選択したバイナリツリーから次に近い点を探索し、同じように P_lに追加する

上記を k_1回繰り返す。

所感

結構計算が多いように感じるけど内積とってスカラ値にするからそんなにきつくはないのかな?
実際に大規模データで試したわけじゃないのでどれくらいの速度なのかちょっとわからない。
ランダム単位ベクトルが唯一の確率的な要素かな?
 k_1のサイズは少々気になる。 k_1 \geq mの制約はありそう?