最近在做文本向量化的工作,正好写点记录一下
文本向量化的历史
文本向量化技术的发展大致可以分为基于统计的方法和基于神经网络的方法两个阶段。
1. 基于统计的方法
1.1 词袋模型(Bag of Words, BOW)
BOW 是文本向量化的最早形式,通过统计文本中每个词出现的次数来构造向量。
- 特点: 简单直观,容易实现。
- 不足:
- 无法捕获词语间的语序和上下文关系。
- 随着词汇量增长,向量维度迅速增大,产生稀疏矩阵。
1.2 TF-IDF
为了弥补 BOW 对常见词(如“的”、“是”)权重分配不合理的缺陷,TF-IDF 引入了“逆文档频率”对词频进行加权。
- 特点:
- 能够提升关键词的权重,减小高频非关键信息词的影响。
- 常用于传统文本分类、信息检索等任务。
- 不足:
- 同样无法捕获上下文关系。
- 无法反映词语的深层语义信息。
1.3 共现矩阵与 LSA
基于分布假设,使用词语在上下文中的共现频率构建矩阵,并通过降维(如奇异值分解,SVD)获得低维表示。
- 代表方法: LSA(Latent Semantic Analysis)。
- 优点: 捕获了一定的语义关系,向量维度降低。
- 缺陷: 降维计算代价高,效果依赖数据稀疏性处理。
2. 基于神经网络的方法
2.1 词嵌入(Word Embedding)
神经网络方法从语义层面上对词语进行分布式表示,显著提升了词向量的表达能力。
- 代表方法: Word2Vec、GloVe。
- Word2Vec: 通过 Skip-gram 或 CBOW 模型学习词向量,捕捉语义关系。
- GloVe: 将共现矩阵信息与神经网络模型结合,效果接近 Word2Vec。
- 特点:
- 向量低维且密集,能够捕获语义关系(如“king - man + woman = queen”)。
- 词向量是静态的,对多义词处理不足。
2.2 上下文敏感表示
通过深度神经网络捕获词语在具体上下文中的动态表示,解决静态词嵌入的局限性。
- 代表模型:
- ELMo: 使用双向 LSTM,从上下文生成动态词向量。
- BERT: 基于 Transformer 的双向编码器,能够捕获更复杂的语义与上下文信息。
- 特点:
- 每个词的表示与其上下文相关,动态生成。
- 大幅提升了模型在机器翻译、问答等任务中的性能。
2.3 预训练语言模型
利用大规模预训练模型生成句子或文档级语义向量,开启了向量化的新阶段。
- 代表模型:
- Sentence-BERT(SBERT): 在 BERT 基础上进行微调,专门用于生成句子级向量。
- CLIP: 在多模态领域,通过对比学习生成文本向量。
- GPT 系列: 生成式模型同样可用于语义向量的提取。
- 特点:
- 丰富的语义信息,能够表示复杂上下文。
- 支持从词、句到文档的多粒度向量化表示。
3. 最新趋势
文本向量化技术在不断演进,逐步向多模态融合和更高效的表示方法发展。
- 多模态融合: 结合文本、图像、音频等信息,生成统一的向量表示。
- 稀疏向量化与密集向量化结合: 在提升效率的同时保留语义完整性。
- 对比学习: 提升向量表示的质量,使其更具区分能力。
M3 Embedding:
检索相关:
三个常见检索:稠密检索、稀疏检索、多向量检索
稠密检索:
取最后一层的[CLS] token
query q通过encoder变成hidden state的 $H_q$,那么query embedding就是 $e_q = norm(H_q[0])$ 。类似地我们可以得出对于document的embedding就是 $e_p = norm(H_p[0])$。因此计算query和document的内积即可得出相关性分数。
稀疏检索:
个人理解的稀疏检索是类似与TF-IDF,BM25这一类的,query和document都用稀疏向量表示,通过计算词项的匹配度(如余弦相似度)来进行检索。
这里的做法是模型输出的结果被用来计算query中每个 term 的重要性。具体地,term 作为 token,经过模型的处理后,会得到一个加权值。该加权值是通过以下方式计算的:
$$
w_{qt} \leftarrow \text{ReLU}(W_{lex}^T Hq[i])
$$
- $w_qt$ 代表的是query中某个 term(或 token)在嵌入空间中的权重
- $W_{lex}∈R^{d×1}$ 是模型中学习到的权重矩阵(将hidden states 映射到浮点数),H_q[i])是query向量,通过这个矩阵的转置计算得到 term 的权重
如果某个 term 在query中出现多次,模型会对该 term 的每次出现进行权重计算,但最终只保留该 term 在query中的最大权重。接下来是计算query和doc的相似性,模型使用类似的方法计算每个 term 的权重,并且计算query与doc之间的相似度。相似度的计算是通过以下公式:
$$
s_{lex} \leftarrow \sum_{t \in q \cap p} \left(w_{qt} * w_{pt}\right)
$$ - $s_{lex}$ 表示query和doc之间的相似度评分
- $t \in q \cap p$ 表示query和doc中共同出现的 term
- $w_{qt}$ 和 $w_{pt}$ 分别是query和doc中对应 term 的权重,二者的乘积会被累加起来,得到query和doc的最终相似度评分
多向量检索:
在多向量检索中,整个query和doc通过多个向量来表示,采用投影矩阵来将query和doc映射到一个新的空间,也就是利用整个输出嵌入来表示query和doc:
$$
E_q = \text{norm}(W_{\text{mul}}^T H_q)
$$
- $W_{mul}∈R ^{d×d}$ 是一个可学习的投影矩阵,将query的表示 $H_q$ 映射到新的空间。$H_q$ 是query的原始嵌入表示
- 最终的query向量 $E_q$ 是经过归一化处理后的结果,确保向量的长度一致,从而使得后续的相似度计算不受向量尺度的影响
doc的表示也是采用类似的方式,通过一个学习的投影矩阵对doc向量进行变换,得到doc在新的空间中的表示 $E_p$
相似度计算使用Max pooling,通过对query与doc向量的元素进行比较,选出最大值来计算二者之间的相关性:
$$
s_{\text{mul}} \leftarrow \frac{1}{N} \sum_{i=1}^{N} \max_{j=1}^{M} E_q[i] \cdot E_p^T[j]
$$ - N和M分别是query和doc的长度,即对应向量的维度
- $E_q[i]$ 和 $E_p[i]$ 分别表示query和doc中第i和第j维的值
通过计算query和doc在每个维度上对应元素的乘积,再取最大值,最后对所有query向量的最大值进行平均,得到query和doc之间的最终相似度。多向量检索将query和doc都映射到高维空间中,并通过多向量表示来捕捉query和doc的不同特征。
Self-Knowledge Distillation Loss:
损失函数的基本形式是基于InfoNCE loss的,看过clip的应该很熟悉这个Loss。核心思想就是表示查询和正样本、负样本之间的相似度差异。其基本公式为:
$$
\mathcal{L} = - \log \left( \frac{\exp(s(q, p^*)) / \tau}{\sum_{p’ \in P} \exp(s(q, p’) / \tau)} \right)
$$
这个损失函数的形式应该是对比学习中比较常见的。核心就是最大化正样本的相似度并最小化负样本的相似度,来优化模型的embedding表示
原生多目标训练不利于embedding的质量,为了优化检索过程,作者提出将多个检索方法的损失进行集成。公式中给出了一个集成的损失函数:
$$
s_{\text{inter}} \leftarrow s_{\text{dense}} + s_{\text{lex}} + s_{\text{mul}}
$$
- $s_{\text{dense}}$,$s_{\text{lex}}$,$s_{\text{mul}$分别是稠密检索、稀疏检索和多向量检索的Loss
这个Loss的目标是通过集成来自不同检索方法的知识,使得模型能够学习到更健壮的表示。损失函数的计算形式为:
$$
\mathcal{L}^* \leftarrow p(s_{\text{inter}}) \cdot \log(p(s_*))
$$ - $p(s_{\text{inter}}$ 表示通过集成后的损失计算得到的最终结果,进一步与 $p(s_*)$ 的对数进行乘积,目的是加强模型对查询和文档之间关系的建模
最终的损失函数是通过合并原始的损失函数 $\mathcal{L}$ 和自我知识蒸馏部分的损失 $L’$ 得到的:
$$
L_{\text{final}} = \mathcal{L} + L’
$$