Skip to content

Embedding

2 posts with the tag “Embedding”

向量归一化和相似度

在机器学习和深度学习中,对嵌入向量进行归一化(Normalization)至关重要,它能带来多方面的益处,尤其是在涉及到相似度计算、模型训练和数据表示时。归一化通常指的是将向量的长度(或范数)缩放为单位长度(通常为 L2 范数等于 1)。以下是归一化的主要必要性:

  • 避免特征尺度差异的影响: 不同的特征或模型生成的原始嵌入向量可能具有不同的尺度和范围。例如,一个模型的嵌入向量的数值可能在 -1 到 1 之间,而另一个模型的可能在 -100 到 100 之间。如果不进行归一化,在计算向量之间的距离或相似度时(如欧氏距离、点积),尺度较大的向量会占据主导地位,导致模型更关注这些尺度较大的特征,而忽略了尺度较小的特征中可能包含的重要信息。
  • 确保每个特征的贡献相等: 归一化可以将所有嵌入向量的元素缩放到相似的尺度,使得每个维度在距离和相似度计算中具有更公平的权重,从而提高模型的鲁棒性和泛化能力。
  • 提高余弦相似度的准确性: 余弦相似度是衡量两个向量方向之间夹角的余弦值,常用于计算文本、图像等嵌入的语义相似性。当向量未归一化时,向量的长度(magnitude)会影响点积的值,从而影响余弦相似度的结果。归一化后,向量的长度变为 1,此时余弦相似度就直接等于向量的点积,能够更准确地反映向量方向上的相似程度。
  • 改善基于距离的度量: 对于依赖欧氏距离等距离度量的算法(如 K-近邻、K-均值聚类),归一化可以确保距离的计算不会被尺度较大的特征所主导,从而得到更符合语义或特征实际分布的结果。
  • 避免梯度爆炸或消失: 在神经网络训练中,如果输入的特征尺度过大或过小,可能导致梯度在反向传播过程中变得非常大(梯度爆炸)或非常小(梯度消失),从而影响模型的收敛速度和训练稳定性。归一化可以将输入特征限制在合理的范围内,有助于缓解这些问题。
  • 加快收敛速度: 当特征具有相似的尺度时,梯度下降等优化算法可以更有效地找到最优解,因为模型不需要在不同尺度的特征空间中来回震荡。
  • 减少模型对异常值的敏感性: 某些归一化方法(如 Z-score 归一化)可以降低异常值对模型的影响,使模型更加稳定。
  • 提升模型在不同数据集上的泛化能力: 通过统一特征的尺度,归一化可以帮助模型学习到更通用的模式,而不是过度依赖于特定数据集的尺度分布。

方便不同嵌入模型的比较和集成:

Section titled “方便不同嵌入模型的比较和集成:”
  • 统一不同模型的输出尺度: 不同的嵌入模型可能产生具有不同尺度范围的向量。归一化可以将它们的输出统一到一个共同的尺度,使得可以直接比较或组合来自不同模型的嵌入,从而进行更复杂的分析或构建更强大的系统。

总结

归一化是处理嵌入向量的一个关键步骤,它可以确保相似度计算的准确性,优化模型训练过程,提高模型性能和泛化能力,并方便不同嵌入之间的比较和集成。在大多数使用嵌入向量的机器学习和深度学习应用中,都强烈建议进行归一化处理。最常用的归一化方法是 L2 归一化,它将向量的长度缩放为单位长度。

相似度量用于衡量向量之间的相似性。选择合适的距离度量有助于显著提高分类和聚类性能。向量的相似度量有:余弦相似度(Cosine Similarity)、内积(Inner Product, IP)、欧氏距离(Euclidean Distance)、曼哈顿距离(Mahalanobis Distance)、余弦距离(Cosine Distance)、汉明距离(Hamming Distance)、Jaccard 相似度(Jaccard Similarity)、BM25 相似度(BM25 Similarity)等等。

Cosine(A, B) = (A · B) / (||A|| * ||B||)。它衡量的是两个向量方向上的一致性,忽略了向量的长度(模长)。它的取值范围是 [-1, 1],越接近 1 表示方向越一致。 例如,两个正比向量的余弦相似度为1,两个正交向量的余弦相似度为0,两个相反向量的余弦相似度为-1,余弦越大,两个向量之间的夹角越小,说明这两个向量之间的相似度越高。 用 1 减去它们的余弦相似度,就可以得到两个向量之间的余弦距离。

IP(A, B) = A · B。它计算的是两个向量的点积。这个值同时受到向量方向和向量模长的影响。如果两个向量方向一致,它们的模长越大,内积通常也越大。IP 的取值范围没有固定界限(取决于向量模长)。

3、同样的数据,内积 (IP) 能查到,但是余弦相似度查询不到

Section titled “3、同样的数据,内积 (IP) 能查到,但是余弦相似度查询不到”

因为内积查询需要计算两个向量的点积,而余弦相似度只需要计算两个向量的余弦值。

$~$

  • 如果向量是归一化的(即模长为1,||A|| = 1||B|| = 1),那么Cosine(A, B) = A · B = IP(A, B)。在这种情况下,使用余弦相似度和内积进行检索,得到的结果排序应该是完全相同的。

  • 如果向量不是归一化的,那么Cosine(A, B) = (A · B) / (||A|| * ||B||),而IP(A, B) = A · B。在这种情况下,使用余弦相似度和内积进行检索,得到的结果排序可能不同。


具体到这个现象来说:


  • 内积 (IP) 成功: 这很可能意味着你想要查找的那个目标数据向量,与你的查询向量之间的点积 (A · B) 相对较高。这个高点积可能是因为它们的方向比较接近,也可能是因为一个或两个向量的模长(长度)非常大,即使方向不是最接近的,较大的模长也导致了较高的内积得分,使其排在了前面。
  • 余弦相似度 (Cosine) 失败: 这表明,虽然目标向量和查询向量的内积可能较高(被 IP 检索到),但当除以各自的模长进行归一化计算后 ((A · B) / (||A|| * ||B||)),得到的余弦相似度得分反而不高。可能有其他向量,虽然它们的模长较小(导致 IP 得分不如目标向量),但它们与查询向量的方向更一致(角度更小),因此具有更高的余弦相似度得分,把真正的目标挤出了 top-k 结果。

总结来说可能原因是:


  • 向量未归一化: 这是最主要的原因。gte-Qwen2-7B-instruct 或你使用的其他嵌入模型产生的向量可能其模长不为 1。
  • 模长的影响: 能够被 IP 检索到的目标数据,很可能与查询向量的点积较大,这其中较大的模长起到了重要作用,弥补了方向上可能不是绝对最优的劣势。
  • 方向 vs. 模长: 其他数据可能在方向上与查询向量更接近(余弦相似度更高),但由于模长较小,其内积得分不如目标数据高。

取一个由模型产生的向量 v,计算其 L2 范数(模长):norm = np.linalg.norm(v)。如果 norm 不接近 1,那么向量就没有归一化。


检查向量是否归一化,可以使用以下代码:
from llama_index.embeddings.ollama import OllamaEmbedding
import numpy as np
def is_normalized(vector):
return np.isclose(np.linalg.norm(vector)1.0
def normalize(vector):
if is_normalized(vector):
return vector
return vector / np.linalg.norm(vector)
def normalize_vectors(vectors):
return [normalize(vector) for vector in vectors]
embedd = OllamaEmbedding(
# model_name="Embedding-GGUF/gte-Qwen2-1.5B-instruct-Q4_K_M-GGUF",
model_name="modelscope.cn/Embedding-GGUF/gte-Qwen2-7B-instruct-Q4_K_M-GGUF:latest",
base_url="http://localhost:11434",
normalize=True
)
embedding = embedd.get_text_embedding("hello")
print(f"向量是否归一化: {is_normalized(embedding)}")

Embedding

简单来说,Embedding 模型是一种将高维度、离散或复杂的输入数据(例如文字、图片、用户ID、商品ID等)转换为低维度、连续的向量(Vector)表示的技术或模型。这个生成的向量被称为“嵌入”(Embedding)。

想象一下,我们有很多词语,比如“国王”、“女王”、“男人”、“女人”。直接用这些词语本身,计算机很难理解它们之间的关系。Embedding 模型就能学习到将这些词语映射到一个多维空间中的点(向量)。在这个空间里,“国王”和“男人”的距离会比较近,“女王”和“女人”的距离会比较近,而“国王”和“女王”之间可能存在一种类似于“男人”到“女人”的关系向量。

  1. 降维: 将原本可能维度非常高(比如用 one-hot 编码表示词语,维度可能高达几万甚至几十万)或者非结构化的数据,映射到一个维度相对较低(通常是几十到几百维)的连续向量空间。

  2. 保留语义/关系: 这个映射过程不是随机的,而是通过学习大量数据得到的。目标是让转换后的向量能够捕捉到原始数据中的内在含义、相似性或关系。在向量空间中,语义相近或关系类似的对象,它们的向量也会比较接近或具有特定关联。

  3. 利于计算: 计算机更擅长处理数值型的向量。将各种类型的数据转换为统一的向量表示后,就可以方便地进行各种数学运算,如计算相似度(点积、余弦相似度)、距离(欧氏距离)等,进而应用于各种下游任务。

Embedding 模型的能力非常广泛,是许多现代机器学习和人工智能应用的基础模块。主要作用包括:

  1. 语义理解与表示 (Semantic Understanding & Representation):

    • 自然语言处理 (NLP): 这是 Embedding 最经典的应用领域。

      • 词嵌入 (Word Embeddings):Word2Vec, GloVe, FastText,将单词映射为向量,捕捉词语的语义和语法关系。

      • 句子/文档嵌入 (Sentence/Document Embeddings):Sentence-BERT, Universal Sentence Encoder,将整个句子或文档表示为向量,用于文本分类、情感分析、问答系统、文本相似度计算等。

    • 知识图谱 (Knowledge Graphs): 将实体(如人物、地点)和关系(如“出生在”、“工作于”)嵌入到向量空间,用于知识推理和链接预测。

  2. 相似性计算与搜索 (Similarity Calculation & Search):

    • 信息检索/语义搜索: 通过比较查询(Query)的 Embedding 和数据库中文档/物品的 Embedding,找到语义最相关的结果,而不是仅仅基于关键词匹配。例如,搜索“夏天穿的透气鞋子”,能找到包含“凉鞋”、“网面运动鞋”等词语的商品,即使查询中没有这些具体词。

    • 图像/音频检索: 将图像或音频转换为 Embedding,实现以图搜图、以歌搜歌等功能。

  3. 推荐系统 (Recommendation Systems):

    • 协同过滤: 将用户(User)和物品(Item)都嵌入到同一个向量空间。可以通过计算用户 Embedding 和物品 Embedding 的相似度来预测用户可能喜欢的物品,或者找到具有相似兴趣的用户(计算用户 Embedding 之间的相似度)。

    • 内容推荐: 基于物品内容的 Embedding(如文章内容、商品描述)来推荐相似的物品。

  4. 分类与聚类 (Classification & Clustering):

    • 将原始数据转换为 Embedding 后,这些向量可以作为特征输入到传统的分类器(如 SVM、逻辑回归)或聚类算法(如 K-Means)中,通常能提高模型的性能,因为 Embedding 包含了更丰富的语义信息。
  5. 异常检测 (Anomaly Detection):

    • 正常的数据点在 Embedding 空间中可能会聚集在一起,而异常点则可能远离这些聚集区,从而可以被识别出来。
  6. 数据可视化 (Data Visualization):

    • 虽然 Embedding 本身是高维的,但可以使用降维技术(如 t-SNE, PCA)将其投影到二维或三维空间进行可视化,帮助我们直观地理解数据点之间的关系和结构。

总结来说,Embedding 模型的核心价值在于:

Section titled “总结来说,Embedding 模型的核心价值在于:”
  • 将复杂数据转化为计算机易于处理的数值向量。

  • 在转化过程中捕捉并保留数据的内在语义和关系。

  • 作为许多高级 AI 应用(如搜索、推荐、NLP)的基础,提升其效果和智能程度。

它就像是为不同类型的数据(文本、图像、用户行为等)构建了一个通用的“语义坐标系”,使得我们可以在这个统一的空间中进行有意义的比较、查找和分析。