使用嵌入进行语义文本搜索

通过嵌入搜索查询,然后查找最相似的评论,我们可以非常高效且低成本地对所有评论进行语义搜索。数据集在 Get_embeddings_from_dataset Notebook 中创建。

import pandas as pd
import numpy as np
from ast import literal_eval

datafile_path = "data/fine_food_reviews_with_embeddings_1k.csv"

df = pd.read_csv(datafile_path)
df["embedding"] = df.embedding.apply(literal_eval).apply(np.array)

在这里,我们比较查询和文档的嵌入的余弦相似度,并显示前 n 个最佳匹配项。

from utils.embeddings_utils import get_embedding, cosine_similarity

# 搜索特定产品的评论
def search_reviews(df, product_description, n=3, pprint=True):
    product_embedding = get_embedding(
        product_description,
        model="text-embedding-3-small"
    )
    df["similarity"] = df.embedding.apply(lambda x: cosine_similarity(x, product_embedding))

    results = (
        df.sort_values("similarity", ascending=False)
        .head(n)
        .combined.str.replace("Title: ", "")
        .str.replace("; Content:", ": ")
    )
    if pprint:
        for r in results:
            print(r[:200])
            print()
    return results

results = search_reviews(df, "delicious beans", n=3)
美味!:我喜欢这种白豆调味料,它给豆子带来了浓郁的风味,我非常喜欢它,我的婆婆不知道这个 Zatarain 品牌,现在她正在尝试不同的调味料。

绝佳的即食炸豆泥:绝佳的即食炸豆泥近 20 年来一直是我的家庭必需品。我们全家 7 口人都喜欢它,我的成年孩子们也在传承这一传统。

美味:虽然可能有更好的咖啡豆,但这是我的第一次购买,也是我第一次自己研磨豆子。购买前我阅读了几篇评论,并且非常满意。
results = search_reviews(df, "whole wheat pasta", n=3)
美味又快捷的意大利面:Barilla 全麦螺旋面配番茄酱味道鲜美,蔬菜番茄酱也很棒。我只希望份量能再多一点。如果你不是饿极了或者在

太好吃了:味道好极了。物有所值。我的男朋友讨厌小麦意大利面,但他很喜欢这个。煮得很快,味道也很好。我喜欢这个品牌,并开始购买更多他们的意大利面。批量购买是最好的。

味道平淡,略带腥味,跳过这个:就预制餐包而言,“Barilla 全麦通心粉配番茄罗勒酱”对我来说并不合胃口……而且这是来自一个

我们可以轻松地搜索这些评论。为了加快计算速度,我们可以使用一种专门用于更快地搜索嵌入的特殊算法。

results = search_reviews(df, "bad delivery", n=1)
产品很棒,但送货很糟糕:咖啡很棒,我是回头客。这次的问题出在 UPS 的送货上。他们把箱子留在了车道中间的车库门前。

正如我们所见,这可以立即带来很多价值。在此示例中,我们展示了能够快速找到交付失败的示例。

results = search_reviews(df, "spoilt", n=1)
失望:金属盖严重变形。里面的饼干大部分都碎成了小块。购物体验很糟糕。我再也不会在线购买了。
results = search_reviews(df, "pet food", n=2)
很棒的食物!:我想要一种适合皮肤有问题狗的食物。换了食物后,他的皮肤有了很大的改善,尽管他仍然有些痒。他喜欢这种食物。没有召回,美国制造,美国原料

很棒的食物!:我想要一种适合皮肤有问题狗的食物。换了食物后,他的皮肤有了很大的改善,尽管他仍然有些痒。他喜欢这种食物。没有召回,美国制造,美国原料