背景描述

我们要做的是一个辅助线下销售的推荐系统。我们通过摄像头识别消费者,在服务器上生成该消费者的推荐列表,再传送到线下导购的终端,让他们能方便的向消费者推荐可能符合消费者喜好的商品

由于我们的场景是在线下,因此我们能够比线上多一个prior knowledge就是消费者想买的商品种类。举例来看,当消费者进入优衣库的时候,导购会问消费者想买什么东西,消费者会回答说:衣服。这个衣服种类就是我们的 prior knowledge,我们无论是通过语音识别还是导购自己操作,至少会知道消费者想要的category。由此我们的推荐形式变成为每个category推荐5个商品。

数据

我们的数据来自于阿里天池比赛 https://tianchi.aliyun.com/datalab/dataSet.html?spm=5176.100073.0.0.3cce35eefAB8ce&dataId=42

这些数据的属性有:user_id, item_id, cat_id, merchant_id, brand_id, time_stamp, action_typye, 以及另一个记录user生理信息的age_range, gender的表,而且所有信息都是id化的

由于brand所对应的交易比merchant多,为了得到更多数据来提高推荐命中率,我们以brand来作为店铺的分类依据。在做单店铺推荐的时候,我们选取了购买数最多的brand作为我们的数据集

而在做多店铺的时候,我们则是选取了购买数前30的brand作为我们的数据集

命中率

这里的命中率有点类似与recall,由于我们的推荐形式是每个cat推荐5个item,我们看该user在test set中的item是不是在推荐列表中,若在里面就算推荐成功。

最后比较的是 成功的人数/test中总的人数

单店铺推荐

单店铺推荐的代码就在和多店铺推荐同一层文件夹里,其中data是购买数最多的那个brand所对应的购买记录

划分训练集和测试集 split.py

原数据 个数
item 2040
交易记录 73790
category 68
user 33377
稀疏度 99.97%

由于数据过于稀疏,我们通过计算各个商品的购买次数来剔除冷门商品(也是为了降低稀疏度),这里我们删除了购买次数少于等于7的商品,得到删除的信息如下:

删除记录 个数
item 1258
交易记录 3322
user 1201
稀疏度 99.7%

由于这些交易都是单笔交易,我们把一个消费者的重复购买合并在一起,并用一个新的列occurrence来记录下他们出现的次数。例如user_id = 1000的人购买了3次 item_id = 222的商品,我们 就合并这三次记录,同时用一个occurrence列来记录购买的数量(也就是3)。以上7万行交易记录转化为交易数量后变成50380行

由于我们需要测试购买不同商品数量(也就是你买的多少)对我们的预测准确率的影响,因此我们采用的是有偏采样,对购买商品数大于某个num的user进行sample(也因为这样准确率会提升,比较好对商家进行展示)

具体的划分步骤是: 1.sample属于符合条件的user 2.选择每个user购买记录中的一条作为test set,同时在原数据中把那条购买记录删除掉(这个为training test) 3.讲test和training各自保存成文件让下面的几个算法代码读取

隐式反馈 new_implicit.ipynb & 联合矩阵分解 cmf.ipynb

由于readme这里贴图不方便,因此详细介绍看那个pptx

原先的协同过滤是把评分矩阵R中的评分(对应到我们这里的购买数量)当做消费者的喜好程度,即如果你买的多,你就很喜欢这个商品。然后对这个R矩阵进行矩阵分解,分解成2个小的latent matrix,然后再将这两个 latent matrix相乘,得到一个新的R’矩阵。R’相比R而言,会更加dense,R’中的每一行都代表着该user对不同item的喜爱程度

隐式反馈

在隐式反馈implicit feedback中,我们把购买数量视为一种置信度confidence,也就是说你买的越多,我越有足够的信心认为你喜欢这个商品。

item数 test人数 命中率
2 1798 56.4%
3 700 63.4%
4 362 71.3%
5 230 74.4%
6 99 64.2%
联合矩阵分解 collective matrix factorization

这里加入了消费者的信息(user side information),通过共同分解矩阵来得到对应的latent matrix(不方便贴图,具体原理可以看ppt)

item数 test人数 命中率
3 700 35.8%
4 362 46.4%
5 230 50.8%
6 99 50.5%

由两表的对比发现加了side information矩阵的推荐效果并没有单纯的隐式反馈好,而且调参的结果也显式如果side information的权重降低反而效果好。这也意味着在这个数据集上,如果我们添加一个消费者的信息作为约束的话, 至少在多次购买的熟客上,命中率会降低

冷启动 cold start with popular goods.ipynb

冷启动cold start是指当一个user没有来过我们这家店,我们该如何推荐

我们采取的方法是推荐最为popular的商品,也就是买的最多的商品。这点各个互联网公司也是同样在运用,抖音,今日头条他们在对新注册的用户进行推荐的时候也是推荐最为general的东西,根据用户接下来的反馈 来进行下一步的推荐。

除了popular之外,我们还尝试对消费者按照年龄、性别进行聚类,整体效果如下:

item数 命中率
无分类popular 41.3%
gender分类popular 42.2%
age_range分类popular 42.0%
gender和age_range分类 43.2%

可以看到,按照这些基础的性别、年龄来聚类消费者,能够提升在各自分类的命中率。由此我们可以想来,当实际运用的时候,我们可以通过视觉信息来对消费者进行聚类来提高冷启动推荐率。

多店铺推荐

多店铺推荐是另一种形式的冷启动,即我们有user在其他店铺B,C,D,E,F的购买记录,但是没有该消费者在店铺A的购买记录,我们该如何推荐。

我们的数据现在变成30个brand的交易记录,可以想象成一个商超。 直观的跨店铺比例展示如下:

购买的brand数 比例
1 66.7%
2 19%
3 7.5%
4 3.3%
5 1.4%
6 0.7%
由于我们的数据是阿里巴巴的,而电商网站上有非常多的店铺,因此当我们取30个店铺来做实验的时候,大部分的数据还是集中在1个brand的购买。可以想象,在现实场景中,多个brand的比例会有上升,命
中率也能因此增加

以下是关于数据集的信息

数据信息 个数
item 35533
交易记录 47.8万
user 17.7万
brand数 30

划分test,training set的方法和单店铺类似,挑选在3个brand购买的消费者,然后将其中一个brand的交易记录分到test set,在training set上删去那个brand的交易记录

各个方法比较如下:

方法 命中率
implicit feedback 27.9%
popular 30.3%
popular+implicit 34.6%

如果单纯用implicit feedback来预测的话,由于缺少了在对应店铺的购买,推荐效果不是很好,甚至都没有popular商品的命中率高。 因此我们采用popular+implicit feedback的方法,在每个cat的推荐上加入一个popular,其余仍然保留implicit feedback的推荐,这样子既考虑了popular,又保留了基于消费者的个性推荐