20.推荐召回算法之k近邻算法:局部敏感哈希、kdtree、balltree算法分析与比较

推荐系统里面临的比较大的问题是1.召回 2.排序。召回是从百万、千万甚至上亿的候选中找到用户可能喜欢的商品(可以不那么精细),排序一般是设计怎样排序才能使点击率更高。

考虑一个新闻推荐场景,假设一个用户曾经看过美妆、育儿、明星类的新闻,怎样在ta下一刷中把用户可能感兴趣的找到并推给用户呢?

比较简单的做法是,将每条新闻分一个类(如体育、美妆、育儿、八卦、明星、电影),根据分类将候选召回再排序。

比较复杂一点的做法是,通过用户看过的新闻得到一个embedding向量,然后根据这个向量去做召回,局部敏感哈希、kdtree、balltree算法就用在这里,下面会逐一介绍。

1.局部敏感哈希(Locality Sensitive Hashing,LSH):总体思想就是降低维度,同时保留向量在空间上的相似度(就是两个距离很近的向量,LSH之后也不会很远)

                                                                       

                                                               局部敏感哈希示意图(from: Piotr Indyk)

2.kdtree

k-d树是每个节点都为k维点的二叉树。所有非叶子节点可以视作用一个超平面把空间分割成两个半空间。节点左边的子树代表在超平面左边的点,节点右边的子树代表在超平面右边的点。选择超平面的方法如下:每个节点都与k维中垂直于超平面的那一维有关。因此,如果选择按照x轴划分,所有x值小于指定值的节点都会出现在左子树,所有x值大于指定值的节点都会出现在右子树。这样,超平面可以用该x值来确定,其法线为x轴的单位向量。

创建:

有很多种方法可以选择轴垂直分割面( axis-aligned splitting planes ),所以有很多种创建k-d树的方法。 最典型的方法如下:

  • 随着树的深度轮流选择轴当作分割面。(例如:在三维空间中根节点是 x 轴垂直分割面,其子节点皆为 y 轴垂直分割面,其孙节点皆为 z 轴垂直分割面,其曾孙节点则皆为 x 轴垂直分割面,依此类推。)
  • 点由垂直分割面之轴座标的中位数区分并放入子树

这个方法产生一个平衡的k-d树。每个叶节点的高度都十分接近。然而,平衡的树不一定对每个应用都是最佳的。

kd树在20维以内最佳,对高维不友好

3.ball-tree(转自知乎)

为了解决kdtree在高维上效率低下的问题,因此引入了ball-tree。

KD树在搜索路径优化时使用的是两点之间的距离来判断,而球树使用的是两边之和与第三边大小来判断,即 。

以下图为例搜索点 的半径为 内的最近邻,即满足 :

1. 从根节点 开始从上至下递归遍历每个可能包含最终近邻的子空间 。

2. 如果子空间的半径 与 之和小于 中心点 到目标点 的距离,即 ,接着在满足这样条件的子空间样本点内递归搜索满足 的点就是我们想要的最近邻点了。换句简单的话来说,对于目标空间 ,所有被该超球体截断的子超球体内的所有子空间都将被遍历搜索。

3. 由于子超球体 与 被 所截,而对于 与 内的子空间, 又被 所截,所以接下来就会在 内进行线性搜索。诸如 这些距离太远的子空间将被舍去。最后 就是最终得到的最近邻。

20.推荐召回算法之k近邻算法:局部敏感哈希、kdtree、balltree算法分析与比较_第1张图片

参考文献:

Mohamad Dolatshah, Ali Hadian, Behrouz Minaei-Bidgoli, "Ball*-tree: Efficient spatial indexing for constrained nearest-neighbor search in metric spaces", ArXiv e-prints, Nov 2015.


 

你可能感兴趣的:(推荐算法)