Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166833
  • 博文数量: 47
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 466
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-31 23:12
个人简介

知乎:http://www.zhihu.com/people/chanpinjinglizhilu

文章分类

全部博文(47)

分类: 大数据

2024-09-13 10:20:47

本教程演示如何使用向量检索服务(DashVector),结合上的Embedding API,来从0到1构建基于文本索引的构建+向量检索基础上的语义搜索能力。具体来说,我们将基于QQ 浏览器搜索标题语料库(:QQ Browser Query Title Corpus)进行实时的文本语义搜索,查询{BANNED}{BANNED}最佳佳相似的相关标题。


什么是 Embedding

简单来说,Embedding是一个多维向量的表示数组,通常由一系列数字组成。Embedding可以用来表示任何数据,例如文本、音频、图片、视频等等,通过Embedding我们可以编码各种类型的非结构化数据,转化为具有语义信息的多维向量,并在这些向量上进行各种操作,例如相似度计算、聚类、分类和推荐等。


整体流程概述

  • Embedding:通过DashScope提供的通用文本向量模型,对语料库中所有标题生成对应的embedding向量。

  • 构建索引服务和查询

    • 通过DashVector向量检索服务对生成embedding向量构建索引。

    • 将查询文本embedding向量作为输入,通过DashVector搜索相似的标题。


具体操作流程

前提条件


1、环境安装

说明

需要提前安装 Python3.7 及以上版本,请确保相应的 python 版本。


  1. pip3 install dashvector dashscope



2、数据准备

(QBQTC, QQ Browser Query Title Corpus),是QQ浏览器搜索引擎目前针对大搜场景构建的一个融合了相关性、权威性、内容质量、 时效性等维度标注的学习排序(LTR)数据集,广泛应用在搜索引擎业务场景中。作为CLUE-beanchmark的一部分,QBQTC 数据集可以直接从github上下载(训练集路径为dataset/train.json)。


  1. git clone https://github.com/CLUEbenchmark/QBQTC.git
  2. wc -l QBQTC/dataset/train.json


数据集中的训练集(train.json)其格式为 json:

  1. {
  2.   "id": 0,
  3.   "query": "小孩咳嗽感冒",
  4.   "title": "小孩感冒过后久咳嗽该吃什么药育儿问答宝宝树",
  5.   "label": "1"
  6. } 

我们将从这个数据集中提取title,方便后续进行embedding并构建检索服务。

  1. import json

  2. def prepare_data(path, size):
  3.     with open(path, 'r', encoding='utf-8') as f:
  4.         batch_docs = []
  5.         for line in f:
  6.             batch_docs.append(json.loads(line.strip()))
  7.             if len(batch_docs) == size:
  8.                 yield batch_docs[:]
  9.                 batch_docs.clear()

  10.         if batch_docs:
  11.             yield batch_docs



3、通过 DashScope 生成 Embedding 向量

DashScope灵积模型服务通过标准的API提供了多种模型服务。其中支持文本Embedding的模型中文名为通用文本向量,英文名为text-embedding-v1。我们可以方便的通过DashScope API调用来获得一段输入文本的embedding向量。

说明

需要使用您的api-key替换示例中的 your-dashscope-api-key ,代码才能正常运行。


  1. import dashscope
  2. from dashscope import TextEmbedding

  3. dashscope.api_key='{your-dashscope-api-key}'


  4. def generate_embeddings(text):
  5.     rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v1,
  6.                              input=text)
  7.     
  8.     embeddings = [record['embedding'] for record in rsp.output['embeddings']]
  9.     return embeddings if isinstance(text, list) else embeddings[0]


  10. # 查看下embedding向量的维数,后面使用 DashVector 检索服务时会用到,目前是1536
  11. print(len(generate_embeddings('hello')))


4、通过 DashVector 构建检索:向量入库

DashVector 向量检索服务上的数据以集合(Collection)为单位存储,写入向量之前,我们首先需要先创建一个集合来管理数据集。创建集合的时候,需要指定向量维度,这里的每一个输入文本经过DashScope上的text_embedding_v1模型产生的向量,维度统一均为1536。


DashVector 除了提供向量检索服务外,还提供倒排过滤功能 和 scheme free 功能。所以我们为了演示方便,可以写入数据时,可以将title内容写入 DashVector 以便召回。写入数据还需要指定 id,我们可以直接使用 QBQTC 中id

说明

需要使用您的api-key替换示例中的 your-dashvector-api-key ,以及您的Cluster Endpoint替换示例中的 your-dashvector-cluster-endpoint代码才能正常运行。


  1. from dashvector import Client, Doc


  2. # 初始化 DashVector client
  3. client = Client(
  4.   api_key='{your-dashvector-api-key}',
  5.   endpoint='{your-dashvector-cluster-endpoint}'
  6. )

  7. # 指定集合名称和向量维度
  8. rsp = client.create('sample', 1536)
  9. assert rsp

  10. collection = client.get('sample')
  11. assert collection

  12. batch_size = 10
  13. for docs in list(prepare_data('QBQTC/dataset/train.json', batch_size)):
  14.     # 批量 embedding
  15.     embeddings = generate_embeddings([doc['title'] for doc in docs])

  16.     # 批量写入数据
  17.     rsp = collection.insert(
  18.         [
  19.             Doc(id=str(doc['id']), vector=embedding, fields={"title": doc['title']})
  20.             for doc, embedding in zip(docs, embeddings)
  21.         ]
  22.     )
  23.     assert rsp


5、语义检索:向量查询

在把QBQTC训练数据集里的title内容都写到DashVector服务上的集合里后,就可以进行快速的向量检索,实现“语义搜索”的能力。继续上面代码的例子,假如我们要搜索有多少和'应届生 招聘'相关的title内容,可以通过在DashVector上去查询'应届生 招聘',即可迅速获取与该查询语义相近的内容,以及对应内容与输入之间的相似指数。

  1. # 基于向量检索的语义搜索
  2. rsp = collection.query(generate_embeddings('应届生 招聘'), output_fields=['title'])

  3. for doc in rsp.output:
  4.     print(f"id: {doc.id}, title: {doc.fields['title']}, score: {doc.score}")

  1. id: 0, title: 实习生招聘-应届生求职网, score: 2523.1582
  2. id: 6848, title: 应届生求职网校园招聘yingjieshengcom中国领先的大学生求职网站, score: 3053.7095
  3. id: 8935, title: 北京招聘求职-前程无忧, score: 5100.5684
  4. id: 5575, title: 百度招聘实习生北京实习招聘, score: 5451.4155
  5. id: 6500, title: 中公教育招聘信息网-招聘岗位-近期职位信息-中公教育网, score: 5656.128
  6. id: 7491, title: 张家口招聘求职-前程无忧, score: 5834.459
  7. id: 7520, title: 前程无忧网北京前程无忧网招聘, score: 5874.412
  8. id: 3214, title: 乡镇卫生院招聘招聘乡镇卫生院招聘信息+-58同城, score: 6005.207
  9. id: 6507, title: 赶集网招聘实习生北京实习招聘, score: 6424.9927
  10. id: 5431, title: 实习内容安排百度文库, score: 6505.735 
阅读(110) | 评论(0) | 转发(0) |
0

上一篇:?shell 统计源码行数?

下一篇:没有了

给主人留下些什么吧!~~