随着关于大型语言模型、矢量和矢量搜索的所有嗡嗡声,重要的是要退后一步,了解这些人工智能技术的进步如何转化为组织乃至最终客户的结果。
问题所在
今天,我们会见了促销团队。他们正在寻求我们的帮助,以做出有关客户广告、优惠和优惠券的更明智的决策。目前,促销活动主要基于地理市场。因此,发送给一个城市的客户的促销活动将与向另一个城市的客户提供的促销活动不同。因此,必须提前计划这些活动。
问题在于,营销部门正在向他们施加压力,要求他们提供更具战略性的方法来定位客户,尽管有地理区域。人们的想法是,特定客户可能更有可能根据其购买历史记录利用某些优惠。如果我们能找到一种方法来实时提供它们,比如相关产品(每购物车)的 10% 折扣,我们也许能够推动一些额外的销售。
首先,我决定看看我们的Apache Cassandra集群中的一些匿名订单数据。很明显,数据中肯定存在一些模式,一些客户购买相同的商品(主要是杂货产品)具有一定的可预测规律性。也许我们有办法利用这些数据?
改善体验
我们要做的一件事是:我们的客户倾向于通过多种渠道与我们互动。有些人使用网站,有些人使用移动应用程序,有些人仍然会走进我们大约1000家实体店中的任何一家。商店中超过一半的客户同时使用移动应用程序。
另一个有趣的点是:如果我们按家庭地址而不是仅按客户ID汇总商品销售数据,我们会看到更严格的购物模式。在从几个不同的来源收集数据后,我们可以开始描绘这些数据的样子。
示例:一对夫妇养了一只狗。通常,配偶一方购买狗粮。但有时,另一方配偶会这样做。单个客户级别的这些事件并没有形成太大的模式。
但是,当在家庭层面汇总在一起时,它们确实如此。事实上,他们每周都会购买超过一卷6磅重的“HealthyFresh-鸡肉生狗粮”。从推荐的份量来看,他们要么有六只小狗,要么有一只大狗,可能是后者。
每个客户经常光顾的商店也可以在这里发挥作用。例如,我们的客户 Marie 可能正在出差,可能会访问我们从未去过的商店之一。如果商店与她的常客商店列表相距甚远,我们可以假设玛丽可能正在购买与她的旅行相关的特定商品
但是,如果 Marie 在她经常光顾的商店之一,那么在她的移动设备上触发促销可能是有意义的。如果我们鼓励客户使用手机扫描商品,我们将知道他们的实体购物车中有哪些商品。然后,我们可以展示类似的商品来补充购物车中已有的产品。
计算向量以查找相似产品
查找相似产品意味着我们需要计算产品的相似性向量。有几种方法可以做到这一点。为了将最小可行产品放在一起,我们可以只关注产品名称,并基于“词袋”方法构建自然语言处理(NLP)模型。
在这种方法中,我们从所有产品名称中获取每个单词,并为每个唯一的单词提供一个条目。这是我们的词汇。我们为每个产品创建和存储的相似性向量变成一个由 1 和 0 组成的数组,指示当前产品名称是否具有该词,如下面的表 1 所示。我们可以使用 像TensorFlow 这样的平台来构建和训练我们的机器学习(ML)模型。
健康新鲜 |
鸡 |
.raw |
狗 |
食物 |
牛肉 |
噗嗤—— 香肠 |
戒指 |
嚼 |
玩具 |
球 |
网球 |
培根 |
对待 |
|
健康新鲜 – 鸡肉生狗粮 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
健康新鲜 – 牛肉生狗粮 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
狗网球玩具 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
狗圈咀嚼玩具 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
噗嗤—— 香肠培根狗零食 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
噗嗤—— 香肠牛肉狗零食 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
表 1:宠物用品类别下产品名称的一组单词 NLP 词汇,显示了每个向量是如何组装的 这可能会导致更长的模型训练时间和更长的预测时间。为了减少这些问题,我们将为每个主要产品类别建立一个独特的词汇表。向量将不能跨不同的类别使用,但这没关系,因为我们可以在查询时按类别进行过滤。
然后,我们可以在 Apache Cassandra 集群中创建一个表,以支持每个特定类别的向量搜索。由于我们的词汇表包含 14 个单词,因此向量的大小也需要为 14:
CREATE TABLE pet_supply_vectors (
product_id TEXT PRIMARY KEY,
product_name TEXT,
product_vector vector<float, 14>);
为了使向量搜索正常运行,我们需要在表上创建一个存储附加二级索引 (SASI):
CREATE CUSTOM INDEX ON pet_supply_vectors(product_vector) USING 'StorageAttachedIndex';
然后,我们可以将 ML 模型的输出加载到 Cassandra 中。 存在数据后,下一步是添加新服务,该服务使用以下查询执行矢量搜索:
SELECT * FROM pet_supply_vectors
ORDER BY product_vector
ANN OF [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] LIMIT 2;
这将使用与当前产品一起存储的向量运行近似最近邻 (ANN) 算法。这将通过向量搜索返回当前乘积和下一个最近(最近邻),这要归功于 LIMIT 2 子句。
在上面的查询中,我们使用来自“HealthyFresh — 鸡肉生狗粮”产品的向量,假设客户刚刚将其在线添加到购物车或用手机扫描。 我们处理此事件并撰写以下消息:
- customer_id: a3f5c9a3
- device_id: e6f40454
- product_id: PF1843
- product_name:“健康新鲜 – 鸡肉生狗粮”
- product_vector: [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
然后,我们将此消息发送到Apache Pulsar主题 这将运行上面指示的查询,返回两种“健康新鲜”口味。我们忽略了 100% 匹配的product_vector数据(我们已经拥有的产品),并在其设备上触发了“HealthyFresh — 牛肉”口味的促销活动:
结论和今后的步骤
在使用此逻辑运行几周后,我们的促销团队联系并报告说,我们的方法在大约 25% 的时间内触发了额外的销售。 虽然人们很容易称之为“胜利”,但肯定还有一些额外的事情我们可以考虑改进。
我们采用了“词袋”NLP方法,只是为了推出最初的(软件)产品。我已经读过关于不同NLP算法的好东西,比如“Word2Vec”,从长远来看,这可能是一个更好的方法。我们的模型也只关注用构成产品名称的单词建立一个词汇表。 也许扩展我们的模型输入以包括其他产品细节(例如,尺寸,颜色,品牌)可能有助于微调一下。
在下一篇文章中,我们将展示如何使用矢量搜索来帮助我们的运输服务团队提高他们的交付路线效率。