首页 >> 大全

AI大模型的使用-语义检索,利用Embedding优化你的搜索功能

2023-12-09 大全 27 作者:考证青年

1.【新品上市】Apple/苹果 iPhone 11 Pro Max 手机
2.【现货特价】华为Mate 30 Pro 5G手机
3.【抢购优惠】小米MIX Alpha智能折叠手机
4.【热卖爆款】三星Galaxy Note 10 Plus 旗舰手机
5.【限时促销】荣耀V30 Pro 5G超薄手机
6.【时尚潮流】OPPO Reno 10X Zoom双摄手机
7.【新品特惠】vivo NEX 3 5G超级旗舰手机
8.【超值优惠】联想Z6 Pro 5G游戏手机
9.【热销精品】金立S10 Pro 5G 全面屏手机
10.【抢购热卖】魅族16s Pro 全面屏手机
11.【热卖抢购】荣耀20 Pro 5G超薄手机
12.【爆款热销】Apple/苹果 iPhone 11 手机
13.【特价热卖】华为P30 Pro 全面屏手机
14.【新品优惠】三星Galaxy S10 Plus 旗舰手机
15.【限时特惠】OPPO Reno 10X 折叠手机
16.【时尚潮流】vivo iQOO Pro 5G超级旗舰手机
17.【新品特价】联想Z5 Pro 5G全面屏手机
18.【超值促销】金立S10 5G 全面屏手机
19.【抢购热卖】魅族16s 全面屏手机
20.【热销特惠】荣耀20 5G超薄手机
21.【爆款特价】Apple/苹果 iPhone XS Max 手机
22.【特价热卖】华为Mate 20 Pro 5G手机
23.【新品优惠】小米MIX 3 智能折叠手机
24.【热卖爆款】三星Galaxy Note 9 Plus 旗舰手机
25.【限时促销】荣耀V20 Pro 5G超薄手机
26.【时尚潮流】OPPO Reno 8X Zoom双摄手机
27.【新品特惠】vivo NEX 3S 5G超级旗舰手机
28.【超值优惠】联想Z6 5G游戏手机
29.【热销精品】金立S10 5G 全面屏手机
30.【抢购热卖】魅族16s Plus 全面屏手机
31.【热卖抢购】荣耀20 5G超薄手机
32.【爆款热销】Apple/苹果 iPhone XR 手机
33.【特价热卖】华为P20 Pro 全面屏手机
34.【新品优惠】三星Galaxy S9 Plus 旗舰手机
35.【限时特惠】OPPO Reno 8 折叠手机
36.【时尚潮流】vivo iQOO 5G超级旗舰手机
37.【新品特价】联想Z5 5G全面屏手机
38.【超值促销】金立S10 Pro 5G 全面屏手机
39.【抢购热卖】魅族16 Plus 全面屏手机
40.【热销特惠】荣耀20 Pro 5G超薄手机
41.【爆款特价】Apple/苹果 iPhone X 手机
42.【特价热卖】华为Mate 10 Pro 5G手机
43.【新品优惠】小米MIX 2S智能折叠手机
44.【热卖爆款】三星Galaxy Note 8 Plus 旗舰手机
45.【限时促销】荣耀V10 Pro 5G超薄手机
46.【时尚潮流】OPPO Reno 7X Zoom双摄手机
47.【新品特惠】vivo NEX 2 5G超级旗舰手机
48.【超值优惠】联想Z4 Pro 5G游戏手机
49.【热销精品】金立S10 Plus 5G 全面屏手机
50.【抢购热卖】魅族16 全面屏手机

我们将给的数据处理下,改成我们能处理的数据,将数据转换为,并起一个key名为。

!pip install pandas
import pandas as pd# 按行分割,strip()函数去掉两边的空白
product_names=data.strip().split("\n")
# 将数据存储成行列,列名为product_name
df=pd.DataFrame({'product_name':product_names})
# 显示前几行数据
df.head()

结果如下:

我们看到它返回的数据都自带了编号,我们把编号去掉,不要它标题的编号:

# 去掉列里自带的编号,apply()函数用于对DataFrame的一列(Series)中的每个元素应用一个函数。然后匿名函数处理列里数据
# 列里根.字符进行分割,取索引1的数据就可。最后赋值给远列product_name
df.product_name=df.product_name.apply(lambda x: x.split('.')[1].strip())
df.head()

结果:

我们再获取一些女装,也是用上边的方式,方便后面实验测试数据

clothes_prompt = """请你生成50条淘宝网里的商品的标题,每条在30个字左右,品类是女性的服饰箱包等等,标题里往往也会有一些促销类的信息,每行一条。"""
clothes_data = generate_data_by_prompt(clothes_prompt)
clothes_product_names=clothes_data.strip().split('\n')
clothes_df=pd.DataFrame({'product_name':clothes_product_names})
clothes_df.product_name= clothes_df.product_name.apply(lambda x: x.split('.')[1].strip())
clothes_df.head()

查看结果:用head取出前5条数据

将上面得到的数码产品和女士服饰箱包这两种数据合并一起,方便后续搜索数据处理:

#把这两个 DataFrame 拼接在一起,就是我们接下来用于做搜索实验的数据。
# concat()此函数用来合并,方式为axis=0按行合并
df = pd.concat([df, clothes_df], axis=0)
# 重制索引。drop=True对原来的索引采取丢弃操作,保留重制后的索引
df=df.reset_index(drop=True)
display(df)

得到结果:你会发现 AI 有时候返回的条数没有 50 条,不过没有关系,这个基本不影响我们使用这个数据源。你完全可以多运行几次,获得足够你需要的数据。

然后我们把这些数据通过转成向量,用于计算相似度搜索~

我们还是利用 和 batch 处理,让代码能够容错,并且快速处理完这些商品标题。

!pip install openai
!pip install os
!pip install backoffimport openai
import os
import backoff
import pandas as pdfrom openai.embeddings_utils import get_embeddingsopenai.api_key = ''
embedding_model = "text-embedding-ada-002"batch_size = 100# 在线colab加上此注解报错,所以在去掉了,你可以测试下你的环境可不可以
@backoff.on_exception(backoff.expo, openai.error.RateLimitError)
def get_embeddings_with_backoff(prompts, engine):print("len(prompts):",len(prompts))embeddings = []for i in range(0, len(prompts), batch_size):batch = prompts[i:i+batch_size]print("第二个batch数据:",batch)embeddings += get_embeddings(list_of_text=batch, engine=engine)return embeddingsprompts = df.product_name.tolist()
prompt_batches = [prompts[i:i+batch_size] for i in range(0, len(prompts), batch_size)]
print("prompt_batches:",prompt_batches)embeddings = []
for batch in prompt_batches:print("第一个batch数据:",batch)batch_embeddings = get_embeddings_with_backoff(prompts=batch, engine=embedding_model)embeddings += batch_embeddingsdf["embedding"] = embeddings
df.to_parquet("taobao_product_title.parquet", index=False)

将数据转换成向量数据完毕!

2 通过 进行语义搜索

然后我们就可以写搜索产品的代码啦,主要通过关键字进行搜索,将关键搜索词转换成向量,因为我们的数据源已经转换成向量了,所以计算两个向量的相似度以后得到数据,并将数据返回即可。

# 搜索商品逻辑-----------------------------------------------------------------
from openai.embeddings_utils import get_embedding, cosine_similarity# 第一个参数df代表要搜索的数据源,在colab有上下文的
# 第二个参数query代表是搜索关键词
# 第三个参数n代表返回多少条记录
# pprint 是一个布尔值,控制是否打印结果,默认为 True。
def search_product(df,query,n=3,pprint=True):# 获取给定文本的嵌入向量,采用此模型计算查询produce_embedding=get_embedding(query,engine=embedding_model,)# 计算embedding与produce_embedding相似度,采用余弦相似度来衡量查询与个产品之间的相似度,并把结果存储到df["similarity"]列中df["similarity"]=df.embedding.apply(lambda x: cosine_similarity(x,produce_embedding))# 按照相似度降序排列,然后选取前n个产品,并提他们的产品名称# ascending是用于排序的,True为正序,False为倒序# 它会根据"similarity"列的值找到相似度最高的n个产品,并返回它们的产品名称。results=(df.sort_values("similarity",ascending=False).head(n).product_name)# pprint为True,则会打印每个匹配结果的产品if pprint:for r in results:print(r)return  resultsresults=search_product(df,"自然淡雅书包",n=3)

结果内容:

【新款】时尚简约女士手提包,柔软质感更耐用!
【新款】简约时尚女士手提包,柔软质感更耐用!
【特惠】精致简约女士手提包,潮流时尚更显靓丽!

我们可以试下搜索手机

results=search_product(df,"华为手机",n=3)

结果:

【新品上市】华为Mate 30 5G 智能手机
【新品上市】华为P40 Pro 5G 智能手机
【热销爆款】华为Mate 30 Pro 5G 智能手机

简简单单就以向量的方式做了一个搜索检查。

3 利用 信息进行商品推荐的冷启动

什么是冷启动,在新的用户或新的商品的情况下,因为没有历史数据作为佐证,无法准确的评估推荐到每一个人,所以就需要,通过合理的策略和算法,推荐系统可以在没有量历史数据的情况下,为新用户和新商品提供有针对性的推荐,从而提高推荐的准确性和个性化程度。

咱们这里只要是搜索过这个商品的话就给推荐相似商品

这个和上面的搜索代码类似,唯一不同的是,上面的代码给出搜索关键字以后又去找调用获取向量,咱们这个直接对比标题内容以后从列中取出向量,没必要浪费去查一次,然后再对比相似度,代码如下:

也就是说我们给的关键字是存在于数据源中的(此处需要与原数据中的产品名称一模一样否则取不出向量会报错)那么可以直接在原数据中产品名称对比,如果一样取出当前产品名称的向量即可。

def recommend_product(df,product_name,n=3,pprint=True):product_embedding = df[df['product_name'] == product_name].iloc[0].embeddingdf['similarity']=df.embedding.apply(lambda x: cosine_similarity(x,product_embedding))results = (df.sort_values("similarity", ascending=False).head(n).product_name)if pprint:for r in results:print(r)return resultsresults=recommend_product(df,"【新品上市】苹果iPhone 11 Pro Max全网通手机",n=3)

结果内容:这样一个新的商品根据语义相似度,就能推荐对应商品。

【新品上市】苹果iPhone 11 Pro Max全网通手机
【新品上市】苹果iPhone 11 Pro 512GB全网通手机
【新品上市】苹果iPhone 11 256GB全网通手机

4 通过 FAISS 加速搜索过程

先把向量数据加载到faiss里,为什么呢,因为面对大数据量我们每次都要计算距离,那速度肯定是慢的不行,所以可以利用一些向量数据库,或者能够快速搜索相似性的软件包就可以了,比如,我比较推荐你使用 开源的 Faiss 这个 包,它的全称就是 AI ,也就是快速进行高维向量的相似性搜索。

把索引加载到 Faiss 里面非常容易,我们直接把整个的 变成一个二维矩阵,整个加载到 Faiss 里面就好了。

!pip install faiss-gpu
!pip install numpy
import faiss
import numpy as npdef load_embeddings_to_faiss(df):# (DataFrame)中的嵌入(embedding)列转换为一个浮点型的 NumPy 数组(numpy array)# df['embedding'].tolist():将数据框中名为 "embedding" 的列转换为 Python 列表。# np.array(...):将 Python 列表转换为 NumPy 数组。# astype('float32'):将数组中的元素类型转换为浮型(32 位浮点数)。embeddings = np.array(df['embedding'].tolist()).astype('float32')# 创建了一个 Faiss 的索引对象,用于存储商品embeddings,embeddings.shape[1]=embeddings数组的第二个维度的大小index = faiss.IndexFlatL2(embeddings.shape[1])# embeddings加入到索引中,以便可以使用 Faiss 进行快速的相似度搜索index.add(embeddings)return indexindex = load_embeddings_to_faiss(df)
print("index:",index)

然后用这种方式搜索下,围绕着index搜索,需要把我们的关键搜索词转换为向量,再转换为numpy数组,通过转换为二维数组,其实和上边没什么区别,目的还是为了数据都是在一个维度上进行对比。然后经过处理的数据传入index的函数里进行搜索,搜索出k个相同的数据,并返回

通过faiss搜索,代码如下:

def search_index(index, df, query, k=5):# reshape转换为二维数组,query_vector = np.array(get_embedding(query, engine=embedding_model)).reshape(1, -1).astype('float32')# 搜索与query_vector 最相似的 k 个向量返回的结果一个包含两个数组的元组# 第一个是最相似的向量与 query_vector 之间的距离# 第二个数组是最相似的向量在索引中的索引位置distances, indexes = index.search(query_vector, k)print("distances:",distances)print("indexes",indexes)# 封装返回结果results = []for i in range(len(indexes)):product_names = df.iloc[indexes[i]]['product_name'].values.tolist()print('for product_names :',product_names)results.append((distances[i], product_names))return resultsproducts = search_index(index, df, "自然淡雅背包", k=3)
print("products:",products)# 将得到的结果解析打印
for distances, product_names in products:print("distances:",distances)for i in range(len(distances)):print(product_names[i], distances[i])

结果如下:Faiss 的原理,是通过 ANN 这样的近似最近邻的算法,快速实现相似性的搜索。

distances: [[0.21429113 0.21453398 0.22011249]]
indexes [[ 90 140 112]]
for product_names : ['【新款】优雅百搭女士单肩包', '【新款】优雅百搭女士单肩包', '【新款】优雅百搭女士手拿包']
products: [(array([0.21429113, 0.21453398, 0.22011249], dtype=float32), ['【新款】优雅百搭女士单肩包', '【新款】优雅百搭女士单肩包', '【新款】优雅百搭女士手拿包'])]
distances: [0.21429113 0.21453398 0.22011249]
【新款】优雅百搭女士单肩包 0.21429113
【新款】优雅百搭女士单肩包 0.21453398
【新款】优雅百搭女士手拿包 0.22011249

本章视频说明:AI大模型-巧用实现搜索和推荐功能_哔哩哔哩

本文根据徐文浩老师的《AI大模型之美》整理记录

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了