本电子书开源，欢迎 star 🌟，关注《LLM 应用开发实践笔记》

我的新书《LangChain编程从入门到实践》 已经开售！推荐正在学习AI应用开发的朋友购买阅读！

## Embedding 嵌入

本节对 Embedding（嵌入）概念进行介绍，同时会提到向量数据库相关知识，有助于后面的项目实现。

### 词嵌入是什么

向量是一个有方向和长度的量，可以用数学中的坐标来表示。例如，可以用二维坐标系中的向量表示一个平面上的点，也可以用三维坐标系中的向量表示一个空间中的点。在机器学习中，向量通常用于表示数据的特征。

而词嵌入是一种将文本这种离散数据映射到连续向量空间的方法，嵌入技术可以将高维的离散数据降维到低维的连续空间中，并保留数据之间的语义关系，从而方便进行机器学习和深度学习的任务。

例如：

> "机器学习"表示为 [1,2,3]
> "深度学习"表示为[2,3,3]
> "英雄联盟"表示为[9,1,3]

> 使用余弦相似度（余弦相似度是一种用于衡量向量之间相似度的指标，可以用于词嵌入之间的相似度）在计算机中来判断文本之间的距离：

> “机器学习”与“深度学习”的距离：

> "机器学习”与“英雄联盟“的距离"：

> “机器学习”与“深度学习”两个文本之间的余弦相似度更高，表示它们在语义上更相似。

### 词嵌入算法

词嵌入算法是指将文本数据转化为向量表示的具体算法，通常包括以下几个步骤：

- 分词：将文本划分成一个个单词或短语。
- 构建词汇表：将分词后的单词或短语建立词汇表，并为每个单词或短语赋予一个唯一的编号。
- 计算词嵌入：使用预训练的模型或自行训练的模型，将每个单词或短语映射到向量空间中。
- 计算词嵌入：将文本中每个单词或短语的向量表示取平均或加权平均，得到整个文本的向量表示。

常见的词嵌入算法包括 Word2Vec、GloVe、FastText 等。这些算法通过预训练或自行训练的方式，将单词或短语映射到低维向量空间中，从而能够在计算机中方便地处理文本数据。

### 词嵌入用途

词嵌入用于测量文本字符串的相关性，通常用于：

- 搜索（结果按与查询字符串的相关性排序）
- 聚类（其中文本字符串按相似性分组）
- 推荐（推荐具有相关文本字符串的项目）
- 异常检测（识别出相关性很小的异常值）
- 多样性测量（分析相似性分布）
- 分类（其中文本字符串按其最相似的标签分类）

### 使用词嵌入模型

- 可以使用 HuggingFace上能够处理词嵌入的开源模型，例如：uer/sbert-base-chinese-nli

      from sentence_transformers import SentenceTransformer
      model = SentenceTransformer('uer/sbert-base-chinese-nli')
      sentences = ["机器学习","深度学习","英雄联盟",]
      sentence_embeddings = model.encode(sentences)

- 使用之前介绍的 OpenAI 词嵌入API 可以将文本转换为向量，OpenAI API提供了多个词嵌入模型，这篇博客对它们的性能进行了比较，这里是性能最好的`text-embedding-ada-002`说明：

模型名称 | 价格 | 分词器 | 最大输入 token | 输出
--- | --- | --- | --- | ---
text-embedding-ada-002 | $0.000/1k tokens | cl100k_base | 8191 | 1536

#### 支持词嵌入的模型

- nghuyong/ernie-3.0-nano-zh
- shibing624/text2vec-base-chinese
- GanymedeNil/text2vec-large-chinese
- moka-ai/m3e-base
- 用于句子、文本和图像嵌入的Python库

  ### 矢量数据库

  - 为了快速搜索多个矢量，建议使用矢量数据库，下面是一些可选的矢量数据库：
- Pinecone，一个完全托管的矢量数据库
- Weaviate，一个开源的矢量搜索引擎
- Redis作为矢量数据库
- Qdrant，一个矢量搜索引擎
- Milvus，一个为可扩展的相似性搜索而构建的矢量数据库
- Chroma，Chroma是一个开源的嵌入式数据库，可以快速构建Python或JavaScript LLM应用程序。
- Typesense，快速的开源矢量搜索引擎
- Zilliz，数据基础设施，由Milvus提供技术支持
- FAISS 是Meta开源的用于高效搜索大规模矢量数据集的库

#### 性能优化✍️：

和传统数据库一样，可以使用工程手段优化矢量数据库搜索性能，最直接的就是更新索引算法 ，对索引数据进行分区优化。

1. 平面索引（FLAT）：将向量简单地存储在一个平面结构中，最基本的向量索引方法。

   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​
   - 余弦相似度（Cosine Similarity）：s i m(x,y)=x⋅y∥x∥∥y∥sim(x,y) = \frac{x \cdot y}{\|x\| \|y\|}s i m(x,y)=​∥x∥∥y∥​​x⋅y​​

2. 分区索引（IVF）：将向量分配到不同的分区中，每个分区建立一个倒排索引结构，最终通过倒排索引实现相似度搜索。

   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​
   - 余弦相似度（Cosine Similarity）：s i m(x,y)=x⋅y∥x∥∥y∥sim(x,y) = \frac{x \cdot y}{\|x\| \|y\|}s i m(x,y)=​∥x∥∥y∥​​x⋅y​​

3. 量化索引（PQ）：将高维向量划分成若干子向量，将每个子向量量化为一个编码，最终将编码存储在倒排索引中，利用倒排索引进行相似度搜索。

   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​
   - 汉明距离（Hamming Distance）：d(x,y)=∑i=1 n(x i⊕y i)d(x,y) = \sum_{i=1}^n (x_i \oplus y_i)d(x,y)=∑​i=1​n​​(x​i​​⊕y​i​​)，其中 ⊕\oplus⊕ 表示按位异或操作。

4. HNSW (Hierarchical Navigable Small World)：通过构建一棵层次化的图结构，从而实现高效的相似度搜索。

   - 内积（Inner Product）：s i m(x,y)=x⋅y sim(x,y) = x \cdot y s i m(x,y)=x⋅y
   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​

5. NSG (Navigating Spreading-out Graph)：通过构建一个分层的无向图来实现快速的相似度搜索。

   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​

6. Annoy (Approximate Nearest Neighbors Oh Yeah)：通过将高维空间的向量映射到低维空间，并构建一棵二叉树来实现高效的近似最近邻搜索。

   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​
   - 曼哈顿距离（Manhattan Distance）：d(x,y)=∑i=1 n∣x i−y i∣d(x,y) = \sum_{i=1}^n |x_i - y_i|d(x,y)=∑​i=1​n​​∣x​i​​−y​i​​∣

7. LSH (Locality-Sensitive Hashing)：通过使用哈希函数将高维的向量映射到低维空间，并在低维空间中比较哈希桶之间的相似度，实现高效的相似度搜索。

   - 内积（Inner Product）：s i m(x,y)=x⋅y sim(x,y) = x \cdot y s i m(x,y)=x⋅y
   - 欧式距离（Euclidean Distance）：d(x,y)=∑i=1 n(x i−y i)2 d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}d(x,y)=√​∑​i=1​n​​(x​i​​−y​i​​)​2​​​​​

### 参考资源

1. 向量数据库技术鉴赏：一个非常不错的讲解向量数据库科普视频

# results matching ""

# No results matching ""