KD树和LSH局部敏感哈希
- 文档结构
- 文档表示
- 距离度量
- KD树
- 原理
- 构建
- 查询
- 复杂度
- KD树的KNN
- KD树的逼近KNN
- 不适用高维数据
- 原理
- LSH
- LSH潜在的问题
- LSH算法
- 复杂度
- 概率逼近
- 多表
文档结构
文档表示
- 词袋模型:有一些词,比如“的”,“吧”出现的频率很高,但是这些词意义不大。
- tf-idf:在该文档局部出现的频率高,在全部文档全局出现的频率低。
距离度量
常见的距离度量有:
- 欧氏距离:d=∑Kk=1(x1k−x2k)2−−−−−−−−−−−−−−√d=\sqrt{\sum_{k=1}^K(x_{1k}-x_{2k})^2}
- 曼哈顿距离:d=∑Kk=1|x1k−x2k|d=\sum_{k=1}^K|x_{1k}-x_{2k}|
- 切比雪夫距离:d=maxk|x1k−x2k|d=\max_k |x_{1k}-x_{2k}|
- 汉明距离:两个等长的字符串将一个变成另外一个所需的最小替换数
- 余弦相似性:d=1−x1⋅x2|x1||x2|d = 1-\frac{x_1 \cdot x_2 }{|x_1| |x_2|}
- 内积:d=x1⋅x2d = x_1 \cdot x_2
- 核函数:d=K(x1,x2)d = K(x_1,x_2)
- 相关系数:d=Cov(x1,x2)σx1σx2d = \frac{Cov(x_1,x_2)}{\sigma_{x_1}\sigma_{x_2}}
不同的特征分布范围不同,对于变化范围很大的特征计算距离的时候要乘以相对较小的系数,对于变化范围小的特征计算距离的时候要乘以相对较大的系数。否则距离就会被变化范围较大的特征统治。另一种做法是先对源数据做归一化。
一般的欧式距离如下:
d(x,y) =|| (x-y)^T(x-y) ||
考虑权重后的欧式距离如下,AA是对角阵,对角线上的元素代表该特征上的距离乘数:
d(x,y) =|| (x-y)^TA(x-y) ||
对于余弦相似性,需要注意几点:
- 不是合适的距离度量,不符合三角不等式(两边之和大于第三边)
- 计算稀疏向量的内积很有效率
对于是否需要scale向量,需要考虑下面几点:
- 如果不scale的话,那么对同样的两篇文章,重复其内容会导致相似性变大,这与常理不符合。
- scale的话,会忽视文章的长度,比如一篇科技论文的相似性和一篇微博的相似性会很高,但是建议阅读科技论文的读者去阅读微博是不大符合常理的。
- 通常的做法是,cap maximum word counts,也就是设置最大的单词数
- 以文档为例,对于文档的内容可以scale以忽略文档长度的影响,对于文档的读者数不可以scale因为它是具有切实意义的特征。
KD树
brute-force搜索的KNN复杂度太高,单次1NN的复杂度是O(N)O(N),单次KNN的复杂度是O(NlogK)O(N\log K )。如果N很大,查询次数很多的话,那么效率很低。
原理
KD树通过不断划分样本到不同的子空间,构建二叉树的结构,通过剪枝实现了效率更高的查询,在低维空间表现较好。
构建
- 确定split特征(更宽更广的特征;alternating)
- 确定split的特征值(median;center point of box)
- split数据到两部分
- 对分支的数据递归构建KD树直到到达停止条件(min leaf nodes; min box width)
每个node上需要记录以下信息:
- split的特征
- split的特征值
- 该node以下包含的节点区域
查询
- 由根节点从上到下找到对应包含查询点的叶节点
- 计算该区域内的点到查询点的最小距离
- 回溯(backtrack)其他分支,如果该分支区域与到查询点最小距离构成的圆相交,那么进一步深入该区域查询;如果不相交,那么对该分支剪枝继续回溯,直到到达根节点。
复杂度
- 构建的复杂度:O(NlogN)O(N\log N)
- 单次查询的复杂度:O(logN)→O(N)O(\log N) \rightarrow O(N),复杂度与维度是指数关系。
KD树的KNN
保留距离的时候,只需要把1NN中的离查询点最小的距离改成离查询点最小的第K个距离即可。
KD树的逼近KNN
实际计算的时候,假设已获得的离查询点最近的距离是rr,那么剪枝的标准由d>rd>r变成d>r/α(α>1)d>r/\alpha(\alpha>1),相当于更容易剪枝。
这样做,虽然可能找不到最近的NN,但是可以保证一旦我们找到的NN距离是rr,那么没有其他点的距离小于r/αr/\alpha。实际中,我们定义的向量表示、距离度量都不一定是百分百地反映其本质的,所以逼近KNN通常可以取得很好的结果,关键更容易剪枝,实现了更高的查询效率。
不适用高维数据
- 查询的复杂度随维度上升指数增长,通常要求N>>2dN>>2^d。
- 距离对不相关的特征很敏感,高维空间中每个点都分离很远,最短距离构成的圆和很多点都相交。
- 需要特征选择,判断哪个特征更优。
LSH
KD树实现检索有以下缺点:
- 实现起来没那么有效
- 复杂度随特征维度指数增加,不适合高维情况
- 高维情况下,一旦发现了最近的点,那么以到最近的点距离为半径的超球体几乎与大多超多面体相交,导致剪枝效率不高。
LSH通过建立hash表,将数据分散到不同的部分,检索的时候只需要检索hash到的那部分的点即可。该方法提供了大概率上发现NN的方法。进一步提高NN概率的方向有两个:在当前hash表内,不仅检索当前的部分还检索周围的部分;建立多个hash表。
如下图所示,根据点在直线上下进行hash,将数据分为两部分,检索的时候只需要检索对应hash后的那部分的数据即可。
LSH潜在的问题
LSH潜在的问题如下:
- 怎么找到好的直线(好的hash函数)
- 最坏的情况怎么样
- hash后的部分可能包含很多点,这样进一步检索的复杂度仍然很大
针对第一个问题,随机划分即可。在随机划分下,针对第二个问题,用一条直线划分,最坏情况的概率是θπ\frac{\theta}{\pi}。θ\theta代表NN点距离样本点的夹角。
针对第三个问题,那我多用几条直线划分,每个bin中的点就小了。
如果想进一步提高精度的话,在计算能力范围内在bin的周围多检索几个bin就可以了。
LSH算法
复杂度
LSH构建hash表的复杂度为:hash表的个数*超平面的个数*数据的维度*训练数据
LSH构建hash表后检索的复杂度为:hash表的个数*表中检索bin的个数*每个bin的数据
概率逼近
多表
如果检测三个bin,有两种方法:
- 建立一个表,找到检索点对应的bin后,在其周围找到两个bin。
- 建立三个表, 每个表各找一个bin。
一般来说,当hash表中的直线(位数)越多时,第二种方法概率保证上效果更好,缺点是需要计算多个表,计算复杂度比较高。
实际中,我们一般固定bits的位数(一个hash表中划分超平面的个数,然后增大hash表的个数。
KD树和LSH局部敏感哈希相关推荐
- LSH(局部敏感哈希算法)实现文本的相似性比对
源码见github:https://github.com/smallsmallcase/lsHash 和LSH算法类似,朴素贝叶斯算法也能实现相近的分类功能,朴素贝叶斯算法给新浪新闻分类的代码见:ht ...
- minHash(最小哈希)和LSH(局部敏感哈希)
在数据挖掘中,有一个比较基本的问题,就是比较两个集合的相似度.关于这个问题,最笨的方法就是用一个两重循环来遍历这两个集合中的所有元素,进而统计这两个集合中相同元素的个数.但是,当这两个集合里的元素数量 ...
- R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 私认为,文本的相似性可以分为两类:一类是机械相 ...
- 最近邻和K近邻及其优化算法LSH(局部敏感哈希,Locality Sensitive Hashing) Kd-Tree
引言 在处理大量高维数据时,如何快速地找到最相似的数据是一个比较难的问题.如果是低维的小量数据,线性查找(Linear Search)就可以解决,但面对海量的高维数据集如果采用线性查找将会非常耗时.因 ...
- 局部敏感哈希(LSH)
一. 近邻搜索 局部敏感哈希,英文locality-sensetive hashing,常简称为LSH.局部敏感哈希在部分中文文献中也会被称做位置敏感哈希.LSH是一种哈希算法,最早在1998年由In ...
- 【时序】Reformer:局部敏感哈希(LSH)实现高效 Transformer 论文笔记
论文名称:Reformer: The Efficient Transformer 论文下载:https://arxiv.org/abs/2001.04451 论文年份:ICLR2020 论文被引:70 ...
- 【期外】 (一)关于LSH :局部敏感哈希算法
LSH是我同学的名字,平时我会亲切的称呼他为离骚,老师好,左移(leftshift),小骚骚之类的,最近他又多了一个新的外号:局部敏感哈希(Locally sensitive hashing). 好了 ...
- LSH系列1:局部敏感哈希(LSH)——基本原理介绍
文章目录 参考 局部敏感哈希(LSH)基本原理介绍 背景 LSH 的基本思想 LSH 的哈希函数族(Hash Family) LSH 的查找过程 LSH 常见的 Hash Function 参考 LS ...
- 在茫茫人海中发现相似的你——局部敏感哈希(LSH)
一.引入 在做微博文本挖掘的时候,会发现很多微博是高度相似的,因为大量的微博都是转发其他人的微博,并且没有添加评论,导致很多数据是重复或者高度相似的.这给我们进行数据处理带来很大的困扰,我们得想办法把 ...
最新文章
- html滑动逐渐覆盖效果,创意jQuery和CSS3滑动覆盖响应式幻灯片特效
- table表格固定前几列,其余的滚动
- 计算图像相似度——《Python也可以》之一(转)
- 解决Ubuntu16.04虚拟机窗口全屏问题
- 周末狂欢赛1(玩游戏/Game,函数,JOIOI王国)
- bs架构 erp 进销存_从应用架构看生鲜电商信息化建设
- Symantec(赛门铁克)非受管检测
- arduino 上传项目出错_Arduino多核编程:简单例子
- WPF DataGrid 对行中单元格的访问
- 基于Spring开发的一个BIO-RPC框架(对小白很友好)
- All In One For Firefox 3
- VMware Fusion Pro v10.1.6 苹果虚拟机免费版及解锁许可证
- c语言调用树莓派usb摄像头,树莓派接多个USB摄像头,使用opencv打开指定的某一个摄像头...
- 2017第八届CSTQB国际软件测试高峰论坛圆满召开
- argument 1 must be str, not PosixPath
- 无限法则服务器维护中,维护内容
- python代码错误有哪些_Python常见十六个错误集合,你知道那些?
- MFC中画出圆形按钮,告别方形普通按钮
- Muti-Scale Resnet论文初步复现
- 塑造公司管理方式(三)- 沟通、创新、未来