使用图像相似度进行产品推荐

社区文章 发布于2024年10月29日

image/png

在本文中,我们将介绍如何使用用户已点击产品的图像相似度来构建产品推荐系统。我们将上传一个数据集,创建一个演示,并讨论其工作原理。

Hugging Face Spaces

下载代码

Github 仓库下载代码

git clone https://github.com/TonyAssi/product-recommendation.git 

数据集

我们假设您只有一个产品图片文件夹(每个产品一张图片)。我们将使用这些图片和图像嵌入来创建一个Hugging Face数据集。图像嵌入是使用我的图像嵌入模块生成的。

首先,您需要进入您下载的仓库中的 *upload_ds.py* 文件,并修改以下三行代码。

img_folder = './img'
repo_name = 'tonyassi/product-images'
hf_token = 'YOUR_HF_TOKEN'

然后从命令行运行 *upload_ds.py* 文件。

python upload_ds.py

这将在您的 Hugging Face 配置文件中创建两个数据集仓库。

tonyassi/product-images (图像和ID)

tonyassi/product-images-embeddings (图像、ID和嵌入) 这是我们将用于产品推荐的数据集。

演示

打开您最初从 Github 下载的 *app.py* 文件,并放入您刚刚创建的数据集仓库中。

ds = load_dataset("tonyassi/finesse1-embeddings", split='train')

前往 Hugging Face,创建一个新的 Gradio 空间。将 *app.py* 和 *requirements.txt* 文件上传到该空间。空间构建完成后,它应该看起来像这样:tonyassi/product-recommendation

首先,用户将在产品图库中选择他们最喜欢的产品,总共10个。该产品将被添加到偏好图库中。然后,新的10个产品将加载到产品图库中。最上面的5个产品是与偏好图库产品视觉上最相似的产品。最下面的5个产品是随机选择的。加载到产品图库中的产品永远不会重复,也就是说,直到您刷新页面,您将永远不会在图库中看到相同的产品。

恭喜!现在您有了一个产品推荐系统的演示。


理论

让我们深入探讨一下这个工作原理。您不一定需要阅读本节,但它将帮助您理解其工作原理以及我为什么这样实现。

图像嵌入

图像嵌入使我们能够进行图像相似度搜索。但是,什么是 *图像嵌入*?简单来说,图像嵌入是图像的高级数值表示。它们向计算机表示高级视觉概念,但对我们来说,它们并不能告诉我们太多。以下是它们的样子:

[0.17519, -0.33182, -0.11692... 1.08443, -0.22943, 1.06595]

图像嵌入是使用 google/vit-base-patch16-224 模型生成的。它是一个出色的通用编码器模型。理论上,您可以使用在您的数据集上微调的视觉模型,但我发现这个模型与微调模型的效果一样好,甚至更好。

我在 Github 上有一个非常简单的图像嵌入模块,它接收一个 Hugging Face 图像数据集,并创建一个带有嵌入列的新图像数据集。

图像相似度

我们通过比较一张图片的图像嵌入与另一张图片的图像嵌入来执行图像相似度。这比我们比较一张图片的像素值与另一张图片的像素值要快得多且更准确。

在实践中,为了进行图像嵌入比较,我们使用 get_nearest_examples()。这是一个与 🤗 Datasets 兼容的 FAISS 函数。

首先,我们将 FAISS 索引添加到数据集的“embeddings”列。

dataset_with_embeddings.add_faiss_index(column="embeddings")

然后,我们使用 get_nearest_examples() 来查找数据集中与查询图像最相似的图像。

scores, retrieved_examples = dataset_with_embeddings.get_nearest_examples(
    "embeddings", query_image_embedding, k=top_k
)

scores 是相似度分数列表,分数越低表示越相似。

retrieved_examples 是与查询图像最相似的行列表。

如果您想了解更多关于图像相似度的信息,请查阅这篇博客。或者查看这个笔记本获取代码示例。您还可以查看我的图像相似度模块

实现

让我们来看看演示的实现。

首先,随机选择10个产品并加载到产品画廊中。之所以随机选择这些初始产品,与冷启动问题有关,因为在没有用户偏好数据的情况下,系统无法进行任何推断。

一旦用户选择他们最喜欢的产品,它就会被添加到偏好画廊。然后,从数据集中加载10个新产品到产品画廊中。加载到产品画廊中的产品永远不会重复。

产品画廊中最上面的 5 个产品是与偏好画廊产品视觉上最相似的产品。偏好嵌入是通过计算偏好画廊中所有图像嵌入的平均值生成的。

Preference Embedding=1ni=1nImage Embeddingi \text{Preference Embedding} = \frac{1}{n} \sum_{i=1}^{n} \text{Image Embedding}_i

这个偏好嵌入是所有偏好图像组合的向量表示。然后将这个偏好嵌入用作查询嵌入,以在数据集中获取最相似的图像。

产品画廊最底部的5个产品是随机选择的。这样做的原因是考虑到前面提到的冷启动问题。假设用户正在寻找一件黄色连衣裙,但最初随机选择的产品集中没有黄色连衣裙。用户可能会选择一件红色连衣裙,因为他们没有看到他们想要的颜色。如果所有推荐给用户的产品都是相似的,那么用户将 계속 被推荐红色连衣裙,永远没有机会找到他们的黄色连衣裙。这就是为什么会推荐一些随机产品;为了引入多样性和更广泛的搜索,这样它就不会陷入局部最优。我们在进化算法中也看到了类似的方法,其中“DNA”被随机突变以引入基因库的多样性。我们可以尝试调整相似/随机比例,但我发现 5:5 是一个很好的平衡。

性能

我们可以测试推荐系统的性能以获得一些基准。为了进行这些基准测试,我们假设数据集中有一个预定义的目标产品。找到目标产品所需的轮数是推荐系统的得分。得分越低越好。

我们首先设想一个“暴力”推荐系统,它每轮随机选择10个产品,并且不考虑用户的偏好。找到目标产品所需的平均轮数的公式定义如下:

  • N 产品总数
  • k 每轮显示的产品数量

E(X)N2×k E(X) \approx \frac{N}{2 \times k}

如果我有 500 个产品,每次显示 10 个,那么平均需要大约 25 轮才能找到目标产品。

现在让我们评估一下我们的推荐系统,看看我们能否做得更好。首先,我们可以从数据集中随机选择一个产品作为我们的目标产品。然后,我们将使用我们制作的演示来尝试找到该目标产品。重复此操作 5-10 次,以了解找到目标产品所需的平均轮数。

我的数据集有 459 个产品,每轮显示 10 个产品。我平均需要 13 轮才能找到目标产品。使用“暴力”方法,平均需要约 23 轮。这意味着我们的方法比暴力方法快 43%。

速度

尽管速度和效率不是本项目关注的重点,但代码运行速度非常快。每轮的计算时间不到1秒。在演示中您可能会看到它耗时超过1秒,这是因为前端 Gradio 代码需要时间来渲染图像。

改进

还有很多改进空间,例如添加文本搜索、优化产品画廊中相似/随机产品的比例、微调 ViT 模型等等。对于本文和演示,我想高度专注于图像相似度,以了解它能发挥多大作用。

关于我

您好,我叫 Tony Assi。我是一名驻洛杉矶的设计师。我拥有软件、时尚和营销背景。我目前为一家电子商务时尚品牌工作。访问我的 🤗 个人资料,了解更多应用程序、模型和数据集。

如有任何问题、意见、业务咨询或工作机会,请随时发送电子邮件至 tony.assi.media@gmail.com

社区

注册登录 以评论