[メモ] Prioritized DCIのアルゴリズム
ICLR2017
上記論文で提案されている効率的なk-nn手法、Prioritized DCIについてのメモ。
同じ著者らが提案したDynamic Continuous Indexing(DCI)の改良手法になる。
あくまでアルゴリズムを理解したかっただけなので理論保証や証明等は省く。
また理解が間違っているかもしれないのであしからず。
データ構造の構築
データ構造は個のバイナリツリー
。
と
は適当なインデックス。速度や性能に影響する。
は学習データの数。
またランダム射影をするための単位ベクトル集合も用意。
- 事前に学習データを次元削減のため適当な方法(例えばNNとかで)
に射影しておく
- 各学習データポイントについて
で内積をとる
- その値をkey、学習サンプルとしてのインデックスをvalueとして対応するバイナリツリー
に追加する
これにより個のサンプルが追加されたバイナリツリーが
個構築される。

クエリの検索
現在個のバイナリツリー集合が
個ある。
この個のバイナリツリー集合からそれぞれ
個の候補点を抽出する。
結果的に(重複含む)個の候補点が得られるのでここから近傍点を
個探索しそれを返す。
用意としての2次元配列
、
個の優先度付きキュー
をそれぞれ用意する。
またあらかじめクエリをに射影しておく。
番目の優先度付きキュー
は、対応する
の
個のバイナリツリーそれぞれから1つずつ最も距離の近いサンプルを取り出し、クエリとの差分の絶対値のマイナスを優先度として追加し初期化する。
つまり各には
個のデータが入っていて、距離の近い順に取り出せる状態になる。
ここから探索。
あるについて。
番目の集合からの候補点が
に満たない場合に
から候補点
を取り出し、対応する学習データのインデックス
から
の対応するインデックスのカウントを+1する(C[l][h] += 1のイメージ)。
- もしカウントが
になったなら(C[l][h] == m)それを
番目の集合の候補点として追加する。
- 今回のサンプルを選択したバイナリツリーから次に近い点を探索し、同じように
に追加する
上記を回繰り返す。

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