两种使用局部敏感哈希查找最近邻居的算法,哪一种?

2024-01-21

目前我正在研究如何使用局部敏感哈希来查找最近邻居。然而,当我阅读论文和搜索网络时,我发现了两种执行此操作的算法:

1-使用L个哈希表和L个随机LSH函数,从而增加两个相似文档获得相同签名的机会。例如,如果两个文档的相似度为 80%,那么它们有 80% 的机会从一个 LSH 函数获得相同的签名。但是,如果我们使用多个 LSH 函数,则从其中一个 LSH 函数获得文档相同签名的机会就更高。这种方法在维基百科中有解释,我希望我的理解是正确的:

http://en.wikipedia.org/wiki/Locality-sensitive_hashing#LSH_algorithm_for_nearest_neighbor_search http://en.wikipedia.org/wiki/Locality-sensitive_hashing#LSH_algorithm_for_nearest_neighbor_search

2-另一种算法使用来自 Moses S. Charikar 的论文(第 5 节)中的方法,该论文名为:来自舍入算法的相似性估计技术。它基于使用一个 LSH 函数生成签名,然后对其应用 P 排列,然后对列表进行排序。其实我不太明白这个方法,希望有人能澄清一下。

我的主要问题是:为什么有人会使用第二种方法而不是第一种方法?我发现它更容易、更快。

我真的希望有人能帮忙!!!

编辑: 实际上我不确定@Raff.Edward 是否混合了“第一”和“第二”。因为只有第二种方法使用半径,而第一种方法只是使用由哈希族 F 组成的新哈希族 g。请检查维基百科链接。他们只是使用许多 g 函数来生成不同的签名,然后对于每个 g 函数都有一个相应的哈希表。为了找到一个点的最近邻居,您只需让该点通过 g 函数并检查相应的哈希表是否有冲突。因此,我将其理解为更多的功能……更多的碰撞机会。

我没有发现任何关于第一种方法的半径的提及。

对于第二种方法,他们只为每个特征向量生成一个签名,然后对其应用 P 排列。现在我们有 P 个排列列表,其中每个排列包含 n 个签名。现在,他们对 P 中的每个列表进行排序。在给定查询点 q 后,他们为其生成签名,然后对其应用 P 排列,然后对每个排列和排序的 P 列表使用二分搜索来查找最相似的签名查询 q。我在阅读了很多有关它的论文后得出了这个结论,但我仍然不明白为什么有人会使用这种方法,因为它在找到汉明距离方面似乎并不快!!!!

对我来说,我只需执行以下操作即可找到查询点 q 的最近邻居。给定一个签名列表 N,我将为查询点 q 生成签名,然后扫描列表 N 并计算 N 中每个元素与 q 签名之间的汉明距离。因此我最终会得到 q 的最近邻居。而且需要 O(N)!!!


你对第一个的理解有点偏差。碰撞发生的概率与相似度不成正比,而与是否小于预先定义的半径成正比。目标是半径内的任何物体都有很高的几率发生碰撞,半径 * (1+eps) 之外的任何物体发生碰撞的几率都很低(并且中间的区域有点模糊)。

第一种算法实际上很难实现,但是可以得到很好的结果。特别是,第一个算法适用于 L1 和 L2(以及技术上的更多)指标。

第二种算法实现起来非常简单,但根据问题的大小,简单的实现可能会占用太多内存而无法发挥作用。在这种情况下,碰撞概率与输入的相似度成正比。但是,它仅适用于余弦相似度(或基于相似度变换的距离度量。)

因此,您将使用哪一个主要取决于您为最近邻居(或任何其他应用程序)使用的距离度量。

第二个实际上比第一个更容易理解和实现,只是论文非常罗嗦。

简短版本:取一个随机向量 V 并为每个索引赋予一个独立的随机单位正态值。根据签名长度创建任意数量的向量。签名就是做矩阵向量乘积时每个索引的符号。现在,任意两个签名之间的汉明距离与各个数据点之间的余弦相似度相关。

因为您可以将签名编码为 int 数组,并使用带有位计数指令的 XOR 来非常快速地获取汉明距离,所以您可以非常快速地获得近似余弦相似度分数。

LSH 算法没有太多标准化,而且两篇论文(以及其他论文)使用不同的定义,因此有时会有点令人困惑。我最近才实现了这两种算法JSAT https://code.google.com/p/java-statistical-analysis-tool/,并且仍在努力充分理解它们。

编辑:回复您的编辑。维基百科的文章对 LSH 来说不太好。如果您阅读了原纸 http://people.csail.mit.edu/indyk/nips-nn.ps,您所说的第一种方法仅适用于固定半径。然后根据该半径创建哈希函数,并将其连接起来以增加碰撞中接近点的概率。然后,他们构建了一个系统,通过确定他们想要的 k 的最大值,然后找到最大的值,在此基础上进行 k-NN合理的他们找到第 k 个最近邻的距离。这样,半径搜索很可能会返回 k-NN 集合。为了加快速度,他们还创建了一些额外的小半径,因为密度通常不均匀,并且使用的半径越小,结果越快。

您链接的维基百科部分取自“稳定分布”部分的论文描述,该部分提供了搜索半径 r=1 的哈希函数。

对于第二篇论文,您描述的“排序”不是散列的一部分,而是更快地搜索汉明空间的单一方案的一部分。正如我所提到的,我最近实现了这个,你可以看到快速基准 I http://jsatml.blogspot.com/2013/06/cosine-similarity-locality-sensitive.html使用暴力搜索确实比朴素的神经网络方法快得多。同样,如果您需要 L2 或 L1 距离上的余弦相似度,您也可以选择此方法。您会发现许多其他论文提出了不同的方案来搜索签名创建的汉明空间。

如果您需要帮助来说服自己,即使您仍在使用蛮力,拟合也会更快 - 只需这样看:假设平均稀疏文档与另一个文档有 40 个常见单词(根据我的经验,这是一个非常保守的数字)。您有 n 个文档可供比较。强力余弦相似度将涉及大约 40*n 浮点乘法(以及一些额外的工作)。如果您有 1024 位签名,则只有 32 个整数。这意味着我们可以在 32*n 整数运算中进行强力 LSH 搜索,这比浮点运算快得多。

这里还有其他因素在起作用。对于稀疏数据集,我们必须保留双精度和整数索引来表示非零索引,因此稀疏点积会执行大量额外的整数运算来查看它们有哪些共同索引。 LSH 还允许我们节省内存,因为我们不需要为每个向量存储所有这些整数和双精度数,相反我们可以只保留它的散列 - 这只有几个字节。 减少内存使用可以帮助我们更好地利用CPU缓存。

你的 O(n) 是我在博客文章中使用的天真的方式。而且速度很快。但是,如果您事先对位进行排序,则可以在 O(log(n)) 中进行二分搜索。即使你有 L 个这样的列表,L

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两种使用局部敏感哈希查找最近邻居的算法,哪一种? 的相关文章

  • 具有最小刻度的图表的漂亮标签算法

    我需要手动计算图表的刻度标签和刻度范围 我知道漂亮刻度的 标准 算法 参见 我也知道这个Java实现 http erison blogspot nl 2011 07 algorithm for optimal scaling on char
  • 沿着长数据序列在固定大小的移动窗口中查找中值

    给定一个数据序列 可能有重复项 一个固定大小的移动 窗口 从数据开始处每次迭代时移动窗口 序列 使得 1 从窗口中删除最旧的数据元素并添加新数据 元素被推入窗口 2 求每次移动时窗口内数据的中位数 以下帖子没有帮助 有效地找到随机序列的中值
  • 竞争性编码 - 以最低成本清除所有级别:未通过所有测试用例

    当我遇到这个问题时 我正在一个竞争性编码网站上解决问题 问题指出 游戏中有 N 个关卡和 M 种可用武器 等级编号从 0 到 N 1 武器编号从 0 到 M 1 您可以按任意顺序清除这些级别 在每个关卡中 需要这些 M 武器的某些子集才能通
  • 哪种算法可以有效地找到路径一定距离内的一组点?

    给定一组点s 一组 x y 坐标 和由连接一组点的线段组成的路径l 描述一种有效的算法 可用于从s在指定距离内d路径的l 其实际应用可能是查找沿城市之间的公路旅行路径 10 英里内任意位置的餐馆列表 For example in the f
  • 从数字列表中生成所有唯一对,n 选择 2

    我有一个元素列表 假设是整数 我需要进行所有可能的两对比较 我的方法是 O n 2 我想知道是否有更快的方法 这是我在java中的实现 public class Pair public int x y public Pair int x i
  • 如何发现“贪婪”算法?

    我正在读一本关于 贪婪 算法 但我很难发现它们解决真正的 顶级程序员 问题 If I know给定的问题可以用 贪婪 算法来解决 因此编写解决方案非常容易 然而 如果我没有被告知这个问题是 贪婪的 我就无法发现它 用 贪婪 算法解决的问题有
  • 为什么对本地列表求和比用“GHC -O2”对教会编码列表求和慢?

    为了测试教会编码的列表如何针对用户定义的列表和本机列表执行 我准备了 3 个基准测试 用户定义的列表 data List a Cons a List a Nil deriving Show lenumTil n go n Nil where
  • 如何改进 PHP 分页算法?

    我正在研究 PHP 中的分页算法 我可以猜测它需要改进的空间 所以我想对如何改进它有一些想法 无论是从 UI UX 的角度清理代码本身 还是你能想到的任何其他东西 该算法应输出如下所示的分页 1 2 3 6 7 8 97 98 99 or
  • Keras 错误:预计会看到 1 个数组

    当我尝试在 keras 中训练 MLP 模型时出现以下错误 我使用的是 keras 版本1 2 2 检查模型输入时出错 您输入的 Numpy 数组列表 传递给您的模型的尺寸不是模型预期的尺寸 预期的 查看 1 个数组 但得到以下 12859
  • 如何跨多个文本文件查找字典中键的频率?

    我应该计算文档 individual articles 中所有文件中字典 d 的所有键值的频率 这里 文档 individual articles 大约有20000个txt文件 文件名为1 2 3 4 例如 假设 d Britain 5 7
  • 使用 glmnet 纠正 n 个数据集上的 n 个 LASSO 回归的输出(严格来说是所选的特征/变量)

    注意 这是对上一个问题 https stackoverflow com questions 75006466 how to replicate my results from running n lassos iteratively usi
  • 循环中的递归算法复杂度(运行时间)

    我想了解您对如何检测以下递归算法的 T n 运行时间 的意见 Charm 是一种用于发现事务数据库中频繁闭项集的算法 频繁闭项集列表是在一组交易 tids 中多次出现的频繁项 例如面包和牛奶是经常一起购买的物品 它们是通过将索引为 i 的当
  • 查找重叠间隔序列中最大和的算法

    我试图解决的问题在数轴上有一个间隔列表 每个间隔都有一个预定义的分数 我需要返回最大可能的总分 问题是间隔重叠 并且重叠间隔中我只能使用一个 这是一个例子 Intervals Score 0 5 15 4 9 18 10 15 12 8 2
  • 对产品列表进行分类的算法? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个代表或多或少相同的产品的列表 例如 在下面的列表中 它们都是希捷硬盘 希捷硬盘 500Go 适用于笔记本电脑的希捷硬盘 120
  • 为什么各个树的 xgboost 回归预测存在差异?

    首先 我运行一个非常简单的 xgb 回归模型 其中仅包含 2 棵树 每棵树有 1 个叶子 可用数据here https raw githubusercontent com jbrownlee Datasets master pima ind
  • Python求矩阵动态规划中最大的平方

    我有一个矩阵如下 Python matrix o o o oo o o o ooo o o oo o o oo 其中 o 是一个障碍 我需要找到这个矩阵中最大的正方形 并替换相应的 带有 x 如下所示 xxxo o o xxxoo xxxo
  • 归并排序究竟进行了多少次比较?

    我读到 在实践中 快速排序比合并排序快得多 其原因是隐藏常量 那么 随机快速排序复杂度的解是2nlnn 1 39nlogn 这意味着快速排序中的常数是1 39 但是合并排序呢 归并排序中的常数是什么 让我们看看能否解决这个问题 在合并排序中
  • 使用按键重新排列字符串

    我想使用Pythonrandomly根据给定的键重新排列字符串的各个部分 我还想用相同的密钥恢复原始字符串 def rearrange key data pass def restore key rearranged data pass 效
  • 算法挑战:从图像生成配色方案

    背景 因此 我正在开发一个网络应用程序的新版本 而且 我们发现我们的用户非常懒惰 实在是太懒了 事实上 我们为他们做的工作越多 他们就越喜欢这项服务 现有应用程序的一部分要求用户选择要使用的配色方案 但是 我们有一张图片 用户网站的截图 为
  • 在哪里可以找到产生无标头输出的无损压缩算法?

    你们中有人知道产生无标头输出的无损压缩算法吗 例如不存储用于压缩的哈夫曼树吗 我不是谈论硬编码的霍夫曼树 但我想知道是否有任何算法可以压缩和解压缩输入而不在其输出中存储一些元数据 或者这在理论上是不可能的吗 当然是可能的 其中 LZ 系列压

随机推荐

  • 生成 M 个箱中 N 个球的所有排列

    我想生成一组排列n球进m垃圾箱 以下一组嵌套列表生成这些排列 n lt 3 m lt 4 v lt rep 0 m for i in n 0 for j in n sum i 0 for k in n sum i j 0 for l in
  • 敲除 javascript foreach 绑定

    我试图允许用户创建一个铸造并向该铸造对象添加一组类别 我试图使用淘汰赛的 foreach 绑定到类别数组 并让用户向铸造添加新类别 我创建了一个 jsfiddle 来说明我在这里试图解释的内容 http jsfiddle net msell
  • Ruby 中的大指数?

    我只是在做一些与大学相关的 Diffie Hellman 练习 并尝试使用 ruby 遗憾的是 Ruby 似乎无法处理大指数 警告 在 a b 中 b 可能太大 NaN 有什么办法解决吗 例如 特殊的数学课或类似的课程 附注这是有问题的代码
  • 获取 Azure 队列中的消息 ID

    有没有办法在将消息插入队列Azure后获取消息ID CloudStorageAccount storageAccount CloudStorageAccount parse storageConnectionString CloudQueu
  • 我可以克隆未来吗?

    我想为未来编写一些通用的重试逻辑 我知道具体的返回类型 并且想在未来重试相同的操作 我的代码只能访问未来 我不想将每个 fn 调用站点包装在闭包中以启用重新创建它 似乎 未来 是 fn args 的组合 并且当 await被调用后 它会运行
  • 如何解决“无法读取 null 的属性‘appendChild’”错误?

    我尝试使用下面的代码 它在我的网站上的幻灯片中添加按钮 window onload function loadContIcons var elem document createElement img elem src http arno
  • Django 模板看不到 CSS 文件

    我正在构建一个 django 应用程序 但无法获取模板来查看 CSS 文件 我的 settings py 文件如下所示 MEDIA ROOT os path join os path abspath os path dirname file
  • Spring Boot未加载application.dev.properties文件

    在我的项目中 我想使用环境特定的属性文件 例如 如果我将其运行到开发中 它应该使用 application dev properties 对于生产它应该使用 application prod properties 等等 我的资源文件夹中有以
  • 当内容较长时,itextsharp 不会创建新页面

    我尝试从 3 天开始寻找制作一份 pdf 文档的方法 如果有任何帮助 我将不胜感激 我有几个表单字段可以毫无问题地访问和填写 我想在此字段下方放置动态创建的表 该表可以足够长 可以包含多个页面 这是我的问题 我无法将此表添加到其下方带有表单
  • 使用上次响应中的数据预填写 Google 表单

    我正在构建一个 Google 表单 我是唯一使用的表单 我每天使用该表单两次 或多或少 我希望某些字段预先填写我上次给出的响应值 因为它们的值不会经常更改 我将我的回复保存在 Google 电子表格中 以便可以从那里获取它们 但我对 Goo
  • 渲染多对多字段

    我试图在模板中显示多个字段 但我得到的只是空白 我将其显示如下 for vehicle in vehicle features features li vehicle features li endfor 我的模型如下 class Vehi
  • 如何使用最新版本的 FFMPEG 在视频录制中创建时间间隙?

    我是论坛的新手 所以我希望我正确地提出了这个问题 我已经下载了最新版本的 FFMPEG 我想用它通过在其中插入时间间隙来修改现有视频 这就是我所说的时间间隔 如果我输入的视频持续 2 秒并以 FPS 10 录制 则其帧的时间戳将如下 0 1
  • 删除 apk 后,每当我启动调试时,它都会告诉我该包尚未安装

    我打开了模拟器 并使用命令提示符删除了我的应用程序 我没有关闭模拟器 然后我进入 Eclipse 并点击 调试 但没有将 apk 部署到模拟器 只是告诉我该包尚未在系统中注册 New package not yet registered w
  • gtk2hs:删除小部件后请求重新计算窗口大小

    我有一个带有三个条目小部件和一个按钮的窗口 我使用该按钮以编程方式删除其中一个小部件 问题是主窗口在被删除后不会改变其大小以适应新的布局 我可以想象我需要向主循环发送一些信号或事件 这会导致重新计算 但我一直无法找到这样的功能 这是一些示例
  • Django的bulk_create函数示例

    我试图理解 Django 中的bulk create 这是我试图转换的原始查询 for e in q msg Message objects create recipient number e mobile content batch co
  • 如何更改 TreeView 节点高度,在节点中绘制 3 条线

    我将 D7 与 TreeView 不是 VirtualTreeView 一起使用 如何更改节点高度以使用 OwnerDraw 并在节点矩形中绘制 3 或 5 或更多 行 文本 所以树应该看起来像这样 显示根节点 2 个节点 aaa 和 bb
  • 使用 PM2 运行自定义 npm 脚本

    我目前正在开发几个 Telegram 机器人 但我想将它们全部保存在同一个 git 存储库中 问题是 另一方面 我想将它们作为单独的进程运行 由于我使用的是 Telegraf 框架 因此要运行机器人 请执行以下操作 micro bot sr
  • 如何在容器内保存对不同元素的多个引用?

    考虑这个简单的例子 v Vec
  • mailchimp api 2.0通过php订阅?

    我需要一个如何通过电子邮件地址订阅 mailchimp 时事通讯的示例 请在此处查看新的 api 链接 https bitbucket org mailchimp mailchimp api php https bitbucket org
  • 两种使用局部敏感哈希查找最近邻居的算法,哪一种?

    目前我正在研究如何使用局部敏感哈希来查找最近邻居 然而 当我阅读论文和搜索网络时 我发现了两种执行此操作的算法 1 使用L个哈希表和L个随机LSH函数 从而增加两个相似文档获得相同签名的机会 例如 如果两个文档的相似度为 80 那么它们有