The case of learned index structures论文阅读(二)

The case of learned index structures论文阅读(二)

链接:https://pan.baidu.com/s/1L65BK2vZ_5qEny04bfHPoA 
提取码:z98n

学习索引结构的实例

 

3.6训练

        虽然训练(即加载)时间不是本文的重点,但应该指出,我们所有的模型,浅NNs甚至简单的线性/多变量回归模型,训练相对较快。 简单NNs可以利用随机梯度下降进行有效的训练,并且可以在随机数据上以较少步数的速度收敛,而线性多变量模型(如0层NN)则存在一个闭式解,并且可以在排序数据上以一步的速度进行训练。因此,对于200M记录的训练,一个简单的RMI索引不会花费超过几秒的时间(当然,这取决于执行了多少自动调谐);神经网络可以根据每个模型的分钟顺序进行训练,这取决于复杂程度。还要注意的是,在整个数据上训练顶级模型通常是不必要的,因为这些模型往往在对整个随机数据进行一次扫描之前就收敛了。这在一定程度上是因为我们使用简单的模型,不太关心最后几个数字点的精度,因为它对索引性能的影响很小。最后,关于改进学习时间的研究[27,72]在我们的背景下得到了应用,我们期望在这个方向上有很多未来的研究。

3.7结果

        我们在几个真实的和合成的数据集上对学习范围指数的空间和速度进行了评估,并与其他读取优化的指数结构进行了比较。

3.7.1整数数据集

        【实验方式及数据集】作为第一个实验,我们在三个数据集上比较了 使用两阶段RMI模型和不同的第二阶段大小(10k、50k、100k和200k)学习索引  和具有不同页面大小的读优化b。对于数据,我们使用了2个真实的数据集,(1)Weblogs和(2)Maps[56],(3)一个合成数据集Lognormal。Weblogs数据集包含2亿个日志条目,用于数年内对一个主要大学网站的每个请求。我们使用唯一的请求时间戳作为索引键。这个数据集对于学习型索引来说几乎是一个最坏的情况,因为它包含了非常复杂的时间模式,这些时间模式是由课程安排、周末、假期、午休、部门活动、学期休息等引起的,众所周知,这些时间模式很难学习。对于地图数据集,我们将全球用户维护的特征(如道路、博物馆、咖啡店)的经度编入索引。不出所料,位置的经度是相对线性的,并且比Weblogs数据集具有更少的不规则性。最后,为了测试索引在重尾分布上的工作方式,我们生成了一个190M个唯一值的合成数据集,这些值从μ=0和σ=2的对数正态分布中采样。这些值被放大为高达1B的整数。这些数据当然是高度非线性的,这使得使用神经网络学习CDF更加困难。对于所有的B树实验,我们使用64位key和64位有效负载/值。

        【实验基准及优化】至于我们的基准,我们使用了一个生产级质量的B-Tree实现,与stx::B Tree类似,但具有进一步的缓存线优化、密集页面(即填充因子为100%)和非常有竞争力的性能。为了优化两级学习索引,我们在神经网络上使用了简单的网格搜索,它有0到2个隐藏层,层宽度从4到32个节点。一般来说,我们发现在第一阶段使用一个简单的(0个隐藏层)到半复杂的(2个隐藏层和8-16宽)模型效果最好。对于第二阶段,简单的线性模型具有最好的性能。这并不奇怪,因为在最后一英里,往往不值得执行复杂的模型,线性模型可以学习的最佳。

        学习索引与B树性能比较:主要结果如图4所示。注意,B-树的页面大小表示每页的键数,而不是字节大小,字节实际上更大。作为主要的度量标准,我们以MB为单位显示大小,以纳秒为单位显示总查找时间,以纳秒为单位显示执行模型(B树遍历或ML模型)的时间,并与paranthesis中的总时间进行百分比比较。此外,作为大小和查找列的一部分,我们在括号中显示了与页面大小为128的B树相比的速度和空间节省。我们选择128页作为固定的参考点,因为它为B树提供了最佳的查找性能(注意,通过完全没有索引,总是很容易以牺牲查找性能为代价节省空间)。speedup和size列中的颜色编码表示索引相对于参考点的快慢成都(较大或较小)。

        可以看出,学习型索引在几乎所有配置中都占据了B树索引的主导地位,它的速度高达1.5-3倍,同时又小了两个数量级。当然,B-树可以进一步压缩,但要花费CPU时间进行解压缩。然而,这些优化大多是正交的,并且对神经网络同样适用(如果不是更多的话)。例如,可以使用4位或8位整数而不是32位或64位浮点值来表示模型参数(称为量化的过程)来压缩神经网络。这种压缩级别可以为学习的索引释放额外的增益。

        毫不奇怪,第二阶段的规模大小对索引规模和查找性能有着显著的影响。在第二阶段使用10000个或更多的模型对于第2.1节中的分析来说尤其令人印象深刻,因为它表明我们的第一阶段模型可以比B树中的单个节点在精度上有更大的提升。最后,我们没有报告混合模型或其他搜索技术比二进制搜索这些数据集,因为它们没有提供显著的好处。

        学习索引与备选基线比较:除了针对我们的已读优化B-树对学习索引进行详细评估外,我们还在公平条件下将学习索引与其他备选基线(包括第三方实现)进行了比较。在下面,我们将讨论一些备选基线,并在适当的情况下将它们与学习的索引进行比较:

        直方图:B-树近似于底层数据分布的CDF。一个明显的问题是直方图是否可以用作CDF模型。原则上,答案是肯定的,但要实现快速数据访问,直方图必须是CDF的低误差近似值。通常这需要大量的bucket,这使得搜索直方图本身非常昂贵。如果bucket具有不同的bucket边界以有效地处理数据倾斜,因此只有少数bucket是空的或太满的,那么这一点尤其正确。这个问题的明显解决方案将产生一个B-树,因此直方图不再进一步讨论。

        查找表:B树的一个简单替代方法是(分层)查找表。查找表通常具有固定的大小和结构(例如,每个插槽指向另一个64个插槽)。查找表的优点是,由于其固定的大小,可以使用AVX指令对其进行高度优化。我们包含了一个与三阶段查找表的比较,三阶段查找表是通过获取每个第64个键并将其放入一个包含填充的数组中,使其成为64的倍数来构造的。然后我们在数组中重复这个过程一次,不加填充,总共创建了两个数组。为了查找一个键,我们在最上面的表上使用二进制搜索,然后对第二个表和数据本身进行VX优化的无分支扫描[14]。与其他方法相比,此配置导致最快的查找时间(例如,在顶层使用扫描,或在第二个数组或数据上使用二进制搜索)。

        FAST:FAST[44]是一种高度SIMD优化的数据结构。我们使用[47]中的代码进行比较。但是,需要注意的是,FAST总是需要以2的幂来分配内存,以使用无分支SIMD指令,这可能会导致更大的索引。

        固定大小B-树和插值搜索:最后,正如最近一篇博客文章[1]中所建议的,我们创建了一个固定高度B-树和插值搜索。设置了B树的高度,使得树的总大小为1.5MB,与我们学习的模型类似。

        无开销学习索引:对于我们的学习索引,我们使用了两阶段的RMI索引,顶部是多元线性回归模型,底部是简单线性模型。我们对top模型使用简单的自动特征工程,通过自动创建和选择key、log(key)、key2等形式的特征。多元线性回归是NN的一种有趣的替代方法,因为它特别适合只需少量操作就能拟合非线性模式。此外,我们在基准测试框架之外实现了学习型索引,以确保公平的比较。

        为了进行比较,我们使用了Lognormal数据和一个8字节指针的有效负载。结果如图5所示。从公平条件下的数据集可以看出,学习索引在节省大量内存的同时提供了最佳的总体性能。需要注意的是,由于对齐要求,快速索引很大。

        虽然结果是非常有希望的,但我们绝不声称学习索引永远是大小或速度方面的最佳选择。相反,学习过的索引提供了一种思考索引的新方法,需要更多的研究来充分理解其含义。

3.7.2字符串数据集

        我们还创建了一个超过1000万个大型web索引的非连续文档id的二级索引,作为Google实际产品的一部分,用于测试学习到的索引如何在字符串上执行。基于字符串的文档id数据集的结果如图6所示,其中现在还包括混合模型。此外,我们在表中包含了我们最好的模型,这是一个带有四元搜索的非混合RMI模型索引,名为“learn QS“(表格底部)。所有RMI索引在第二阶段使用10000个模型,对于混合索引,我们使用两个阈值128和64作为模型在替换为B树之前的最大允许绝对误差。

        【图6解释说明】可以看出,对于字符串,学习索引的速度比B-树的速度要慢得多。部分原因是模型执行成本相对较高,GPU/TPU可以解决这个问题。此外,对字符串的搜索要昂贵得多,因此更高的精度通常会带来回报;混合索引(通过B树替换性能不佳的模型)有助于提高性能的原因。

        由于搜索的成本,不同的搜索策略会产生更大的差异。例如,具有1-隐藏层和有偏二值搜索的NN的搜索时间是1102ns,如图6所示。相比之下,我们使用相同模型的有偏四元搜索只需要658ns,这是一个显著的改进。偏倚搜索和四元搜索之所以表现得更好,是因为它们考虑了模型误差。

4点索引

        除了范围索引之外,用于点查找的Hash-maps散列映射在DBMS中也起着类似的重要作用。概念上的哈希映射使用哈希函数来确定将键映射到数组中的位置(参见图7(a))。任何有效的散列映射实现的关键挑战是防止太多不同的键被映射到散列映射内的同一位置,以下称为冲突。例如,假设100M记录和100M哈希映射大小,对于一致随机化key的哈希函数,可以类似于birthday悖论导出预期冲突的数量,并且预期冲突的数量大约为33%或3300万个时隙。对于这些冲突中的每一个,哈希映射体系结构都需要处理这些冲突。例如,单独的链接散列映射将创建一个链接列表来处理冲突(参见图7(a))。

        然而,存在许多替代方法,包括二次探测、使用具有多个时隙的桶、甚至同时使用多个散列函数(例如,如布谷鸟散列[57]所做的那样)。然而,不管哈希映射体系结构如何,冲突都会对性能和/或存储需求产生重大影响,机器学习模型可能提供一种减少冲突数量的替代方法。虽然将学习模型作为散列函数的想法并不新鲜,但现有的技术并没有利用底层数据分布的优势。例如,各种完美的散列技术[26]也试图避免冲突,但作为散列函数一部分使用的数据结构随着数据大小而增长;属性学习模型可能没有(回想一下,索引1到100M之间的所有键的示例)。据我们所知,如果有可能学习能够产生更有效的点索引的模型,就没有进行过探索。

4.1哈希模型索引

        【哈希模型索引核心】出人意料的是,学习key分布的CDF是学习更好的哈希函数的一个潜在途径。但是,与范围索引相比,我们的目标不是紧凑地或严格地按排序顺序存储记录。相反,我们可以按哈希映射的目标大小M来缩放CDF,并使用,使用键K作为哈希函数。如果模型F完美地学习了key的经验CDF,则不存在冲突。此外,哈希函数与实际的哈希映射体系结构正交,可以与单独的链接或任何其他哈希映射类型组合。

        对于模型,我们可以再次利用上一节中的递归模型体系结构。很明显,和以前一样,索引的大小和性能之间存在一个折衷,这受模型和数据集的影响。

        注意,如何处理插入、查找和冲突取决于散列映射体系结构。因此,与传统的散列函数相比,学习散列函数所带来的好处在于,它key映射到均匀分布的空间,这取决于两个关键因素:(1)模型如何准确地表示观察到的CDF。例如,如果数据是由均匀分布生成的,一个简单的线性模型将能够学习一般的数据分布,但是得到的散列函数不会比任何足够随机的散列函数好。(2)散列映射体系结构:根据体系结构、实现细节、负载(即值)、冲突解决策略以及将要或可以分配多少内存(即插槽)显著影响性能。例如,对于小键和小值或无值的哈希函数,使用布谷鸟哈希的传统哈希函数可能会工作得很好,而较大的有效负载或分布式哈希映射可能会从避免冲突中获益更多,从而从学习的哈希函数中获益更多。

4.2结果

        【字符串数据集实验配置】我们评估了前一节中三个整数数据集上学习散列函数的冲突率。作为我们的模型散列函数,我们使用了前一节中的两阶段RMI模型,第二阶段有100k个模型,没有任何隐藏层。作为基线,我们使用了一个简单的类似murrushHash3的哈希函数,并比较了一个与记录具有相同槽数的表的冲突数。

        如图8所示,在我们的数据集上,通过以合理的成本学习经验CDF,所学习的模型可以减少高达77%的冲突;执行时间与图4中的模型执行时间相同,大约为25-40ns。

        模型的执行时间取决于散列映射体系结构、有效负载和许多其他因素,这对减少冲突有多大好处。例如,我们的实验(见附录B)表明,对于具有20字节记录的独立链式哈希映射体系结构,学习的哈希函数可以减少与随机散列相比,延迟仅增加13ns,浪费的存储量高达80%。它只增加13 ns而不是40 ns延迟的原因是,通常较少的冲突也会导致较少的缓存未命中,从而获得更好的性能。另一方面,对于非常小的有效负载,使用标准散列映射进行杜鹃散列可能仍然是最好的选择。然而,正如我们在附录C中所示,对于较大的有效载荷,具有学习的散列函数的链式散列映射可以比杜鹃散列和/或传统的随机散列更快。最后,我们看到了分布式设置的最大潜力。例如,NAM-DB[74]使用散列函数使用RDMA在远程机器上查找数据。由于每次冲突的代价都非常高(即每次冲突都需要一个额外的RDMA请求,该请求按微秒的顺序排列),因此模型执行时间可以忽略不计,甚至冲突率的小幅度降低都可以显著提高整体性能。总之,学习的散列函数独立于所使用的散列映射体系结构,并且取决于散列映射体系结构,它们的复杂性可能得到回报,也可能得不到回报

5存在性索引

        DBMS的最后一种常见指标类型是存在性索引,最重要的是Bloom过滤器一种空间效率高的概率数据结构,用来测试一个元素是否是集合的成员。它们通常用于确定cold storage中是否存在key。例如,Bigtable使用它们来确定键是否包含在SSTable[23]中。

        【Bloom过滤器工作原理】在内部,Bloom过滤器使用一个大小为m的位数组和k个散列函数,每个散列函数将一个键映射到m数组位置之一(参见图9(a))。要向集合中添加元素,向k个散列函数馈送一个键,并将返回位置的位设置为1。为了测试一个key是否是集合的成员,该key再次被馈送到k个散列函数中以接收k个数组位置。如果这些k个数组位值中的任何一位为0,则该键不是集合的成员。换句话说,Bloom过滤器确实保证不存在假阴性【实际上是阳性,但表现为阴性】,但具有潜在的假阳性。

        虽然Bloom过滤器具有很高的空间效率,但它们仍然可以占用大量内存。例如,对于10亿条记录,大约需要1.76千兆字节。对于0.01%的FPR,我们需要大约2.23千兆字节。已经有几次尝试提高Bloom过滤器的效率[52],但是一般的观察结果仍然存在。

        然而,如果有某种结构来确定集合内部与外部是什么,这是可以学习的,那么就有可能构造更有效的表示。有趣的是,对于数据库系统的存在索引,延迟和空间需求 通常与 我们之前看到的 非常不同。考虑到访问冷存储的高延迟(例如磁盘或甚至频带),我们可以提供更复杂的模型,而主要目标是最小化索引空间和误报次数。我们概述了使用lea构建存在索引的两种可能的方法。

5.1学习Bloom过滤器

        构建存在性索引的两种可能方法,而范围索引和点索引都学习key的分布,存在性索引需要学习一个将把所有的键都分开的函数。换句话说,一个好的点索引哈希函数是一个键之间很少冲突的函数,而一个好的Bloom过滤器哈希函数是一个有很多键之间的冲突和非键之间的冲突,但键和非键之间的冲突很少。下面我们考虑如何学习这样一个函数f,以及如何将它合并到一个存在性索引中。

        虽然传统的Bloom过滤器对于任何一组查询的先验选择,保证了一个假阴性率(FNR)为零和一个特定的假阳性率(FPR) ;但我们遵循这样的概念:我们希望为realistic queries提供特定的FPR,特别是在FNR保持为零的情况下。也就是说,我们在查询固定数据集上测量FPR,这在评估ML系统时很常见[30]。虽然这些定义不同,但我们认为,假设我们可以观察查询的分布,例如从历史日志中观察查询的分布,在许多应用程序中都适用,特别是在数据库5中。

        传统上,存在性索引不使用键的分布,也不使用它们与非键的区别,但是learned-Bloom过滤器可以使用。例如,如果我们的数据库包含0≤x<n, 存在性索引可以在恒定的时间内计算出来,而且通过计算几乎没有内存占用

        在考虑用于ML的数据分布时,我们必须考虑非键的数据集。在这项工作中,我们考虑非键来自可观察的历史查询的情况,并假设未来查询来自与历史查询相同的分布。当这一假设不成立时,可以使用随机生成的key、由机器学习模型生成的非key[34]、直接处理协变量移位的重要性加权[18]或鲁棒性的对抗性训练[65];我们将此作为未来的工作。我们用K表示key集,用U表示非key集。

5.1.1作为分类问题的Bloom过滤器

        将存在性指标作为一个二元概率分类任务来构造。也就是说,我们想学习一个模型f,它可以预测查询x是键还是非键。例如,对于字符串,我们可以训练的递归神经网络(RNN)或卷积神经网络(CNN)[64,37]。由于这是一个二元分类任务,我们的神经网络具有产生概率的乙状结肠激活,并训练以最小化对数损失:。f(x)的输出可以解释为x在我们的数据库中是一个键的概率。因此,我们可以通过选择阈值τ将模型转换为存在性指数,在阈值τ以上,我们将假设key存在于我们的数据库中。与Bloom滤波器不同,我们的模型可能具有非零FPR和FNR;事实上,随着FPR的下降,FNR将上升。为了保持存在索引的无假否定约束,我们创建了一个溢出Bloom过滤器。也就是说,我们认为是f的假负的集合,并为这一key子集创建Bloom滤波器。然后我们可以运行图9(c)中的生存指数:如果f(x)≥τ,则认为key存在;否则,检查溢出Bloom过滤器。一个问题是如何设置τ,使我们学习的Bloom滤波器具有所需的FPR p*。我们用来表示模型的FPR,其中∏U是非键的保持集。我们用FPRB表示我们的溢流Bloom过滤器的FPR。因此,我们系统的整体FPR是

        为了简单起见,我们将FPRτ=FPRB=p∗2设为FPRO≤p∗。我们对τ进行调整,以在∮U上实现该FPR。该设置的有效性在于,所学习的模型相对于数据的大小可以相当小。此外,由于Bloom过滤器随键集的大小而缩放,溢出Bloom过滤器将随FNR而缩放。我们将从实验上看到,这种组合在减少存在索引的内存占用方面是有效的。最后,学习模型计算可以受益于机器学习加速器,而传统的Bloom滤波器往往严重依赖于内存系统的随机访问延迟。

5.1.2带模型散列的Bloom过滤器

        构建存在性索引的另一种方法是学习散列函数,其目标是最大化键之间和非键之间的冲突,同时最小化键和非键之间的冲突。有趣的是,我们可以使用与以前相同的概率分类模型来实现这一点。也就是说,我们可以创建一个散列函数d,它通过将f的输出缩放为

        将f映射到m大小的位数组,因此,我们可以像Bloom过滤器中的任何其他函数一样使用d作为散列函数。这样做的好处是f被训练成将大多数键映射到较高的位位置范围,而非键映射到较低的位位置范围(见图9(b))。附录E.5.2给出了对该方法的更详细的解释。

5.2结果

        为了实验性地验证这一想法,我们探索了一个存在性指数在跟踪黑名单钓鱼网址中的应用。我们认为谷歌透明度报告中的数据是我们需要跟踪的关键。这个数据集由170万个唯一的url组成。我们使用一个负数集,它是随机(有效)URL和白名单URL的混合,这些URL可能会被误认为是仿冒网页。我们将阴性集随机分成训练集、验证集和测试集。我们训练一个字符级RNN(特别是GRU[24])来预测URL属于哪个集合;我们基于验证集设置τ,并在测试集上报告FPR。

        具有所需1%FPR的普通Bloom过滤器需要2.04MB。我们考虑一个16维GRU,每个字符嵌入32维;这个模型是0.0259MB。当建立一个可比较的学习指数时,我们在验证集上设置τ为0.5%的FPR;这给出了55%的FNR。(测试集上的FPR为0.4976%,验证了所选阈值。)如上所述,我们的Bloom过滤器的大小与FNR成比例。因此,我们发现我们的模型加上溢出Bloom过滤器使用了1.31MB,大小减少了36%。如果我们想强制执行0.1%的总FPR,那么FNR为76%,这将使Bloom过滤器的总大小从3.06MB减少到2.59MB,内存减少了15%。我们在图10中观察到这种一般关系。有趣的是,我们看到不同大小的模型如何以不同的方式平衡准确性和内存权衡。

        我们简要地考虑了在我们的查询分布中存在协变量转移的情况,我们在模型中没有讨论这个问题。当使用只有随机url的验证和测试集时,我们发现在FPR为1%的Bloom过滤器上可以节省60%。当使用只有白名单url的验证和测试集时,我们发现与FPR为1%的Bloom过滤器相比,我们可以节省21%。最终,负集的选择是特定于应用的,协变量转移可以更直接地解决,但这些实验旨在为该方法如何适应不同的情况提供直觉。

        显然,我们的模型越精确,Bloom过滤器的尺寸就越节省。其中一个有趣的特性是,我们的模型没有理由需要使用与Bloom过滤器相同的特性。例如,大量的研究已经开始使用ML来预测网页是否是钓鱼网页[10,15]。在模型中可以加入WHOIS数据或IP信息等附加特征,提高了模型的精度,减小了Bloom滤波器的尺寸,并保持了无假阴性的特性。

        此外,我们根据附录E第5.1.2节中的方法给出了额外的结果。

图10:学习的Bloom过滤器在广泛的fpr中改善了内存占用。(这里W是RNN宽度,E是每个字符的嵌入大小)

6相关工作

        学习索引的思想建立在机器学习和索引技术的广泛研究基础上。在下面,我们将重点介绍最重要的相关领域。

        B-树和变体:在过去的几十年中,人们提出了各种不同的索引结构[36],例如基于磁盘的系统的B+树[17]和内存系统的T-树[46]或平衡/红黑树[16,20]。由于原始的主存树的缓存性能较差,因此提出了几种具有缓存意识的B+树变体,如CSB+树[58]。类似地,也有人研究如何利用诸如FAST[44]之类的SIMD指令,甚至利用gpu[44、61、43]。此外,这些(内存中)索引中的许多能够通过在节点之间使用偏移量而不是指针来减少其存储需求。对于文本的索引结构也有大量的研究,如tries/radix trees[19,45,31]或其他奇异的索引结构,它们结合了B-树和tries[48]的思想。

        然而,所有这些方法都与学习索引的思想正交,因为没有一种方法从数据分布中学习,以获得更紧凑的索引表示或性能提高。同时,与我们的混合索引一样,可能可以将现有的硬件意识索引策略与学习模型更紧密地结合起来,以进一步提高性能。

        由于B+树消耗大量内存,因此在压缩索引方面也做了大量工作,例如前缀/后缀截断、字典压缩、键规范化[36、33、55]或混合的热/冷索引[75]。然而,我们提出了一种完全不同的索引压缩方法,这种方法依赖于数据分布,能够实现数量级的较小索引和更快的查找时间,甚至可能改变存储复杂性类(例如,O(n)到O(1))。有趣的是,一些现有的压缩技术是对我们方法的补充,可以帮助进一步提高效率。例如,字典压缩可以看作是一种嵌入形式(即,将字符串表示为唯一整数)。

        可能与本文最相关的是A-树[32]、BF-树[13]和B-树插值搜索[35]。BF树使用B+树来存储关于数据集某个区域的信息,但是叶节点是Bloom过滤器,并不近似于CDF。相比之下,A-Trees使用分段线性函数来减少B-Tree中的叶节点数,并且[35]建议在B-Tree页面中使用插值搜索。但是,学会了索引更进一步,建议使用学习模型替换整个索引结构。

        最后,像Hippo[73]、块范围索引[63]和小型物化聚合(SMAs)[54]这样的稀疏索引都存储有关值范围的信息,但同样没有利用数据分布的基本属性。

        用于ANN索引的学习散列函数:已有很多关于学习散列函数的研究[49,68,67,59]。最值得注意的是,已经有人在学习局部敏感哈希(LSH)函数来建立近似最近邻(ANN)索引。例如,[66,68,40]探索使用神经网络作为散列函数,而[69]甚至试图保持多维输入空间的顺序。然而,LSH的一般目标是将相似项分组到桶中,以支持最近邻查询,通常需要在高维输入空间中使用一些不同的hamming距离来学习近似相似性度量。没有直接的方法来调整以前的方法来学习我们所考虑的基本数据结构,也不清楚它们是否能够被调整。

        完美散列:完美散列[26]与我们对散列映射模型的使用非常相关。就像我们的CDF模型一样,完美的散列试图避免冲突。然而,在我们所知道的所有方法中,学习技术都没有被考虑,并且函数的大小随着数据的大小而增长。相反,学习的散列函数可以独立于大小。例如,用于映射0到200M之间的其他整数的线性模型不会产生任何冲突,并且与数据大小无关。此外,完美散列对于B树或Bloom过滤器也没有用处。

        Bloom filters:最后,我们的存在性索引直接建立在bloomfilters中的现有工作的基础上[29,11]。我们的工作再一次从不同的角度来看待这个问题,提出了一个Bloom过滤器增强的分类模型,或者使用模型作为特殊的散列函数,其优化目标与我们为散列映射创建的散列模型大不相同。简洁的数据结构:学习的索引和简洁的数据结构之间存在着有趣的联系,特别是秩选择字典,如小波树[39,38]。然而,许多简洁的数据结构侧重于H0熵(即,对索引中的每个元素进行编码所需的位数),而学习型索引则试图学习底层数据分布以预测每个元素的位置。因此,学习的索引可能获得比H0熵更高的压缩率,但可能会以较慢的操作为代价。此外,简洁的数据结构通常必须为每个用例精心构建,而学习的索引通过机器学习“自动化”这个过程。简洁的数据结构可以为进一步研究学习型指标提供一个框架。

        CDF建模:我们的范围和点索引模型都与CDF模型密切相关。估计CDF是非常重要的,已经在机器学习社区[50]中进行了研究,并有一些应用,如排名[42]。如何对CDF进行最有效的建模仍然是一个有待进一步研究的问题。专家混合:我们的RMI架构遵循了一个关于为数据子集建立专家的长期研究路线[51]。随着神经网络的发展,这一现象变得越来越普遍,并显示出更大的实用性[62]。正如我们在设置中看到的那样,它很好地让我们能够分离模型大小和模型计算,从而使更复杂的模型不需要更高的执行成本。

7结论和未来的工作

        我们表明学习型索引可以利用被索引数据的分布提供显著的效益。这为许多有趣的研究问题打开了大门。

        其他ML模型:虽然我们关注的是线性模型和混合专家的神经网络,但还有许多其他ML模型类型以及将它们与传统数据结构相结合的方法,值得探索。多维索引:可以说,学习索引的思想最令人兴奋的研究方向是将其扩展到多维索引。模型,特别是NNs,非常擅长捕捉复杂的高维关系。理想情况下,该模型能够估计由任何属性组合过滤的所有记录的位置。

        除了索引:学习到的算法可能令人惊讶,CDF模型还有可能加速排序和连接,而不仅仅是索引。例如,加快排序的基本思想是使用现有的CDF模型F大致按排序顺序排列记录,然后使用插入排序等方法更正几乎完全排序的数据。

        GPU/TPUs:最后,正如本文中多次提到的,将使学习索引的思想更有价值。同时,GPU/tpu也有自己的挑战,最重要的是高调用延迟。虽然可以合理地假设,由于如前所示的异常压缩比,可能所有学习到的索引都适合GPU/TPU,但仍需要2-3微秒才能调用对它们的任何操作。同时,机器学习加速器与CPU的集成也越来越好[6,4],通过批处理请求等技术,调用成本可以分摊,因此我们不认为调用延迟是真正的障碍。

        综上所述,我们已经证明了机器学习模型比最新的索引具有显著的优势,我们相信这是未来研究的一个富有成效的方向。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
## A C++11 implementation of the B-Tree part of "The Case for Learned Index Structures" A research **proof of concept** that implements the B-Tree section of [The Case for Learned Index Structures](https://arxiv.org/pdf/1712.01208.pdf) paper in C++. The general design is to have a single lookup structure that you can parameterize with a KeyType and a ValueType, and an overflow list that keeps new inserts until you retrain. There is a value in the constructor of the RMI that triggers a retrain when the overflow array reaches a certain size. The basic API: ```c++ // [first/second]StageParams are network parameters int maxAllowedError = 256; int maxBufferBeforeRetrain = 10001; auto modelIndex = RecursiveModelIndex recursiveModelIndex(firstStageParams, secondStageParams, maxAllowedError, maxBufferBeforeRetrain); for (int ii = 0; ii < 10000; ++ii) { modelIndex.insert(ii, ii * 2); } // Since we still have one more insert before retraining, retrain before searching... modelIndex.train(); auto result = modelIndex.find(5); if (result) { std::cout << "Yay! We got: " << result.get().first << ", " << result.get().second << std::endl; } else { std::cout << "Value not found." << std::endl; // This shouldn't happen in the above usage... } ``` See [src/main.cpp](src/main.cpp) for a usage example where it stores scaled log normal data. ### Dependencies - [nn_cpp](https://github.com/bcaine/nn_cpp) - Eigen based minimalistic C++ Neural Network library - [cpp-btree](https://code.google.com/archive/p/cpp-btree/) - A fast C++ implementation of a B+ Tree ### TODO: - Lots of code cleanup - Profiling of where the slowdowns are. On small tests, the cpp_btree lib beats it by 10-100x - Eigen::TensorFixed in nn_cpp would definitel

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值