背景
打散是在推荐、广告、搜索系统的结果基础上,提升用户视觉体验的一种处理。主要方法是对结果进行一个呈现顺序上的重排序,令相似品类的对象分散开,避免用户疲劳。算法端传出的推荐结果,往往具有以下几个痛点:
相似品类的商品易扎堆。显然的,如果商品的各特征相似,其获得的推荐分数也容易相近,而满目的同款肯定不是用户期望的结果。
对用户的偏好捕捉太强。用户心理层面,对于隐私或者偏好被完美捕捉这件事是敏感的,过于精准的结果不但容易导致用户的反感,也容易限制用户潜力的转化。
产生的错误容易被放大。对于几乎没有什么使用痕迹的用户,很容易出现对仅有特征的放大,从而就容易产生错误推荐。
而打散算法,通过呈现顺序的改变,将相似品类分开,缓冲了推荐系统和用户的交互,提升了用户体验,是算法赋能落地的最后一步。
问题定义
首先,我们明确打散算法的定义。其输入是算法端根据用户偏好程度排列的有序列表,每个对象拥有一个或多个需要加以区分的属性,输出的要求是将相似属性分散开后的一个列表。其中会涉及到这几个细节:
打散程度。究竟是让相同类目的尽可能分隔开,还是只要间隔一定距离就可以满足要求?
打散依据的维度。是按照一种属性分开就可以,还是存在多种需要考虑分开的因素?
打散的性能。作为经常调用的一种接口,性能的优化当然是越多越好。
值得注意的是,我们并不希望丢失算法端系统带来的用户个性因素,所以如何在打散的基础上,充分利用好原对象的顺序,也是非常值得权衡的问题。
解决方案
从三个不同的维度,我们将讨论三种比较通用的打散办法。三种方法中,打散程度最彻底的,是按列打散法;能综合多维度考虑的,是权重分配法;只需要局部计算来提高性能的,是滑动窗口法。
按列打散法
既然要避免相似属性的内容在呈现时相邻,很直接的思路是我们将不同属性的装在不同的桶里,每次要拿的时候尽量选择不同的桶。这样就可以实现将元素尽量打散。如下图所示,在这个例子