
# 文本向量化
向量化模型是将人类语言和各类信息"翻译"成计算机能够直接进行数学处理和逻辑推理的"通用语言"，就像为各种信息（例如一段话、一张图片）创建一个专属的"数字指纹"。有了这个数字指纹，计算机就能理解信息的意思，并判断不同信息之间的相似性，而不仅是做表面的文字匹配。
**核心思想：从"关键词"到"语义"**
- 传统方法：例如搜索"苹果"，只能找到包含"苹果"这两个字的文章。
- 向量化模型：将"苹果"转换成一个向量（一组数字）。这个向量同时包含着"水果"、"甜"、"公司"、"手机"等多种语义。当您搜索时，它能在向量空间里找到与"科技"、"手机"等概念相近的文章，即使文章里根本没出现"苹果"二字。
您可以使用文本向量化模型服务，将文本数据转换为数值向量，旨在捕捉文本的语义、语法或统计特征，使计算机能够处理和理解自然语言。
#### 应用场景
表1文本向量化场景 
| 场景      | 描述                                     |
|:---|:---|
| 语义搜索与匹配 | 用向量相似度（如余弦相似度）实现智能搜索、问答系统。             |
| 文本分类与聚类 | 向量作为特征输入分类器（如新闻分类、情感分析）或聚类算法（如用户评论分组）。 |
| 推荐系统    | 将用户评论、商品描述向量化，计算内容相似度以增强推荐效果。          |
| 异常检测    | 在安全或风控领域，检测与正常文本向量差异较大的内容（如垃圾邮件、虚假评论）。 |
   
#### 支持模型
文本向量化支持的模型请见[文本向量化](https://support.huaweicloud.com/model-list-maas/model_list_0001.html#section3)。
#### API说明
模型调用的完整参数列表请见[创建文本向量化](https://support.huaweicloud.com/model-call-maas/model-call-027.html)。
#### 前提条件
- 已在"模型推理 \> 在线推理 \> 预置服务"页签开通预置服务。详情请见[开通MaaS预置服务](https://support.huaweicloud.com/model-call-maas/model-call-052.html)。
- （可选）如果需要控制服务调用流量，可提前创建自定义接入点，详情请参见[MaaS创建自定义接入点](https://support.huaweicloud.com/model-call-maas/model-call-048.html)。

- 已获取API Key。详情请见[在MaaS管理API Key](https://support.huaweicloud.com/model-call-maas/model-call-049.html)。
- 已获取模型服务的model参数值。详情请见[文本向量化](https://support.huaweicloud.com/model-list-maas/model_list_0001.html#section3)。
- 如果使用OpenAI SDK方式进行调用，请下载安装SDK（Python SDK：pip install openai）。
 
#### 快速开始
以下为通过调用BGE-M3模型，将输入的文本字符串转换为向量表示的示例代码。可通过model参数替换模型，model参数详情请参见[文本向量化](https://support.huaweicloud.com/model-list-maas/model_list_0001.html#section3)。
- [Python]
  ```
  import requests
  import json
  if __name__ == '__main__':
      url = "https://api.modelarts-maas.com/v1/embeddings"  # API地址
      api_key = "MAAS_API_KEY"  # 把MAAS_API_KEY替换成已获取的API Key
      # Send request.
      headers = {
          'Content-Type': 'application/json',
          'Authorization': f'Bearer {api_key}'
      }
      text = "这是一只小猫"
      data = {
          "model": "bge-m3",  # 模型名称
          "input": text,
          "encoding_format": "float"  # 取值范围："float","base64"
      }
      response = requests.post(url, headers=headers, data=json.dumps(data), verify=False)
      # Print result.
      print(response.status_code)
      print(response.text)
  ```
- [Curl]
  ```
  curl -X POST "https://api.modelarts-maas.com/v1/embeddings" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $MAAS_API_KEY" \
    -d '{
      "model": "bge-m3",
      "input": [
        "这是一只小猫",
        "这是一只小狗"
      ],
      "encoding_format": "float"
    }'
  ```
- [Java]
  建议JDK版本为15+。
  ```
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.time.Duration;
  public class EmbeddingsRequest {
      public static void main(String[] args) {
          // 接口地址
          String apiUrl = "https://api.modelarts-maas.com/v1/embeddings";
          // 把MAAS_API_KEY替换成已获取的API Key
          String apiKey = "MAAS_API_KEY";
          // 替换为你要调用的模型名称，例如 "bge-m3"
          String modelName = "bge-m3";
          // 构造请求体
          String requestBody = String.format(
                  """
                      {
                          "model": "%s",
                          "input":"这是一只小猫",
                          "encoding_format": "float"
                      }""", modelName);
          // 创建 HttpClient
          HttpClient client = HttpClient.newBuilder()
                  .connectTimeout(Duration.ofSeconds(10))
                  .build();
          // 创建请求
          HttpRequest request = HttpRequest.newBuilder()
                  .uri(URI.create(apiUrl))
                  .header("Content-Type", "application/json")
                  .header("Authorization", "Bearer " + apiKey)
                  .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                  .build();
          try {
              // 发送请求并打印结果
              HttpResponse<String> response = client.send(
                      request, HttpResponse.BodyHandlers.ofString());
              System.out.println("HTTP Status: " + response.statusCode());
              System.out.println("Response Body:\n" + response.body());
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  ```
#### 应用场景示例
- **文本文件逐行转换**
  向量化模型可以基于您的文档生成嵌入向量。此处以embedding_test.txt作为示例文件，您可以通过代码对文本文件逐行转化成向量。
  embedding_test.txt内容如下：
  ```
  这是一只小猫
  这是一只小狗
  ```
  示例代码如下：
  ```
  #Python
  import json
  import requests
  if __name__ == '__main__':
      url = "https://api.modelarts-maas.com/v1/embeddings"  # API地址
      api_key = "MAAS_API_KEY"  # 把MAAS_API_KEY替换成已获取的API Key
      # Send request.
      headers = {
          'Content-Type': 'application/json',
          'Authorization': f'Bearer {api_key}'
      }
      file_path = "./embedding_test.txt"
      # 从文件读取文本并生成向量
      with open(file_path, "r", encoding="utf-8") as f:
          # 按行分割文本（每行作为一个独立输入）
          texts = [line.strip() for line in f if line.strip()]
      data = {
          "model": "bge-m3",  # 模型名称
          "input": texts,
          "encoding_format": "float"  # 取值范围："float","base64"
      }
      response = requests.post(url, headers=headers, data=json.dumps(data), verify=False)
      # Print result.
      print(response.status_code)
      print(response.text)
  ```
  

- **语义搜索与匹配**
  用向量相似度（如余弦相似度）实现智能搜索、问答系统。
  ```
  #Python
  import numpy as np
  import httpx
  from typing import List
  from openai import OpenAI
  from openai.types import Embedding
  base_url = "https://api.modelarts-maas.com/v1"  # API地址
  api_key = "MAAS_API_KEY"  # 把MAAS_API_KEY替换成已获取的API Key
  def embedding(texts) -> List[Embedding]:
      """文本转换为数值向量"""
      client = OpenAI(api_key=api_key, base_url=base_url, http_client=httpx.Client(verify=False))
      response = client.embeddings.create(
          model="bge-m3",  # model参数
          input=texts,  # input类型可为string or string[]
          encoding_format="float"  # 取值范围："float","base64"
      )
      return response.data
  def cosine_similarity(a, b):
      """计算余弦相似度"""
      return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
  def semantic_search(query, documents, top_k=5):
      """语义搜索"""
      # 生成查询向量
      query_resp = embedding(query)
      query_embedding = query_resp[0].embedding
      # 生成文档向量
      doc_resp = embedding(documents)
      # 计算相似度
      similarities = []
      for i, doc_emb in enumerate(doc_resp):
          similarity = cosine_similarity(query_embedding, doc_emb.embedding)
          similarities.append((i, similarity))
      # 排序并返回top_k结果
      similarities.sort(key=lambda x: x[1], reverse=True)
      return [(documents[i], sim) for i, sim in similarities[:top_k]]
  # 使用示例
  documents_exp = [
      "深度学习是机器学习的一个分支，它使用多层神经网络进行特征学习",
      "Python是一种流行的编程语言，广泛用于数据科学和人工智能",
      "Transformer模型在自然语言处理领域取得了革命性进展",
      "苹果公司发布了新款iPhone手机，搭载了强大的A系列芯片",
      "气候变化导致全球气温上升，海平面逐年升高"
  ]
  query_exp = "机器学习技术"
  results = semantic_search(query_exp, documents_exp, top_k=2)
  for doc, sim_result in results:
      print(f"相似度: {sim_result:.3f}, 文档: {doc}")
  ```
  
 
- **电影推荐系统**
  将用户喜好的电影类型数据向量化，计算所有电影与用户喜好电影类型的相似度以进行电影推荐。
  ```
  #Python
  import numpy as np
  import httpx
  from typing import List
  from openai import OpenAI
  from openai.types import Embedding
  base_url = "https://api.modelarts-maas.com/v1"  # API地址
  api_key = "MAAS_API_KEY"  # 把MAAS_API_KEY替换成已获取的API Key
  def embedding(texts) -> List[Embedding]:
      """文本转换为数值向量"""
      client = OpenAI(api_key=api_key, base_url=base_url, http_client=httpx.Client(verify=False))
      response = client.embeddings.create(
          model="bge-m3",  # model参数
          input=texts,  # input类型可为string or string[]
          encoding_format="float"  # 取值范围："float","base64"
      )
      return response.data
  def cosine_similarity(a, b):
      """计算余弦相似度"""
      return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
  def movie_recommendation(movie_types, movies, top_k=10):
      """电影推荐"""
      
      embedding_result = embedding(movie_types)
      # 生成用户喜好类型电影向量
      user_embedding = np.mean([
          emb.embedding for emb in embedding_result
      ], axis=0)
      # 生成所有电影向量结果
      movie_result = embedding(movies)
      # 根据用户喜好计算电影推荐分数
      movie_scores = []
      for i, item_emb in enumerate(movie_result):
          score = cosine_similarity(user_embedding, item_emb.embedding)
          movie_scores.append((movies[i], score))
      # 生成最终结果
      movie_scores.sort(key=lambda x: x[1], reverse=True)
      return movie_scores[:top_k]
  # 使用示例
  movie_types = ["浪漫爱情类", "科幻动作类", "太空探险类"]
  movies = [
      "科幻电影：星际穿越，讲述太空探险和时间旅行",
      "爱情电影：泰坦尼克号，浪漫的爱情故事",
      "动作电影：速度与激情，飙车和冒险",
      "科幻电影：阿凡达，外星世界的冒险",
      "喜剧电影：三傻大闹宝莱坞，校园喜剧",
      "科幻电影：黑客帝国，虚拟现实和人工智能",
      "爱情电影：罗马假日，浪漫的邂逅",
      "动作电影：007系列，间谍冒险",
      "动画电影：疯狂动物城，动物都市的冒险",
      "恐怖电影：闪灵，恐怖惊悚"
  ]
  recommendations_result = movie_recommendation(movie_types, movies)
  for movie, score in recommendations_result:
      print(f"推荐分数: {score:.3f}, 电影: {movie}")
  ```
  
