Skip to content

Latest commit

 

History

History
 
 

nearest-search

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
nearest-search.cl: (近似)最近傍探索 nearest-search

* nearest-search オブジェクト
input-data: 入力データ
input-key:  データから比較用のベクトルを取り出す関数. defaultは#'identity
distance:   2引数の距離関数 defaultは#'hjs.util.vector:euclid-distance

注意:一部のクラスに対してはdistanceは二つのdvecを取りdouble-floatを返す必要がある
naive以外の近傍点探索を用いる動機は高速化であると思われるので、この要求は自然と考えている
また、kd-treeに関してはアルゴリズム自体がカテゴリーデータには適用できない


* 標準メソッド
dataはinput-keyに渡される
make-instanceされた時点で自動的に初期化ステップが走るので、すぐ下記のメソッドが使える

- (find-nearest nearest-search data)
  dataに一番近い点と距離を返す

- (find-nearest-k nearest-search data k &optional result tmp-distances)
  dataからのk近傍点と距離の入った長さkのベクトルを返す
  (result,tmp-distances)は長さkの(vector,dvec)を与える(初期化は自動的に行われる.ゴミ抑制のため)

- (find-nearest-epsilon nearest-search data epsilon &optional result)
  dataから距離epsilon以内の点すべての入ったベクトルを返す(距離は返さない!)
  resultにはextend可能なvectorを与える(初期化は自動)

* 実装済み(近似)近傍点class hierarchy list
  葉にあたるclassでしか動作しない!

- nearest-search
-- exact-nearest-search  (厳密な近傍点探索)
--- naive-nearest-search (単に全データをチェックするnaiveな探索)
--- kd-tree-search       (kd-木: n次元空間を超矩形で分割する)
--- m-tree-search        (m-木:  n次元距離空間を超球体で分割する)
                追加引数 (:m 木の次数 :pivot rootのpivot(dvec)
                                  :priority-queue priority-queueの種類 default = :binomial (priority-queue.clを参照))
-- stochastic-nearest-search               (近似近傍点探索)
--- locality-sensitive-hashing             (LSH: 代表的な近似近傍点探索)
                                            追加引数 (:L hash長 :k hash数)
---- p-stable-locality-sensitive-hashing   (p安定分布族に対するLSH)
                                            追加引数 (:w 分母(double-float))
----- euclid-locality-sensitive-hashing    (euclid距離に対するgauss分布を使ったLSH)
----- manhattan-locality-sensitive-hashing (manhattan距離に対するcauchy分布を使ったLSH)
---- cosine-locality-sensitive-hashing     (cosine距離に対するLSH)

* Tips:
一般に、高次元データに対しては近似近傍点探索が強い
低次元、大量データにはnaive,m-treeが優秀
どれが最速かはオーバーヘッド次第

m-treeのmは大きいほど分割が大きくなり、幅が広い木となる
pivotは次元さえあってればなんでもいいが、性能を考えると距離空間の真ん中にあるとよい(全データの平均など)

LSHに対して距離関数を与えても(hash関数は距離関数に対して定義されるため)勝手に上書きされる
# errorを返すべき?

LSHはL,k,wの三つのパラメータで精度と速度のトレードオフを制御する
理論計算量はO(Lk)
# 実際にはO(L^2k)な気がする。実験するとそうなる by 藤井
wはhash-bitのon/offの閾値で、大きいほど発火点が下がる=一つのハッシュに入るデータ数が減る=誤検出が減ることが期待される
それぞれのパラメータの正確な意味は、元論文を参照していただきたい
Lはrecallを高めるパラメータ
kはprecisionを高めるパラメータ
と思えばよい

* Todo

m-tree,kd-treeは、実際にはpivot選択によって性能が大きく変化する
汎用的に性能が高いものを選んだつもりだが、別の実装を試す必要がある?

m-treeにおけるpriority-queueは検索時に使用するので、make-instance時ではなく、find-nearest-*の引数でもよいはず
&allow-other-keysとかを使ってそういうインターフェイスにすべきか否か

以下のものは性能が出ないのでバグとかチェック中です

- spectral-hashing (PCAを使ってハッシュ関数を設計する L-n距離用? :Lは次元数以下である必要がある)
- simhash          (cosine距離用:構築・探索に効率的なアルゴリズムを使えるはず)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

k-nn-new.cl: nearest-searchパッチ済k-nn

完全に別パッケージにパッチ済クローンをまるまる定義する
(カテゴリデータについて拡張されたk-nnの扱いが面倒だったので)
問題無ければ単にパッケージ名とファイルを置き換えるだけでよい

インターフェイスに対して追加引数nns-type,nns-argsを定義
nns-argsはlistでapplyの最後に渡るようになっている
naiveに対しては依然としてカテゴリデータを扱える(はず)
多少の引数チェックはしている

sample/eyes200.sexp(1680次元)に対して試すとLSHの威力がある程度分かるが、インスタンスが200程度なのでちょっと寂しい

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

optics-speed.cl: OPTICSに対するnearest-searchパッチ

必要な箇所だけOPTICSパッケージに追加定義する
optics-speedがインターフェイス

追加引数はk-nnと同じくnns-type,nns-args
フォーマットも同じ

参考文献:

kd-tree:
Songrit Maneewongvatana and David M. Mount, "It’s okay to be skinny, if your friends are fat", 4th Annual CGC Workshop on Computational Geometry, 1999 (Sliding-midpoint split)
(他の空間木データ構造へのポインタが豊富)

m-tree:
Paolo C., Marco P., Pavel Z.,"M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", Proceedings of the 23rd International Conference on Very Large Data Bases, 1997

LSH:
Datar M., Immorlica N., Indyk P., Mirrokni V S., "Locality-sensitive hashing scheme based on p-stable distributions, Proceedings of the twentieth annual symposium on Computational geometry", 2004
lsh p-stable: http://www.slideshare.net/JavaDM/lsh-pstable-1565961 (日本語)
http://d.hatena.ne.jp/n_shuyo/20100201/simhash (cosine-lsh, Lとkの簡単な説明)

spectral hashing:
Y. Weiss, A. Torralba, R. Fergus."Spectral Hashing", NIPS, 2008.

simHash:
Gurmeet Singh Manku ,Arvind Jain, and Anish Das Sarma. "Detecting near-duplicates for web crawling", Proceedings of the 16th international conference on World Wide Web, 2007.