首页 > 其他分享 >差异编码(Delta Encoding) 和 字典压缩(Dictionary Encoding)

差异编码(Delta Encoding) 和 字典压缩(Dictionary Encoding)

时间:2025-01-21 20:21:05浏览次数:1  
标签:编码 Dictionary Encoding 压缩 索引 文档 Delta ID 字典

1. 差异编码(Delta Encoding):倒排列表中可能会采用差异编码,即存储相邻文档 ID 之间的差值,而不是直接存储每个文档 ID,这样可以进一步压缩空间。

2. 字典压缩(Dictionary Encoding):对于倒排列表中的文档 ID,可以使用字典进行压缩,进一步减少存储需求。 举例学习和说明这两个方法

 

差异编码(Delta Encoding)字典压缩(Dictionary Encoding) 是常见的数据压缩技术,广泛应用于倒排索引中以减少存储空间并提高查询效率。

下面我将详细讲解这两种方法,并通过具体的示例来说明它们是如何工作的。

 

1. 差异编码(Delta Encoding)

 

差异编码 是一种常用于压缩数值序列的方法,特别是在处理那些数值变化较小的序列时。它的基本思路是:对于一个数值序列,存储相邻数值之间的差值,而不是直接存储每个数值本身。

 

工作原理:

 

• 给定一个序列 S = [s0, s1, s2, ..., sn],差异编码将该序列转换为差值序列 D = [s0, s1 - s0, s2 - s1, ..., sn - sn-1]。

• 差异编码能够减少存储空间,因为差值往往比原始数值小,尤其是在数值变化较小的情况下,差值通常为小的整数或零。

 

举例:

 

假设我们有一个文档的倒排列表,表示文档中包含某个词项的位置(文档ID)。传统的倒排索引可能是这样的:

 

词项 倒排列表

apple [1, 5, 8, 12, 15]

banana [2, 4, 6, 7, 9]

 

在这个例子中,apple 词项出现在文档 1, 5, 8, 12, 15 中。直接存储这些文档 ID 需要 5 个整数。

 

差异编码后的存储

• 对于 apple 词项,首先存储第一个文档 ID 1。

• 然后存储与上一个文档 ID 的差值:5 - 1 = 4、8 - 5 = 3、12 - 8 = 4、15 - 12 = 3。

• 因此,apple 的差异编码后的倒排列表为:[1, 4, 3, 4, 3]。

 

相比原始的 [1, 5, 8, 12, 15],差异编码显著减少了存储空间,因为差值 4, 3, 4, 3 都是较小的数字,通常会占用比原始文档 ID 更少的字节数。

 

实际效果:

 

• 假设一个文档ID占用 4 字节,如果文档ID的差异比较大,比如 10000, 10005, 10010,差异编码后的差值 0, 5, 5 可以用更少的字节存储。

• 如果我们有一大批文档 ID 的变化较小(例如 ID 数字是递增的),差异编码将能显著减小存储空间。

 

2. 字典压缩(Dictionary Encoding)

 

字典压缩 是另一种常用的压缩技术,特别适用于具有重复元素的序列。它的基本思路是:将序列中的元素映射到一个固定的字典或索引表,然后用较小的数字代替原始的元素。这样可以显著减少存储空间,尤其是在有大量重复元素时。

 

工作原理:

 

• 构建一个字典,字典将每个唯一的元素(如文档 ID)映射到一个整数。

• 倒排索引中的每个文档 ID 使用字典中的索引代替,从而减少存储所需的字节数。

 

举例:

 

假设我们有一个倒排列表,包含以下文档 ID:

 

词项 倒排列表

apple [1, 5, 8, 15]

banana [2, 4, 6, 9, 15]

 

传统存储

• 直接存储文档 ID,如 apple 的倒排列表是 [1, 5, 8, 15] 和 banana 的倒排列表是 [2, 4, 6, 9, 15]。

 

字典压缩存储

1. 首先,构建一个字典,将所有出现过的文档 ID 映射到一个整数 ID。假设我们构建如下字典:

• 1 -> 0

• 2 -> 1

• 4 -> 2

• 5 -> 3

• 6 -> 4

• 8 -> 5

• 9 -> 6

• 15 -> 7

2. 然后,将倒排列表中的文档 ID 替换为字典中的索引值。apple 的倒排列表变为 [0, 3, 5, 7],banana 的倒排列表变为 [1, 2, 4, 6, 7]。

 

相比原始的文档 ID,字典编码通过使用较小的索引值代替原始文档 ID,显著减少了存储需求。

 

实际效果:

 

• 字典压缩的效果非常适合有大量重复元素的情况。如果文档 ID 出现的次数很多,使用字典压缩可以极大地减少存储空间。

• 假设每个文档 ID 是 4 字节,而字典索引是 1 字节(如果字典足够小的话)。通过将文档 ID 替换为字典索引,可以节省大量存储空间。

 

综合应用(差异编码 + 字典压缩)

 

在实际的倒排索引中,差异编码和字典压缩通常是结合使用的。首先,通过字典压缩将文档 ID 映射到较小的整数,然后使用差异编码存储这些整数的差值。这样,倒排索引的存储空间得到了大幅度的压缩。

 

综合示例:

 

假设我们有一个倒排列表,文档 ID 如下:

 

词项 倒排列表

apple [1, 5, 8, 12, 15]

banana [2, 4, 6, 7, 9]

 

1. 字典压缩:首先创建一个字典,将文档 ID 映射为索引值:

 

文档 ID 索引值

1 0

2 1

4 2

5 3

6 4

7 5

8 6

9 7

12 8

15 9

 

2. 差异编码:对倒排列表中的索引值进行差异编码,得到差值序列:

 

• 对于 apple:原始索引为 [0, 3, 6, 8, 9],差异编码后的索引为 [0, 3, 3, 2, 1]。

• 对于 banana:原始索引为 [1, 2, 4, 5, 7],差异编码后的索引为 [1, 1, 2, 1, 2]。

 

通过这种方式,倒排索引的存储空间得到了显著压缩。

 

总结

 

差异编码:通过存储相邻数值的差值,而不是直接存储原始数值,能够减少存储空间,特别是当数值变化较小的时候。

字典压缩:通过为重复的元素分配索引值,将原始元素替换为较小的整数,从而减少存储空间,尤其在元素重复时效果显著。

 

在实际的倒排索引实现中,这两种技术通常是结合使用的,进一步提高存储效率和查询性能。

结合 差异编码(Delta Encoding)字典压缩(Dictionary Encoding) 是一种常见的压缩策略,特别适用于需要高效存储和查询的场景,如大规模文档集合(例如 27 亿篇文档)的倒排索引。

下面将详细讲解如何将这两种技术结合使用,并给出具体的实现思路。

 

1. 结合使用差异编码和字典压缩

 

步骤概览:

 

1. 文档 ID 压缩(字典压缩):对于倒排列表中的文档 ID,首先将它们映射到一个更小的字典索引。这可以减少每个文档 ID 所占的空间,因为它们通常是连续的且重复出现的。

2. 倒排列表压缩(差异编码):在倒排列表中使用差异编码,将每个词项的文档 ID 序列转换为相邻文档 ID 的差值序列。差值通常比原始的文档 ID 更小,从而进一步减少存储空间。

 

2. 字典压缩(Dictionary Encoding)

 

对于 27 亿篇文档,假设每篇文档都有一个唯一的文档 ID。传统的倒排列表可能是:

 

词项 倒排列表

apple [1, 5, 8, 12, 15, 20, …, 267891234]

banana [2, 4, 6, 7, 9, 10, …, 267891234]

 

• 假设 apple 出现在文档 1, 5, 8, 12, 15 等文档中,直接存储这些文档 ID 可能占用很多空间。每个文档 ID 是一个 32 位整数,占用 4 字节。

 

字典压缩 的目标是将文档 ID 替换为更小的整数值。例如,如果 1, 5, 8, 12, 15 是文档 ID 中出现的值,可以为这些文档 ID 创建一个字典,字典将文档 ID 映射到索引:

 

文档 ID 索引值

1 0

5 1

8 2

12 3

15 4

… …

 

然后,apple 词项的倒排列表就变成了:[0, 1, 2, 3, 4, ...]。

 

这种方法的好处是将文档 ID 转换为小的整数值,从而节省空间。

 

字典压缩的实现:

 

• 为所有文档 ID 创建一个字典。每个文档 ID 映射到一个唯一的整数索引(可能是一个 32 位或更小的整数,具体取决于文档集合的规模)。

• 倒排列表中存储的是字典索引而不是实际的文档 ID,从而减少了存储空间。

 

3. 差异编码(Delta Encoding)

 

差异编码的目标是将连续的文档 ID 序列转换为差值,避免存储大数字。特别是,当文档 ID 是递增的或相差不大的时候,差异编码能够显著压缩存储空间。

 

举例:

 

假设我们已经对文档 ID 使用了字典压缩,并得到了以下文档 ID 序列:

 

apple 词项的倒排列表:[0, 1, 2, 3, 4, ...],这已经是字典压缩后的结果。

 

我们对这些索引值应用差异编码。差异编码的过程是:

• 第一个文档 ID(即 0)不变。

• 第二个文档 ID 与第一个文档 ID 的差值是 1 - 0 = 1。

• 第三个文档 ID 与第二个文档 ID 的差值是 2 - 1 = 1。

• 以此类推。

 

因此,经过差异编码,apple 词项的倒排列表变为:[0, 1, 1, 1, 1, ...]。

 

为什么差异编码有效:

 

• 如果文档 ID 是递增的,或者文档 ID 之间的差值很小,差异编码会显著减少存储空间。通常,差值比原始的文档 ID 要小,可以用更少的字节表示。

 

实现差异编码:

 

1. 对每个倒排列表,存储第一个文档 ID(或者字典索引)。

2. 对后续的文档 ID,存储它与前一个文档 ID 的差值。

 

4. 结合差异编码与字典压缩

 

通过将 字典压缩差异编码 结合使用,我们可以获得更高的压缩比。在实际的倒排索引中,通常的步骤如下:

1. 创建字典

• 为文档集合中的所有文档创建一个字典,确保每个文档 ID 都被映射到一个唯一的整数。

2. 字典压缩文档 ID

• 在倒排列表中,使用字典中为每个文档 ID 分配的索引值来代替原始文档 ID。这样可以减少存储每个文档 ID 所需的字节数。

3. 应用差异编码

• 对倒排列表中的文档 ID 序列(已经通过字典压缩)应用差异编码,将相邻的文档 ID 之间的差值存储。这样可以进一步压缩存储空间,特别是当文档 ID 序列变化不大时。

 

5. 考虑 27 亿篇文档的规模

 

假设每个倒排列表中有数百万个文档 ID,这时 差异编码字典压缩 将特别有效。

 

字典压缩:

 

• 如果字典映射中的索引值使用 1 字节(例如,最多 256 个不同的文档 ID)而不是 4 字节存储文档 ID,则可以显著减少存储空间。

• 对于更大的文档集合,可以使用更大的字典(例如,2 字节索引、4 字节索引等)。

 

差异编码:

 

• 如果文档 ID 变化较小(例如,ID 是递增的或差值较小),差异编码将进一步压缩空间。差值通常小于原始文档 ID,因此占用的存储空间会大大减少。

 

示例:假设有大量连续的文档 ID

 

假设我们有如下的文档 ID 序列(字典压缩后):

 

[1000, 1001, 1002, 1003, 1004, 1005, 1006]

 

差异编码后的序列为:

 

[1000, 1, 1, 1, 1, 1, 1]

 

这里,文档 ID 的差值是常数 1,差异编码压缩后的空间比原始序列小得多。

 

总结

 

结合 差异编码字典压缩 可以极大地减少倒排索引的存储空间,尤其是在处理大规模文档集合时。具体的实现步骤如下:

1. 为每个文档 ID 创建字典,将文档 ID 映射为索引。

2. 使用差异编码将连续的文档 ID 序列转换为差值。

3. 存储差异编码后的倒排列表和字典索引,极大地减少存储空间。

 

通过这两种压缩技术的结合,Havenask 或类似的大规模搜索引擎可以高效地处理数十亿文档的数据量,同时保持较低的存储开销和高效的查询性能。

 

 

 

标签:编码,Dictionary,Encoding,压缩,索引,文档,Delta,ID,字典
From: https://www.cnblogs.com/zhangkele/p/18684364

相关文章

  • ViewDataDictionary(this.ViewData)
    在ASP.NETMVC中,ViewDataDictionary是一个用于在控制器和视图之间传递数据的字典类。它继承自ViewDataContainer,并提供了键值对的存储和检索功能。ViewDataDictionary可以存储任何类型的数据,并且在视图中可以通过键名来访问这些数据。构造函数 ViewDataDictionary(this.ViewD......
  • [PCIE5.0] 4.2.8 Compliance Pattern in 8b/10b Encoding
    这段文字描述的是在PCIe或类似高速接口协议中,Polling.Compliance子状态的具体要求,特别是合规模式(CompliancePattern)在传输过程中的处理方式。这个过程主要是通过SKPOrderedSet来验证链路的合规性,确保链路在高频率下的稳定性、可靠性和时序准确性。我们来逐步解读这......
  • 找不到或无法加载主类 .encoding=utf-8 解决
    问题1:在cmd命令行下执行以下命令的时候,报错:找不到或无法加载主类.encoding=utf-8java-Dfile.encoding=utf-8 -jarC:\Users\meiya\PycharmProjects\BMProduceV1.0.0.0\lib\plantuml.jar C:\Users\meiya\PycharmProjects\BMProduceV1.0.0.0\pumlFiles\deleteADebugComput......
  • 【NLP高频面题 - Transformer篇】Position encoding为什么选择相加而不是拼接呢?
    **【NLP高频面题-Transformer篇】Positionencoding为什么选择相加而不是拼接呢?**重要性:★首先明确:Transformer会对原始输入做嵌入(embedding),从而映射到需要的维度,可采用一个变换矩阵做矩阵乘积的方式来实现,Transformer中的positionembedding也是加在这个嵌入后......
  • 神经网络的德尔塔(Delta)到底是什么
    (本文假设读者已经了解梯度下降法及的推导过程,仅对的作用和意义进一步讨论)神经网络使用误差反向传播法更新权重和偏置参数的过程中,引入了一个重要的参数,这个到底是什么?是通过梯度下降法更新权重和偏置的过程中引入的,目的是计算权重或偏置的对损失函数的偏微分,来更新或。在这个......
  • 索引压缩算法 New PForDelta 简介以及使用 SIMD 技术的优化
     1.背景:搜索引擎与索引压缩 在搜索引擎或类似需要对海量文档进行检索的系统中,通常会构建倒排索引(InvertedIndex)。为降低存储成本、减少I/O并提升检索速度,对倒排索引所包含的大量整数序列进行压缩是一种行之有效的手段。•目标:在确保解压速度的同时,尽量获得更好的压缩......
  • 从位置到语境:解码 Contextual Position Encoding 的奥秘
    在自然语言处理(NLP)领域,Transformer模型已经成为了无可争议的主角。然而,尽管它们在许多任务中表现优异,却始终面临一个关键问题:如何有效地编码序列中的位置信息。传统的绝对位置编码(AbsolutePositionEncoding)和相对位置编码(RelativePositionEncoding)方法虽然解决了部分问......
  • Dictionary 添加重复的键值对
    Dictionary添加重复的键值对|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------------|-----------......
  • 使用 httputils + sbe (Simple Binary Encoding) 实现金融级 java rpc
    1、认识SimpleBinaryEncoding(sbe)高性能Java库Agrona的主要目标是减少性能瓶颈,通过提供线程安全的直接和原子缓冲区、无装箱操作的原始类型列表、开散列映射和集合以及锁-free队列等,为开发者在处理并发和低延迟场景时提供强大工具。SimpleBinaryEncoding(sbe)是Agr......
  • NLP 中文拼写检测纠正论文-04-Learning from the Dictionary
    拼写纠正系列NLP中文拼写检测实现思路NLP中文拼写检测纠正算法整理NLP英文拼写算法,如果提升100W倍的性能?NLP中文拼写检测纠正Paperjava实现中英文拼写检查和错误纠正?可我只会写CRUD啊!一个提升英文单词拼写检测性能1000倍的算法?单词拼写纠正-03-leetcodeedit-d......