教程:使用 Eventhouse 作为矢量数据库
在本教程中,您将学习如何使用 Eventhouse 作为矢量数据库,在实时智能中存储和查询矢量数据。 有关矢量数据库的常规信息,请参阅 Vector 数据库
给定方案包括在维基百科页面上使用语义搜索来查找包含常见主题的页面。 你将使用一个可用的示例数据集,其中包含数万个维基百科页面的矢量。 这些页面嵌入了 OpenAI 模型,可为每个页面生成矢量。 矢量以及与页面相关的一些相关元数据随后存储在 Eventhouse 中。 你可以使用此数据集来查找彼此相似的页面,或查找与要查找的某些主题相似的页面。 例如,假设你想查找“19 世纪著名的女性科学家”。你将使用同一 OpenAI 模型对此短语进行编码,然后对存储的维基百科页面数据运行矢量相似度搜索,以查找具有最高语义相似度的页面。
具体来说,在本教程中,你将执行以下操作:
- 使用矢量列的
Vector16
编码,准备 Eventhouse 中的表。 - 将矢量数据从预先嵌入的数据集存储到 Eventhouse。
- 使用 Open AI 模型,嵌入自然语言查询。
- 使用 series_cosine_similarity KQL 函数,计算查询嵌入矢量与 Wiki 页面矢量之间的相似度。
- 查看相似度最高的行,以获取与搜索查询最相关的 Wiki 页面。
此流程可以可视化,如下所示:
先决条件
- 具有已启用 Microsoft Fabric 的容量的工作区
- 工作区中的 eventhouse
- 部署了 text-embedding-ada-002(版本 2) 模型的 Azure OpenAI 资源。 此模型当前仅在特定区域中可用。 有关详细信息,请参阅创建资源。
- 确保已在 Azure OpenAI 资源上启用本地身份验证。
- 从 GitHub 存储库下载示例笔记本
注意
虽然本教程使用 Azure OpenAI,但你可以使用任何嵌入模型提供程序,为文本数据生成矢量。
准备 Eventhouse 环境
在此设置步骤中,你要在 Eventhouse 中创建一个表,其中包含必需的列和编码策略,以便存储矢量数据。
在实时智能中浏览到工作区主页。
选择在先决条件部分中创建的 Eventhouse。
选择要在其中存储矢量数据的目标数据库。 如果没有数据库,可以通过选择“添加数据库”来创建一个数据库。
选择“浏览我的数据”。 复制/粘贴以下 KQL 查询,以便创建包含所需列的表:
.create table Wiki (id:string,url:string,['title']:string,text:string,title_vector:dynamic,content_vector:dynamic,vector_id:long)
复制/粘贴以下命令,以便设置矢量列的编码策略。 按顺序运行这些命令。
.alter column Wiki.title_vector policy encoding type='Vector16' .alter column Wiki.content_vector policy encoding type='Vector16'
将矢量数据写入 Eventhouse
通过以下步骤导入嵌入式维基百科数据并将其写入 Eventhouse:
导入笔记本
- 从 GitHub 存储库下载示例笔记本。
- 浏览到 Fabric 环境。 在体验切换器中,选择“开发”,然后选择你的工作区。
- 选择“导入”>“笔记本”>“从此计算机”>“上传”,燃烧后选择在上一步中下载的笔记本。
- 导入完成后,从工作区打开导入的笔记本。
将数据写入 Eventhouse
运行单元格以设置环境。
%%configure -f {"conf": { "spark.rpc.message.maxSize": "1024" } }
%pip install wget
%pip install openai
运行单元格以下载预计算嵌入。
import wget embeddings_url = "https://cdn.openai.com/API/examples/data/vector_database_wikipedia_articles_embedded.zip" # The file is ~700 MB so it might take some time wget.download(embeddings_url)
import zipfile with zipfile.ZipFile("vector_database_wikipedia_articles_embedded.zip","r") as zip_ref: zip_ref.extractall("/lakehouse/default/Files/data")
import pandas as pd from ast import literal_eval article_df = pd.read_csv('/lakehouse/default/Files/data/vector_database_wikipedia_articles_embedded.csv') # Read vectors from strings back into a list article_df["title_vector"] = article_df.title_vector.apply(literal_eval) article_df["content_vector"] = article_df.content_vector.apply(literal_eval) article_df.head()
若要写入 eventhouse,请输入群集 URI 和数据库名称,URI 可在系统概述页上找到。 该表是在笔记本中创建的,随后在查询中引用。
# replace with your Eventhouse Cluster URI, Database name, and Table name KUSTO_CLUSTER = "Eventhouse Cluster URI" KUSTO_DATABASE = "Database name" KUSTO_TABLE = "Wiki"
运行剩余单元格,以便将数据写入 Eventhouse。 执行此操作可能需要一些时间。
kustoOptions = {"kustoCluster": KUSTO_CLUSTER, "kustoDatabase" :KUSTO_DATABASE, "kustoTable" : KUSTO_TABLE } access_token=mssparkutils.credentials.getToken(kustoOptions["kustoCluster"])
#Pandas data frame to spark dataframe sparkDF=spark.createDataFrame(article_df)
# Write data to a table in Eventhouse sparkDF.write. \ format("com.microsoft.kusto.spark.synapse.datasource"). \ option("kustoCluster",kustoOptions["kustoCluster"]). \ option("kustoDatabase",kustoOptions["kustoDatabase"]). \ option("kustoTable", kustoOptions["kustoTable"]). \ option("accessToken", access_token). \ option("tableCreateOptions", "CreateIfNotExist").\ mode("Append"). \ save()
查看 Eventhouse 中的数据
此时,你可以通过浏览数据库详细信息页,来验证数据是否已写入 Eventhouse。
- 在实时智能中浏览到工作区主页。
- 选择在上一部分提供的数据库项。 你应该看到已写入“Wiki”表的数据的摘要。
针对搜索词生成嵌入
现在,你将嵌入的维基百科数据存储在 Eventhouse 中,可以将这些数据用作引用,以便查找特定文章上的页面。 为了进行比较,可以嵌入搜索词,然后在搜索词和维基百科页面之间进行比较。
若要成功对 Azure OpenAI 进行调用,则需要终结点、密钥和部署 ID。
变量名称 | 值 |
---|---|
endpoint | 从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 或者,可以在“Azure OpenAI Studio”>“操场”>“代码视图”中找到该值。 示例终结点为:https://docs-test-001.openai.azure.com/ 。 |
API 密钥 | 从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 可以使用 KEY1 或 KEY2。 |
部署 ID | 可以在 Azure OpenAI Studio 的“部署”部分下找到此值。 |
运行 Azure OpenAI 单元格时,使用表中的信息。
重要
必须在 Azure Open AI 资源上启用本地身份验证,才能使用 API 密钥。
import openai
openai.api_version = '2022-12-01'
openai.api_base = 'endpoint' # Add your endpoint here
openai.api_type = 'azure'
openai.api_key = 'api key' # Add your api key here
def embed(query):
# Creates embedding vector from user query
embedded_query = openai.Embedding.create(
input=query,
deployment_id="deployment id", # Add your deployment id here
chunk_size=1
)["data"][0]["embedding"]
return embedded_query
searchedEmbedding = embed("most difficult gymnastics moves in the olympics")
#print(searchedEmbedding)
查询相似度
查询直接从笔记本运行,并使用从上一步返回的嵌入,与存储在 Eventhouse 中的嵌入维基百科页面进行比较。 此查询使用余弦相似度函数并返回前 10 个最相似的矢量。
运行笔记本中的单元格,以查看查询结果。 可以更改搜索词并重新运行查询,以查看不同的结果。 还可以比较维基百科数据库中的现有条目,以查找类似的条目。
kustoQuery = "Wiki | extend similarity = series_cosine_similarity(dynamic("+str(searchedEmbedding)+"), content_vector) | top 10 by similarity desc"
accessToken = mssparkutils.credentials.getToken(KUSTO_CLUSTER)
kustoDf = spark.read\
.format("com.microsoft.kusto.spark.synapse.datasource")\
.option("accessToken", accessToken)\
.option("kustoCluster", KUSTO_CLUSTER)\
.option("kustoDatabase", KUSTO_DATABASE)\
.option("kustoQuery", kustoQuery).load()
# Example that uses the result data frame.
kustoDf.show()
清理资源
完成本教程后,你可以删除你创建的资源,从而避免产生其他成本。 若要删除资源,请执行以下步骤:
- 浏览到工作区主页。
- 删除在本教程中创建的笔记本。
- 删除在本教程中使用的 Eventhouse 或数据库。