近似最近邻搜索方法FLANN简介


AR/VR群244751474 ,欢迎加入,进行项目讨论!

-----------------------------------------------分割线---------------------------------------------

一、简介

我们可以用下面的方式定义最近邻搜索(NNS)问题:在一个度量空间X给定一组点P=p1,p2,…,pn,这些点必须通过以下方式进行预处理,给第一个新的查询点q属于X,快速在P中找到距离q最近的点,即最近邻搜索问题。


最近邻搜索的问题是在很多应用领域是一个重大问题,如图像识别、数据压缩、模式识别和分类、机器学习、文档检索系统、统计和数据分析等。然而,在高维空间中解决这个问题似乎是一个非常难以执行任务,没有算法明显优于标准的蛮力搜索。因此越来越多的人把兴趣点转向执行近似最近邻搜索的一类算法,这些方法在很多实际应用和大多数案例中被证明是足够好的近似,比精确搜索算法快很大的数量级。


FLANN(Fast Library for Approximate Nearest Neighbors)是一个执行快速近似最近邻搜索的库。FLANN使用C++写成。他能够很容易地通过C,MTALAB和Python等绑定提供的库,用在很多环境中。


二、使用FLANN

FLANN库的核心部分使用C++写成。为了最大性能和灵活性的使用模版代码,应该尽量使用C++绑定(C++ bindings)。你只要包含库的头文件flann.hpp就能使用C++bindings。


下面我们介绍几个公共C++ API。


1.flann::Index

这是FLANN最近邻指数类。该类用于抽象的不同类型的最近邻搜索索引。距离函子的类模板用于计算两个特征空间之间的距离。

namespace flann
 {
     template
     class Index
     {
         typedef typename Distance::ElementType ElementType;
         typedef typename Distance::ResultType DistanceType;
     public:
         Index(const IndexParams& params, Distance distance = Distance() );
         Index(const Matrix& points, const IndexParams& params,
                 Distance distance = Distance() );
         ~Index();
         void buildIndex();
         void buildIndex(const Matrix& points);
         void addPoints(const Matrix& points,
                        float rebuild_threshold = 2);
         void removePoint(size_t point_id);
         ElementType* getPoint(size_t point_id);
         int knnSearch(const Matrix& queries,
                        Matrix& indices,
                        Matrix& dists,
                        size_t knn,
                        const SearchParams& params);
         int knnSearch(const Matrix& queries,
                        std::vector< std::vector >& indices,
                        std::vector >& dists,
                        size_t knn,
                        const SearchParams& params);
         int radiusSearch(const Matrix& queries,
                          Matrix& indices,
                          Matrix& dists,
                          float radius,
                          const SearchParams& params);
         int radiusSearch(const Matrix& queries,
                           std::vector< std::vector >& indices,
                           std::vector >& dists,
                           float radius,
                           const SearchParams& params);
         void save(std::string filename);
         int veclen() const;
         int size() const;
         IndexParams getParameters() const;
         flann_algorithm_t getType() const;
}; }

其他API,大家可以通过FLANN手册查找,下载 http://download.csdn.net/detail/eric41050808/9133803 。此次仅介绍knnSearch方法:


2.flann::Index::knnSearch

对一组点查询点,该方法执行K最近邻搜索。该方法有两个实现,一个携带预开辟空间的flann::Matrix对象接收返回的找到邻居的索引号和到其距离;另一个是携带std::vector根据需要自动重新调整大小。

int Index::knnSearch(const Matrix& queries,
                Matrix& indices,
                Matrix& dists,
                size_t knn,
                const SearchParams& params);
int Index::knnSearch(const Matrix& queries,
                std::vector< std::vector >& indices,
                std::vector >& dists,
                size_t knn,
                const SearchParams& params); 

参数:

queries: 承载查询点的矩阵,矩阵大小是:查询点数*纬数;

indices: 将承载所有被找到的K最近邻的索引号( 预开辟的大小应该至少是查询点数*knn);

dists:     将承载到所有被找到的K最近邻的距离只(预开辟大小应该至少是查询点数*knn);

knn:       要找的最近邻的个数;

params: 搜索参数。承载搜索时要使用的参数的结构体,结构体类型是SearchParameters。

SearchParameters
      struct SearchParams
      {
          SearchParams(int checks = 32,
                       float eps = 0,
                       bool sorted = true);
          int checks;
          float eps;
          bool sorted;
          int max_neighbors;
          tri_type use_heap;
          int cores;
          bool matrices_in_gpu_ram;
      };


其中,checks: 当搜索邻居时用来制定叶子数的最大值。其值越大,搜索精度越高,但是也会消耗更多时间。如果要检索所有叶子,使用宏值CHECKS UNLIMITED。如果在对象index创建时使用自动配置,达到指定精度的需要的检索次数也会被计算出来,这是使用宏值CHECKS_AUTOTUNED。

你可能感兴趣的:(knn,flann,机器学习,机器学习)