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 pandasimport pandas as pd# 按行分割,strip()函数去掉两边的空白product_names=data.strip().split("\n")# 将数据存储成行列,列名为product_namedf=pd.DataFrame({'product_name':product_names})# 显示前几行数据df.head()
结果如下:
我们看到它返回的数据都自带了编号,我们把编号去掉,不要它标题的编号:
# 去掉列里自带的编号,apply()函数用于对DataFrame的一列(Series)中的每个元素应用一个函数 。然后匿名函数处理列里数据# 列里根.字符进行分割,取索引1的数据就可 。最后赋值给远列product_namedf.product_name=df.product_name.apply(lambda x: x.split('.')[1].strip())df.head()
结果:
我们再获取一些女装,也是用上边的方式,方便后面实验测试数据
clothes_prompt = """请你生成50条淘宝网里的商品的标题,每条在30个字左右,品类是女性的服饰箱包等等,标题里往往也会有一些促销类的信息,每行一条 。"""clothes_data = http://www.kingceram.com/post/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 openaiimport osimport backoffimport 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"] = embeddingsdf.to_parquet("taobao_product_title.parquet", index=False)
【AI大模型的使用-语义检索,利用Embedding优化你的搜索功能】将数据转换成向量数据完毕!
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)returnresultsresults=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 numpyimport faissimport 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大模型之美》整理记录
- 菠萝蜜的高产种植技术
- 破的成语 破的笔顺正确写法
- 一线互联网企业中,招聘网职位的套路,注意这些帮你避坑。
- 针对Android的木马程序Loapi好毒!可以真正的破坏整支手机
- 苹果蓝牙耳机平价替代,可以媲美airpods的蓝牙耳机推荐!
- 主导世界的10 大牛逼算法!
- 有 1000 瓶药物,但是其中有一瓶是有毒的,小白鼠吃了一个星期以后就会死掉!
- 必有近忧的上面一句是什么 必有近忧的前面一句是什么
- Google 的客户参与团队解释了他们如何使用人工智能来取悦全球数十亿用户
- MSE,MAE和CE的区别