在最理想的情况下,推荐系统应当将用户最可能喜欢的物品推荐给用户。然而,由于计算和存储资源总是有限的,推荐系统往往必须在推荐性能和准确率之间做权衡。本文将介绍如何通过配置对Gorse的计算资源使用量、存储资源使用量和推荐准确率之间进行权衡。
设置物品和反馈的有效时间
在默认的配置下,Gorse会读取数据表内的全部数据作为训练数据。在配置文件中,可以通过item_ttl
和positive_feedback_ttl
限制读取的物品和反馈数量。如果物品的时间戳距今超过item_ttl
天,那么Gorse不再读取此物品数据。如果反馈的时间戳距今超过 positive_feedback_ttl
天,那么Gorse同样不再读取此反馈。使用TTL的优缺点如下:
- **优点:**移除过时的物品和反馈可以减少Gorse需要处理的数据量。太过时的物品例如新闻是没有推荐价值的,同样太久远的用户历史记录并不能反应当前的用户兴趣,适当地移除过时的物品和反馈对推荐系统是有益的。
- **缺点:**如果TTL设置果断,会导致推荐算法训练中获取的信息量不足。
TTL用于移除过时的物品和反馈,但是应该设置得足够长防止丢失信息。
# The time-to-live (days) of positive feedback, 0 means disabled. The default value is 0.
positive_feedback_ttl = 0
# The time-to-live (days) of items, 0 means disabled. The default value is 0.
item_ttl = 0
设置训练和推荐频率
在Gorse推荐系统之中一共有三个循环执行的任务,分别是:
- 模型训练循环:主节点加载数据,使用最新数据训练推荐模型,以及更新最新物品、热门物品、相似物品、相似用户等内容,模型训练循环的间隔对应配置文件中的
fit_period
。 - 模型优化循环:主节点加载数据,使用随机搜索查找推荐模型的最佳参数。循环间隔通过
search_period
设置,模型优化循环间隔的值可以设置得比较长。除非数据集发生巨大变化,否则最佳模型参数都是比较稳定的。 - 推荐生成循环:工作节点检查每个用户是否应当更新推荐结果,检查的时间间隔为
check_recommend_period
分钟,如果需要更新测按照推荐策略生成推荐。用户更新推荐的条件是:用户的最后活跃时间超过最后生成推荐时间,或者最后生成推荐时间距今超过refresh_recommend_period
天。检查推荐结果的间隔check_recommend_period
应该设置得比较短,建议在几分钟左右,从而能够应对用户的推荐结果消耗。
循环间隔时间太长会导致模型和推荐结果过时,循环间隔时间太短会导致数据库和缓存负载过高。总之,check_recommend_period
应当较小,search_period
应当较大,fit_period
需要根据数据库负载进行合理设置。
# The time period for model fitting (minutes). The default values is 60.
fit_period = 360
# The time period for model searching (minutes). The default values is 100.
search_period = 60
# The number of epochs for model searching. The default values is 100.
search_epoch = 100
# The number of trials for model searching. The default values is 10.
search_trials = 10
# The time period to check recommendation for users (minutes). The default values is 1.
check_recommend_period = 1
# The time period to refresh recommendation for inactive users (days). The default values is 5.
refresh_recommend_period = 1
check_recommend_period
是尚未发布的v0.3.4新增配置项,目前可以在nightly版本中使用,
开启相似物品和用户向量索引
Gorse会为每个用户和物品查询相似物品,用于相似物品推荐和基于相似用户的推荐。假设有N个物品,那么查询一件物品的相似物品的计算量就是O(N),为全部物品生成相似物品的计算量就是O(N^2)。Gorse提供了基于聚类的向量索引加速相似物品和用户的查询。相似物品(用户)向量索引首先对物品(用户)按照相似度进行聚类,也就是将最相似的物品(用户)分到多个组内。在查询相似物品(用户)的时候,首先找到中心点和当前物品(用户)最相似的K个组,然后再在K个组内查询相似物品(用户),算法基于思想源自于 [1]。
相似物品(用户)向量索引可以通过enable_item_neighbor_index
(enable_user_neighbor_index
)进行开关,目前版本默认关闭,后续版本考虑默认打开。相似物品(用户)向量索引需要设置参数K,也就是查询的组数,K太小会导致向量索引无法到达可用的精度,K太大则会降低查询性能。构建过程会尝试不断增大K,如果查询准确率到达item_neighbor_index_recall
(user_neighbor_index_recall
),或者增长次数到达item_neighbor_index_fit_epoch
(user_neighbor_index_fit_epoch
),那么构建过程停止增长K。
# Enable approximate item neighbor searching using vector index.
enable_item_neighbor_index = true
# Minimal recall for approximate item neighbor searching.
item_neighbor_index_recall = 0.8
# Maximal number of fit epochs for approximate item neighbor searching vector index.
item_neighbor_index_fit_epoch = 3
# Enable approximate user neighbor searching using vector index.
enable_user_neighbor_index = true
# Minimal recall for approximate user neighbor searching.
user_neighbor_index_recall = 0.8
# Maximal number of fit epochs for approximate user neighbor searching vector index.
user_neighbor_index_fit_epoch = 3
使用相似物品/用户向量索引的优缺点如下:
- 优点:节省相似物品/用户查询时间。
- 缺点:索引需要额外的内存,如果数据难以分组(例如随机生成数据),那么索引查询准确率会很低。
相似用户和相似物品的向量查询精度在控制台主面板系统信息中的“User Neighbor Index Recall”和“Item Neighbor Index Recall”可以看到,如果数值过低的话需要关闭相似物品/用户向量索引。
开启协同过滤向量索引
Gorse的协同过滤算法将用户和物品映射为一组向量,对于每个用户,找到和用户向量点乘最大的物品向量即为推荐物品。因此,最直观的推荐物品搜索方法就是扫描全部物品,在扫描过程中求向量点乘,选择点乘最大的前几样物品作为推荐结果。假设有N个用户和M个物品,那么为全体用户生成推荐结果的计算量就是O(MN)。然而,如果物品和用户数据都比较大,那么整体计算量是令人无法接受的。
一种更加高效的方法是使用向量索引HNSW [2]。首先,HNSW索引会为所有的物品向量创建一张导航图。然后,只需要在导航图中查询用户向量点乘最大的物品向量,而不需要遍历全部的物品。HNSW索引上查询得到的结果不是精确的,但是极少的精度损失换取巨大的性能提升是值得的。HNSW向量索引可以通过enable_collaborative_index
进行开关,目前版本默认关闭,后续版本考虑默认打开。HNSW向量索引需要设置一个参数ef_construction,ef_construction太小会导致向量索引无法到达可用的精度,ef_construction太大则会降低查询性能。构建过程会尝试不断增大ef_construction,如果查询准确率到达collaborative_index_recall
,或者增长次数到达collaborative_index_fit_epoch
,那么构建过程停止增长ef_construction。
# Enable approximate collaborative filtering recommend using vector index.
enable_collaborative_index = false
# Minimal recall for approximate collaborative filtering recommend.
collaborative_index_recall = 0.9
# Maximal number of fit epochs for approximate collaborative filtering recommend vector index.
collaborative_index_fit_epoch = 3
使用向量索引进行协同过滤推荐的优缺点如下:
- 优点:向量索引可以显著提高协同过滤推荐速度,并且准确率在大部分情况下都不错。
- 缺点:创建HNSW索引需要额外的内存空间,在极少情况下会产生比较低的准确率。
协同过滤的向量查询准确率对应控制台主面板系统信息中的“Matching Index Recall”,如果数值比较低那么可以考虑关闭索引查询改用简单遍历。
参考文献
- Auvolat, Alex, et al. "Clustering is efficient for approximate maximum inner product search." arXiv preprint arXiv:1507.05910 (2015).
- Malkov, Yu A., and Dmitry A. Yashunin. "Efficient and robust approximate nearest neighbor search using hierarchical navigable small world graphs." IEEE transactions on pattern analysis and machine intelligence 42.4 (2018): 824-836.