使用lightFM通过推荐系统解决业务用例(Python实例)
在这篇文章中,我将介绍推荐系统,以及它们在许多电子商务网站中的使用方式。这篇文章还将介绍如何使用基于Matrix分解算法的lightFM软件包(https://github.com/lyst/lightfm)和推荐系统cookbook(https://github.com/aayushmnit/cookbook/blob/master/recsys.py)来构建简单的推荐系统模型。这篇文章将重点讨论业务用例和简单Python实现。这篇文章只涵盖了算法的基本直觉,如果你想了解算法背后的数学知识,请阅读相关资源。
动机
在互联网上搜索高质量的内容时,我遇到了各种学习环节,它们要么侧重于使用ABC语言的特定数据/建模技术实现算法,要么侧重于使用一系列算法的广义概念(如分类、预测、推荐系统等)来实现业务影响/结果,但没有详细介绍如何实现算法。因此,我们的想法是编写一些文章,将业务用例与代码和算法直觉结合起来,以提供数据科学如何在业务场景中使用的整体视图。
随着世界变得越来越数字化,我们已经习惯了许多个性化的体验和帮助我们实现这一目标的算法。几乎每个基于web的平台都使用推荐系统来提供定制的内容。
什么是个性化?
个性化是一种根据每个用户的需求动态调整内容的技术。个性化的简单例子可以是Netflix上的电影推荐,电子商务平台的个性化电子邮件定位/重新定位,亚马逊物品推荐等。个性化有助于我们实现这四个R -
- Recognize: 了解客户和潜在客户的资料,包括群体统计资料,地理位置以及表达和共享的兴趣。
- Remember:回顾客户的历史,主要是他们如何表现他们浏览和购买的内容
- Reach: 根据行动,偏好和兴趣为客户提供正确的促销,内容和推荐
- Relevance: 在数字体验的背景下实现个性化,具体取决于谁是客户,他们位于何处以及每年的什么时间
为什么个性化?
个性化对用户和公司都有很多好处。对于用户来说,这让他们的生活变得简单,因为他们只能看到更多与他们相关的东西(除非是广告,即使是个性化的)。
- 增强客户体验:个性化减少了混乱,通过显示相关内容来增强客户体验
- 交叉销售/向上销售机会:基于客户偏好的相关产品可以提高产品的可见性,并最终销售更多的产品
- 增加购物篮的数量:个性化的体验和目标最终导致购物篮的增加和频繁的购买。
- 增加客户忠诚度:在数字世界中,客户保留/忠诚是许多公司面临的最突出的问题,因为找到一个替代特定服务的替代品相当容易。根据《福布斯》杂志的一篇文章,44%的消费者表示,经过个性化体验后,他们很可能会重复这一过程
介绍矩阵分解
矩阵分解是推荐系统家族的算法之一,顾名思义,它可以分解矩阵。,将一个矩阵分解成两个(或多个)矩阵,这样一旦你把它们相乘,你就能得到原来的矩阵。在推荐系统中,我们通常从用户和items之间的交互/评级矩阵开始,矩阵分解算法将该矩阵分解为用户和item特征矩阵,也称为嵌入(embeddings)。交互矩阵的例子是电影推荐人的用户电影评分、交易数据的用户产品购买标志等。
典型地,用户/item嵌入分别捕获关于用户和item的属性的潜在特征。实质上,潜在特征是用户/item在任意空间中的表示,其表示用户如何评价电影。在电影推荐的例子中,一个用户嵌入的例子可能代表了当潜在特征的价值高时用户观看严肃类型电影的亲和力,当价值低时则代表喜剧类型的电影。类似地,当电影更多的是男性喜欢的时候,电影的潜在特征可能会有很高的价值,而当它更多的是女性喜欢的时候,它的价值通常是低的。
HandOn:使用Python中的LightFM包构建推荐系统
在“实践”部分,我们将为不同的场景构建推荐系统,我们通常在许多公司中看到使用LightFM包和MovieLens数据。我们正在使用小尺寸(http://files.grouplens.org/datasets/movielens/ml-latest-small.zip)的数据,其中包含10万的评分和1300个标签应用于9000部电影,由700个用户使用
数据
让我们从导入数据,推荐系统cookbook(https://github.com/aayushmnit/cookbook/blob/master/recsys.py)和预处理cookbook文件(https://github.com/aayushmnit/cookbook/blob/master/generic_preprocessing.py)开始这个动手部分。我使用可重用的通用cookbook代码,可以提高生产力并编写清洁/模块化代码; 你会看到我们可以使用这些cookbook来建立一个使用10-15行代码的推荐系统。
# Importing Libraries and cookbooks
from recsys import * ## recommender system cookbook
from generic_preprocessing import * ## pre-processing code
from IPython.display import HTML ## Setting display options for Ipython Notebook
# Importing rating data and having a look
ratings = pd.read_csv('./ml-latest-small/ratings.csv')
ratings.head()
评分数据
正如我们所看到的,评级数据包含用户ID,电影ID和0.5到5之间的评分,并带有表示何时给出评分的时间戳。
# Importing movie data and having a look at first five columns
movies = pd.read_csv('./ml-latest-small/movies.csv')
movies.head()
电影资料
电影数据由电影ID,其标题以及它们所属的流派组成。
预处理
正如我之前提到的,要创建推荐系统,我们需要从创建交互矩阵开始。对于这个任务,我们将使用recsys cookbook中的create_interaction_matrix函数。此功能要求您输入pandas 数据框和必要的信息,如用户标识,item标识和评级的列名称。如果norm = True,它还需要一个额外的参数阈值,这意味着任何高于所述阈值的评级都被视为正评级。在我们的情况下,我们不必对数据进行归一化,但在零售数据的情况下,购买特定类型的商品可以被视为正面评价,数量无关紧要。
# Creating interaction matrix using rating data
interactions = create_interaction_matrix(df = ratings,
user_col = 'userId',
item_col = 'movieId',
rating_col = 'rating')
interactions.head()
交互数据
正如我们所看到的,数据是以交互格式创建的,其中行代表每个用户,列代表每个电影ID,并将评分作为值。
我们还将创建用户和项目字典,以便稍后通过使用create_user_dict和create_item字典函数将user_id转换为user_name或movie_id转换为movie_name 。
# Create User Dict
user_dict = create_user_dict(interactions=interactions)
# Create Item dict
movies_dict = create_item_dict(df = movies,
id_col = 'movieId',
name_col = 'title')
构建矩阵分解模型
要构建矩阵分解模型,我们将使用runMF函数,该函数将采用以下输入 -
- 交互矩阵(interaction matrix):在前一节中创建的交互矩阵
- n_components:为每个用户和项目生成的嵌入数量
- loss:我们需要定义损失函数,在这种情况下,我们使用的是warp loss ,因为我们主要关心数据的排名,即我们应该先显示哪些项目
- epoch:运行次数
- n_jobs:并行处理中使用的核心数量
mf_model = runMF(interactions = interactions,
n_components = 30,
loss = 'warp',
epoch = 30,
n_jobs = 4)
现在我们已经构建了我们的矩阵分解模型,现在我们可以做一些有趣的事情。有许多用例可以通过使用这个模型来解决,我们来看看它们。
用例1:项目推荐给用户
在这个用例中,我们想要向用户展示他可能有兴趣根据他/她过去完成的交互操作购买/查看的项目。典型的行业案例就像亚马逊的“为您推荐的优惠”或者Netflix或个性化电子邮件广告系列中的“用户最热门照片”。
我们可以在这种情况下使用sample_recommendation_user函数。该函数以矩阵分解模型,交互矩阵,用户字典,item字典,用户ID和item数量作为输入,并返回用户可能有兴趣进行交互的item标识列表。
## Calling 10 movie recommendation for user id 11
rec_list = sample_recommendation_user(model = mf_model,
interactions = interactions,
user_id = 11,
user_dict = user_dict,
item_dict = movies_dict,
threshold = 4,
nrec_items = 10,
show = True)
Known Likes:
1- The Hunger Games: Catching Fire (2013)
2- Gravity (2013)
3- Dark Knight Rises, The (2012)
4- The Hunger Games (2012)
5- Town, The (2010)
6- Exit Through the Gift Shop (2010)
7- Bank Job, The (2008)
8- Departed, The (2006)
9- Bourne Identity, The (1988)
10- Step Into Liquid (2002)
11- SLC Punk! (1998)
12- Last of the Mohicans, The (1992)
13- Good, the Bad and the Ugly, The (Buono, il brutto, il cattivo, Il) (1966)
14- Robin Hood: Prince of Thieves (1991)
15- Citizen Kane (1941)
16- Trainspotting (1996)
17- Pulp Fiction (1994)
18- Usual Suspects, The (1995)
Recommended Items:
1- Dark Knight, The (2008)
2- Inception (2010)
3- Iron Man (2008)
4- Shutter Island (2010)
5- Fight Club (1999)
6- Avatar (2009)
7- Forrest Gump (1994)
8- District 9 (2009)
9- WALL·E (2008)
10- Matrix, The (1999)
print(rec_list)
[593L, 260L, 110L, 480L, 47L, 527L, 344L, 858L, 231L, 780L]
正如我们在这种情况下看到的,用户对“Dark Knight Rises(2012)”感兴趣,所以第一个建议是“The Dark Knight(2008)”。这位用户似乎对戏剧,科幻和惊悚类电影有强烈的喜好,并且有许多电影推荐了像Dark Knight(Drama/Crime), Inception(Sci-Fi, Thriller), Iron Man(Sci-FI thriller), Shutter Island(Drame/Thriller), Fight club(drama), Avatar(Sci-fi), Forrest Gump(Drama), District 9(Thriller), Wall-E(Sci-fi), The Matrix(Sci-Fi)
类似的模型也可以用于构建像“根据您最近的浏览历史”推荐的部分,只需更改评级矩阵以仅包含最近的交互并基于特定item的浏览历史访问。
用例2:对item的推荐
在这个用例中,我们将讨论我们如何推荐特定item的特定用户列表。这种情况的例子是,当您在某个item上运行促销并且想要围绕此促销item运行电子邮件活动时,只有10,000个可能对此item感兴趣的用户。
我们可以在这种情况下使用sample_recommendation_item函数。该功能将矩阵分解模型,交互矩阵,用户字典,item字典,item_id和用户数量作为输入,并返回更有可能对item感兴趣的用户标识列表。
## Calling 15 user recommendation for item id 1
sample_recommendation_item(model = mf_model,
interactions = interactions,
item_id = 1,
user_dict = user_dict,
item_dict = movies_dict,
number_of_user = 15)
[116, 410, 449, 657, 448, 633, 172, 109, 513, 44, 498, 459, 317, 415, 495]
正如你所看到的,函数返回可能对item id 1感兴趣的userID列表。另一个可能需要这种模型的例子是当仓库中有一个旧库存需要清理时,否则你可能需要编写它关闭,你想通过给可能有兴趣购买的用户一些折扣来清除它。
用例3:对items的item推荐
在这个用例中,我们将讨论如何推荐特定item的特定items列表。这种模式将帮助您找到可以捆绑在一起的相似/相关物品或物品。这种模式的典型行业用例是在产品页面上的交叉销售和向上销售机会,例如“与此商品相关的产品”,“经常购买的商品”,“购买此商品的顾客也购买了此商品”和“查看此商品的顾客也看过“。
“购买此商品的顾客也购买了此商品”以及“查看此商品的顾客也查看了”也可以通过购物篮分析来解决。
为了实现这个用例,我们将使用由矩阵分解模型生成的项嵌入来创建一个余弦距离矩阵。这将帮助我们计算相似的黑白物品,然后我们可以推荐前N个相似的物品到感兴趣的物品。第一步是使用create_item_emdedding_distance_matrix函数创建item-item distance matrix 。该函数将矩阵分解模型和交互矩阵作为输入并返回一个item_embedding_distance_matrix。
## Creating item-item distance matrix
item_item_dist = create_item_emdedding_distance_matrix(model = mf_model,
interactions = interactions)
## Checking item embedding distance matrix
item_item_dist.head()
Item-Item distance
我们可以看到这个矩阵有电影作为行和列,值表示它们之间的余弦距离。下一步是使用item_item_recommendation函数获得关于item_id的前N项。该函数将项目嵌入距离矩阵、item_id、item_dictionary和推荐的项目数量作为输入,并返回相似的项目列表作为输出。
## Calling 10 recommended items for item id
rec_list = item_item_recommendation(item_emdedding_distance_matrix = item_item_dist,
item_id = 5378,
item_dict = movies_dict,
n_items = 10)
Item of interest :Star Wars: Episode II - Attack of the Clones (2002)
Item similar to the above item:
1- Star Wars: Episode III - Revenge of the Sith (2005)
2- Lord of the Rings: The Two Towers, The (2002)
3- Lord of the Rings: The Fellowship of the Ring, The (2001)
4- Lord of the Rings: The Return of the King, The (2003)
5- Matrix Reloaded, The (2003)
6- Harry Potter and the Sorcerer's Stone (a.k.a. Harry Potter and the Philosopher's Stone) (2001)
7- Gladiator (2000)
8- Spider-Man (2002)
9- Minority Report (2002)
10- Mission: Impossible II (2000)
正如我们可以看到的“Star Wars: Episode II — Attack of the Clones (2002)”电影,我们得到它的下一部电影是“Star Wars: Episode III — Revenge of the Sith (2005)”作为第一个推荐。