(g)分别计算种子用户和潜在目标用户的向量集,并比对相似性,我们使用的是余弦相似度计算相似性,将步骤f得到的用户特征向量集作为输入x,y,代入下面公式计算相似性:
使用余弦相似度要注意:余弦相似度更多的是从方向上区分差异,而对绝对的数值不敏感。因此没法衡量每个维度值的差异,这里我们要在每个维度上减去一个均值或者乘以一个系数,或者在之前做好归一化。 (h)受众扩展 获取种子受众名单,以及目标受众的数量N; 检查种子用户是否存在于UVS中,将存在的用户向量化; 计算受众名单中用户和UVS中用户的相似度,提取最相似的前N个用户作为目标受众。 最后我们将以上步骤串联起来,形成如图5所示。
图5 Lookalike算法示意图 在以上步骤中特征提取完成后,我们使用一个2层的神经网络做最后的特征提取,算法结构示意图如图6所示。
图6 Lookalike算法结构图 其中FC1层也可以替换成MaxPooling,MaxPooling层具有强解释性,也就是在用户特征群上提取最重要的特征点作为下一层的输入,atv,读者可以自行尝试,这里限于篇幅问题就不做展开了。 讲到这里,算法部分就已基本完结,其中还有些工程问题,并不属于本次主题探讨范围,这里也不做讨论了。 结果 我司算法团队根据Lookalike思想完整实现其算法,并在实际产品中投入试用。针对某客户(乳品领域世界排名前三的品牌主)计算出结果(部分):
表1 部分计算结果 可以观察到以上微博ID的主题基本都是西点企业或西点培训企业,和品牌主售卖的乳品有很高的关联性:乳品是非常重要的西点原料,除终端用户外,西点相关企业就是乳品企业主需要寻找的最重要的受众之一。 探讨 特征表达 除了以上提到的特征外,我们也对其他的重要特征表达做了处理和变换:根据我们的需求,需要抽取出人的兴趣特征,如何表达一个人的兴趣?除了他自己生成的有关内容外,还有比较关键的一点是比如“我”看了一些微博,但并没有转发,大多数情况下都不会转发,但有些“我”转发了,有些“我”评论了;“我”转发了哪些?评论了哪些?这次距上次的浏览该人的列表时间间隔多久?都代表“我”对微博的兴趣,而间接的反应“我”的兴趣特征。这些数据看来非常重要,又无法直接取得,怎么办? 下面来定义一个场景,试图描述出我们对看过的内容中哪些是感兴趣的,哪些不是感兴趣的: (a)用户A,以及用户A关注的用户B; (b)用户A的每天动作时间(比如他转发、评论、收藏、点赞)起始时间,我们定义为苏醒时间A_wake(t); (c)用户B每天发帖(转发、评论)时间:B_action(t); (d)简单假设一下A_wake(t)> B_action(t),也就是B_action(t)的评论都能看到。这就能得到用户A对应了哪些帖子; (e)同理,也可知用户A 在A_wake(t)时间内转发了、评论了哪些帖子; (f)结合上次浏览间隔时间,可以描述用户A对哪些微博感兴趣(post ive),哪些不感兴趣(negative)。 全连接层的激活单元比对提升 在Google那篇论文中比对隐含层(也就是我们结构图中的FC层)各种单元组合产生的结果,Google选择的是最后一种组合,如图7所示。
图7 YouTube推荐模型隐含层单元选择对比 我们初期选用了512 tanh→256 tanh 这种两层组合,后认为输入特征维度过大,512个单元无法完整的表达特征,故又对比了 1024→512组合,发现效果确实有微小提升大概在0.7%。另外我们的FC层输入在(-1,1)区间,考虑到relu函数的特点没有使用它,而是使用elu激活函数。测试效果要比tanh函数提升0.3%-0.5%。 附node2vec伪码:
感谢我司算法组周维在拟写这篇文章时提供的帮助。 作者简介 (责任编辑:本港台直播) |