1. 简介
上次更新时间:2024 年 4 月 8 日
文本嵌入
文本嵌入是指将文本数据转换为数值表示形式的过程。这些数值表示法(通常是向量)可捕获文本中字词的语义含义和字词之间的关系。假设如下情况:
文本就像一种复杂的语言,充满了细微差别和模糊性。
文本嵌入会将该语言转换为计算机可以理解和操控的更简单的数学格式。
文本嵌入的优势
- 实现高效处理:与原始文本相比,计算机处理数字表示法要快得多。这对于搜索引擎、推荐系统和机器翻译等任务至关重要。
- 捕获语义含义:嵌入不仅仅局限于字词的字面含义。它们可以捕获字词之间的上下文和关系,从而进行更细致的分析。
- 提升机器学习性能:文本嵌入可用作机器学习模型中的特征,从而在情感分析、文本分类和主题建模等任务中取得更好的效果。
文本嵌入的用例
文本嵌入通过将文本转换为数值表示法,在自然语言处理 (NLP) 领域解锁了各种应用。以下是一些关键用例:
1. 搜索引擎和信息检索:
借助文本嵌入,搜索引擎可以理解查询背后的语义含义,并将其与相关文档进行匹配,即使不存在确切关键字也是如此。
通过将搜索查询的嵌入与文档嵌入进行比较,搜索引擎可以识别涵盖类似主题或概念的文档。
2. 推荐系统:
推荐系统使用文本嵌入来分析用户通过评价、评分或浏览记录表达的行为和偏好。
然后,系统可以通过比较用户互动过的商品、文章或其他内容的嵌入,推荐类似项。
3. 抄袭检测:
比较两段文本的嵌入有助于发现它们在语义结构上的显著相似之处,从而识别潜在的抄袭行为。
以上只是一些示例,随着文本嵌入技术的不断发展,可能性会不断增加。随着计算机通过嵌入更好地理解语言,我们期待未来会有更多创新应用。
textembedding-gecko@003
Textembedding-gecko@003 是 Google Cloud Platform (GCP) 通过 Vertex AI 及其 AI 工具和服务套件提供的预训练文本嵌入模型的特定版本。
构建内容
在此 Codelab 中,您将构建一个 Python 脚本。此脚本将执行以下操作:
- 使用 Vertex API 调用 textembedding-gecko@003,并将文本转换为文本嵌入(向量)。
- 创建由文本及其矢量组成的模拟数据库
- 通过比较向量,对模拟的矢量数据库执行查询,并获取最可能的回答。
学习内容
- 如何在 GCP 中使用文本嵌入
- 如何调用 textembedding-gecko@003
- 如何在 Workbench 中运行此脚本
- 如何使用 Vertex AI Workbench 执行脚本
所需条件
- 最新版 Chrome
- 了解 Python
- Google Cloud 项目
- 对 Vertex AI Workbench 的访问权限
2. 准备工作
创建 Vertex AI Workbench 实例
- 在 Google Cloud 控制台的“项目选择器”页面上,选择或创建一个 Google Cloud 项目。
- 前往项目选择器
- 确保您的 Google Cloud 项目已启用结算功能。
- 启用 Notebooks API。
您可以使用 Google Cloud 控制台、gcloud CLI 或 Terraform 创建 Vertex AI Workbench 实例。在本教程中,我们将使用 Google Cloud 控制台创建该项目。如需详细了解其他方法,请点击此处。
- 在 Google Cloud 控制台中,前往“实例”页面(可在 Vertex AI 菜单的“Notebooks”部分访问),然后点击“Workbench”。
- 前往“实例”。
- 点击“新建”。
- 在“创建实例”对话框的“详细信息”部分中,为新实例提供以下信息:
名称:为新实例提供名称。 名称必须以字母开头,后面最多可跟 62 个小写字母、数字或连字符 (-),但不能以连字符结尾。
区域和可用区:为新实例选择区域和可用区。为获得最佳网络性能,请选择与您的地理位置最近的区域。
无需安装 GPU
在“网络”部分中,提供以下信息:
网络:调整网络选项,以在宿主项目中使用当前项目的网络或共享 VPC 网络(如果已配置)。如果您在宿主项目中使用共享 VPC,则还必须在服务项目中向 Notebooks Service Agent 授予 Compute Network User 角色 (roles/compute.networkUser)。
在“网络”字段中:选择所需的网络。您可以选择 VPC 网络,只要该网络启用了专用 Google 访问通道或者可以访问互联网即可
在“子网”字段中:选择所需的子网。您可以选择默认的。
在“实例”属性中,您可以保留默认值,即 e2-standard-4。
- 点击“创建”。
Vertex AI Workbench 会创建实例并自动启动该实例。当实例可供使用时,Vertex AI Workbench 会激活一个“打开 JupyterLab”链接。点击该图标。
创建 Python 3 笔记本
- 在 Jupyterlab 中,点击启动器的“Notebook”部分中带有 Python 徽标的图标(即“Python3”)。
- 系统会创建一个名为“Untitled”且扩展名为 ipynb 的 Jupyter 笔记本。
- 您可以使用左侧的文件浏览器部分重命名该文件,也可以将其保持不变。
现在,我们可以开始在笔记本中编写代码了。
3. 导入所需的库
创建实例并打开 Jupyterlab 后,我们需要安装此 Codelab 所需的所有库。
我们需要:
- numpy
- pandas
- TextEmbeddingInput、TextEmbeddingModel(来自 vertexai.language_models)
将以下代码复制并粘贴到单元格中:
from vertexai.language_models import TextEmbeddingInput, TextEmbeddingModel
import numpy as np
import pandas as pd
此时的代码如下所示:
4. 创建模拟矢量数据库
为了测试我们的代码,我们将创建一个数据库,其中包含文本及其使用 gecko@003 文本嵌入模型转换的相应矢量。
我们的目标是让用户搜索文本、将其转换为向量,然后在数据库中搜索该向量,并返回最接近的结果。
我们的向量数据库将包含 3 条记录,我们将按如下方式创建它:
将以下代码复制并粘贴到新单元格中。
DOCUMENT1 = {
"title": "Operating the Climate Control System",
"content": "Your Googlecar has a climate control system that allows you to adjust the temperature and airflow in the car. To operate the climate control system, use the buttons and knobs located on the center console. Temperature: The temperature knob controls the temperature inside the car. Turn the knob clockwise to increase the temperature or counterclockwise to decrease the temperature. Airflow: The airflow knob controls the amount of airflow inside the car. Turn the knob clockwise to increase the airflow or counterclockwise to decrease the airflow. Fan speed: The fan speed knob controls the speed of the fan. Turn the knob clockwise to increase the fan speed or counterclockwise to decrease the fan speed. Mode: The mode button allows you to select the desired mode. The available modes are: Auto: The car will automatically adjust the temperature and airflow to maintain a comfortable level. Cool: The car will blow cool air into the car. Heat: The car will blow warm air into the car. Defrost: The car will blow warm air onto the windshield to defrost it."}
DOCUMENT2 = {
"title": "Touchscreen",
"content": "Your Googlecar has a large touchscreen display that provides access to a variety of features, including navigation, entertainment, and climate control. To use the touchscreen display, simply touch the desired icon. For example, you can touch the \"Navigation\" icon to get directions to your destination or touch the \"Music\" icon to play your favorite songs."}
DOCUMENT3 = {
"title": "Shifting Gears",
"content": "Your Googlecar has an automatic transmission. To shift gears, simply move the shift lever to the desired position. Park: This position is used when you are parked. The wheels are locked and the car cannot move. Reverse: This position is used to back up. Neutral: This position is used when you are stopped at a light or in traffic. The car is not in gear and will not move unless you press the gas pedal. Drive: This position is used to drive forward. Low: This position is used for driving in snow or other slippery conditions."}
documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]
df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db
该代码如下所示:
我们来分析一下代码
在变量 DOCUMENT1、DOCUMENT2 和 DOCUMENT3 中,我们存储了一个字典,该字典将模拟带有标题和内容的文档。这些“文档”是指 Google 汽车的模拟手册。
在下一行中,我们将使用这 3 个文档(字典)创建一个列表。
documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]
最后,利用 pandas,我们从该列表中创建一个数据框,该数据框将称为 df_initial_db。
df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db
5. 创建文本嵌入
现在,我们将使用 gecko@003 模型为模拟文档数据库中的每条记录获取文本嵌入。
将以下代码复制并粘贴到新单元格中:
def embed_fn(df_input):
list_embedded_values = []
for index, row in df_input.iterrows():
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
list_embedded_values.append(embeddings[0].values)
df_input['Embedded text'] = list_embedded_values
return df_input
df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db
该代码如下所示:
我们来分析一下代码
我们定义了一个名为 embed_fn 的函数,该函数将接收一个 Pandas DataFrame 作为输入,其中包含要执行嵌入的文本。然后,该函数会返回编码为矢量的文本。
def embed_fn(df_input):
list_embedded_values = []
for index, row in df_input.iterrows():
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
list_embedded_values.append(embeddings[0].values)
df_input['Embedded text'] = list_embedded_values
return df_input
我们将在名为 list_embedded_values 的列表中存储和附加每行的编码文本。
使用 pandas 中的 iterrows 方法,我们可以迭代数据框架中的每一行,从“文本”列(其中包含模拟数据库中的手动信息)中获取值。
为了使用 gecko@003 模型发送常规文本并返回其矢量,我们会初始化变量模型,并通过调用 TextEmbeddingModel.from_pretrained 函数来设置要使用的模型。
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
然后,在变量嵌入中,我们通过 model.get_embeddings 函数捕获发送的文本的向量。
在函数的末尾,我们会在数据框中创建一个名为“嵌入文本”的新列,其中包含根据 gecko@003 模型创建的矢量列表。
df_input['Embedded text'] = list_embedded_values
return df_input
最后,在变量 df_embedded_values_db 中,我们捕获了包含模拟数据库中原始数据的数据框架,以及包含每行矢量列表的新列。
df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db
6. 向矢量数据库提问
现在,我们的数据库包含文本及其向量,我们可以继续提出问题并查询数据库以查找答案。
为此,请将以下代码复制并粘贴到新单元格中:
question='How do you shift gears in the Google car?'
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(question)])
text_to_search=embeddings[0].values
len(text_to_search)
结果应如下所示:
我们来分析一下代码
与上一步中的函数类似,我们首先使用要向数据库询问的内容初始化 question 变量。
question='How do you shift gears in the Google car?'
然后,在模型变量中,我们通过 TextEmbeddingModel.from_pretrained 函数设置要使用的模型,在本例中,该模型为 gecko@003 模型。
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
在 embeddings 变量中,我们调用 model.get_embeddings 函数并传递要转换为向量的文本,在本例中,我们传递要询问的问题。
embeddings = model.get_embeddings([(question)])
最后,text_to_search 变量用于存储从问题转换的矢量列表。
我们输出矢量的长度只是作为参考。
text_to_search=embeddings[0].values
len(text_to_search)
7. 比较矢量
现在,我们的模拟数据库中有一个向量列表,并且一个问题已转换为向量。也就是说,我们现在可以将问题的向量与数据库中的所有向量进行比较,以找出哪个向量最接近问题,从而更准确地回答问题。
为此,我们将衡量问题的向量与数据库中的每个向量之间的距离。有多种方法可以衡量向量之间的距离,在本 Codelab 中,我们将使用欧几里得距离或 L2 范数。
在 Python 中,我们可以利用 numpy 函数来实现这一点。
将以下代码复制并粘贴到新单元格中:
list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1
for position, embedded_value in enumerate(list_embedded_text_from_db):
distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
print(distance)
if distance<shortest_distance:
shortest_distance=distance
shortest_position=position
print(f'The shortest distance is {shortest_distance} and the position of that value is {shortest_position}')
结果应如下所示:
我们来分析一下代码
首先,我们将存储数据库嵌入文本或向量的列转换为列表,并将其存储在 list_embedded_text_from_db 中。
我们还将 shortest_distance 变量初始化为 1,以便在找到实际最短距离之前不断更新它。
list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1
然后,我们使用 for 循环进行迭代,并获取问题向量与数据库中的每个向量之间的距离。
我们使用 numpy linalg.norm 函数计算它们之间的距离。
如果计算出的距离小于 shortest_distance 变量中的距离,则计算出的距离将设为此变量
然后,我们会捕获最短距离以及在列表中找到该距离的位置。在 shortest_distance 和 shortest_position 变量中。
for position, embedded_value in enumerate(list_embedded_text_from_db):
distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
print(distance)
if distance<shortest_distance:
shortest_distance=distance
shortest_position=position
8. 结果
知道问题与数据库之间距离最短的向量在列表中的位置后,我们就可以输出结果。
将以下代码复制并粘贴到新单元格中:
print("Your question was:\n "+question+ " \nAnd our answer is:\n "+
df_embedded_values_db.at[shortest_position, 'Title']+": "+
df_embedded_values_db.at[shortest_position, 'Text'])
执行后,您会看到如下内容:
9. 恭喜
恭喜,您已成功在实际用例中使用 textembedding-gecko@003 模型构建了第一个应用!
您学习了文本嵌入的基础知识,以及如何在 GCP Workbench 上使用 gecko003 模型。
现在,您已了解继续将所学知识应用于更多用例所需的关键步骤。
后续操作
查看下列 Codelab…