兔小巢热搜实践

目录

热搜是何方神圣
热搜算法
    简单的词频统计
    牛顿冷却算法
    高斯(正态)分布算法
兔小巢所需热搜业务场景分析
兔小巢热搜模块架构

热搜是何方神圣

很多产品都会有类似于热搜或者热榜的功能,总的来说都是热点数据的挖掘,属于推荐系统范畴。如点评类的产品(豆瓣、大众点评网、IMDB),资讯类的产品(腾讯新闻、今日头条、天天资讯),问答类的产品(知乎、StackOverflow),视频类的产品(腾讯视频、bilibili),社交类产品(微博、小红书)都会使用热搜或者热榜的形式来展示一些热点数据。通过这种方式可以吸引用户来观看优质的内容,提高信息获取效率,提高信息曝光与互动,(对于兔小巢可以减少重复提问,也能提高产品经理信息检索效率)进而提高用户使用产品的体验以及用户的粘性。


热搜算法

笔者通过查询资料发现,每个产品会根据其不同特征采取的不同热搜或者热榜算法。如微博的热搜更考虑短期内对热点事件的搜索量、bilibili的热榜会考虑时投币数,播放量,点赞量,评论量等因素……因此,在考虑热搜和热榜的算法的时候,可以从自己产品的特点入手,引入产品中自有的因素,如时间、搜索量、评论数、点赞数等。

热点数据的算法可以根据几个重要特征分为:1. 按时间维度;2. 按访问量(搜索量、点击量、播放量);3. 按评分;4. 以上两种或以上的综合考虑。

接下来,介绍本人在探索兔小巢热搜过程中使用过的几个算法(方案)。

简单的词频统计

这个方案很简单,就是对于每个词统计其搜索频率。打开es的搜索日志,通过搜索日志来统计词频,词频高的也就是所要的热搜词。虽然简单直观,但是缺点也很明显,就是不能考虑时间因素,会导致某个搜索词在一段时间被大量搜索后,在随后一直占据热搜榜首,新来的搜索词无法凸显出来。

牛顿冷却算法

为了考虑进时间这个因素,并且热度最好随着时间跨度而下降。牛顿冷却算法就是这么一种考虑进时间因素的算法,并且能够随着时间推移,热度可以快速下降。

原理:物体的冷却速度,与其当前温度与室温之间的温差成正比。简单点说我们可以将热词排名想象成一个即自然冷却的过程。可以利用物理学定律,建立“温度”与“时间”之间的函数关系,构建一个“指数式衰减”的过程。可用以下式子表示:

兔小巢热搜实践

其中w_freq表示词频,△t表示时间差。为了避免除数为0,结果出现负数的情况,以及实现随着时间差越大,热度下降越快的效果(最后趋于0),笔者对上式进行改造。得到如下式子:

兔小巢热搜实践

为了能够更加直观的表示,笔者尝试用上面的公式绘制了下图:

兔小巢热搜实践

上图中,词频取区间[0-1000],时间差为[0-6]天。我们可以看到,词频越高最后的分数也就越高。且随着时间差越大,分数也能够快速下降。达到了符合笔者期望的结果。

牛顿冷却算法虽然达到了笔者最初的预想效果,但是本算法在计算热度的时候,前一两天的热度分数会比较高,而后面下降得太快,可能会导致无法很好考虑最近连续几天都出现的搜索词。

代码(Go版):

// NewtonsLawOfCooling// 本算法是以牛顿冷却定律为基础,根据兔小巢热搜词的特点,改造出来的搜索词热度计算算法// 原公式及原理:见参考文献// @param: temperature 温度,即单词出现的频率,单位:次// @param: deltaTime 时间差,单位:天func NewtonsLawOfCooling(temperature float64, deltaTime float64) float64 {  deltaTime += 1.0                                          // 加1,避免时间作为除数的时候为0  index := 4.0                                              // 幂指数,index数值越大,随着时间差越大,最终结果会下降得更快  deltaTime = math.Pow(deltaTime, index)                    // 求幂  result := math.Log((temperature + deltaTime) / deltaTime) // 取对数,使得结果更平滑一些  return result}

高斯(正态)分布算法

上面的牛顿冷却算法有个小问题就是下降过快,如果对于某个产品,最近几个小时或者最近几天的热度都比较重要,那么牛顿冷却算法可能不再适用。因此,可以考虑引入高斯(正态)分布算法来解决这一问题。

原理:从统计学的意义上来看,很多数据的分布都会遵循类似下图的概率分布。其公式为:我们可以将某天中的一个词的搜索频度看作一个在时间跨度上的正态分布,也就是热度看作词频乘以一个时间跨度上正态分布概率,再做稍微改造得到下式:

兔小巢热搜实践

兔小巢热搜实践

我们可以将某天中的一个词的搜索频度看作一个在时间跨度上的正态分布,也就是热度看作词频乘以一个时间跨度上正态分布概率,再做稍微改造得到下式:

兔小巢热搜实践

上式中w_freq是词的搜索频次、△t表示时间跨度以及△t_max表示数据中最大的时间跨度。取词频为[0-1000]、△t为[0-7]、△t_max为7,依据上述公式,可以绘制如下图:

兔小巢热搜实践

对比牛顿冷却算法,可以从图中看到前几天热度随时间下降得更加平缓。

代码(Go版):

// GaussianDistribution 高斯分布(正态分布)// 本算法是利用高斯分布算法来计算热搜,相对于牛顿冷却算法,前面几天的热度下降会比较缓慢// 原公式及原理:见参考文献// fr=aladdin// @param: frequency 温度,即单词出现的频率,单位:次// @param: deltaTime 时间差,单位:天// @param: deltaMaxTime 最大时间差,比如计算最近两个月的热搜词,那么该值应该是60.0 单位:天func GaussianDistribution(frequency float64, deltaTime float64, deltaMaxTime float64) float64 {  index := 2.0                                       // 幂指数,index数值越大,随着时间差越大,最终结果会下降得更快  x := -math.Pow(2*deltaTime/deltaMaxTime, index)    // 自然数e的幂指数  distribution := math.Pow(math.E, x)          // 求高斯分布值  return frequency * distribution                    // 返回结果}
牛顿冷却算法和高斯分布算法实验比较

假设以下是某产品一周的搜索记录:

兔小巢热搜实践

计算结果(按得分从高到低):

兔小巢热搜实践

分析上面的结果,最明显的是支付失败常见问题两个搜索词在不同算法下,其最终热度也是不一样的。可以看出牛顿冷却算法更加考虑最近一天的数据,对于时间跨度较长的搜索词,其计算出来的分数下降得比较快。而高斯分布算法会将近几天的搜索量的热度提高,这点在常见问题支付识别热度得分高近两倍可以比较明显的看出。

其他的如时间干预法,反对票算法(适用于有点赞和踩的产品)、贝叶斯平均法(适用于避免某个因素对最后影响过大)、今日头条热榜算法等,由于并不适用于兔小巢业务,笔者就没有去尝试实现,如果读者有兴趣可以查看参考文献或自行查阅资料。

对于上述算法,笔者从兔小巢业务出发(目前只需考虑搜索量以及时间因素),在和组内人员和产品探讨后最终选择了高斯分布算法。前文也提到,不同的业务,具有不同的特征,因此读者在设计热搜算法时应该从产品业务的客观特征出发,选用或设计更符合产品特征的热搜算法。


兔小巢所需热搜业务场景分析

谈完算法,需要回归到兔小巢业务本身,分析整个兔小巢业务逻辑,从而设计出更符合兔小巢业务的热搜模块架构。

兔小巢产品特点:

  •  兔小巢类似于论坛,每个产品都是一个独立社区。


  •  有的产品用户比较多,搜索量也大。


  • 有的产品用户比较少,搜索量少,甚至可能一两周之内都不会有人搜索。

从特点出发,分析潜在的问题,给出解决方案:

  • 兔小巢每个产品都是一个独立社区。因此不能像其他应用(如微博)那样,对全局的搜索词进行统计。而是需要每一个产品内部自己维护一个搜索记录,最后根据每个产品的搜索记录计算出各自的热搜词。

  • 有的产品用户比较多,搜索量也大。如果将每天的搜索记录都写到一行记录中去的话,会导致比较久远已经失去时效性的记录无法删除,同时记录表也会越来越大。故最好采用按天记录的方式,这样一来对于超过一周或者一个月的搜索记录可以删除,减轻数据库负担。

  • 有的产品用户比较少,搜索量少,甚至可能一两周之内甚至更长时间内都不会有人搜索。如果像大产品一样频繁的启动热搜计算,会导致计算资源浪费。对于这种情况,可以采取的策略是最近一天或者两天有搜索记录了,再去启动热搜计算。如果最近一天或者两天没有搜索记录,则维持原有的热搜计算结果,不更新。


兔小巢热搜模块架构

结合上述兔小巢业务分析,热搜模块架构方案如下:

  • 每个产品的当天的搜索词,都记录到redis的sorted set结构中。次日凌晨更新到数据库中,每个产品每天的搜索记录做一行表记录,并删除redis中的key。redis的key为<code>product_search_history:[产品id]:[日期]</code>。

  • 启动定时(一天或者两天)脚本,定时扫描数据库,判断每个产品是否有新的搜索记录。如果有新的搜索记录,那么就将该产品最近7天(或者60天)的搜索记录取出,利用选用的热搜算法进行进行。最后将计算出来排名前十的热搜词持久化到数据库。

兔小巢热搜实践


参考文献:
深度解读:小红书热搜词底层逻辑,助力小红书笔记上热门
热词统计发现算法3则
热词提取方法探讨
高斯(正态)分布-百度百科
牛顿冷却定律-百度百科
从豆瓣电影评分算法说起
热榜推荐算法总结


 

兔小巢热搜实践


快乐工作,快乐生活
Happy work , Happy life
/
Join us

本篇文章来源于微信公众号: 腾讯CDC体验设计

UI/UX

京服宝设计分享-为服务提供者设计

2022-3-15 16:30:00

UI/UX

华为鸿蒙设计指南,能否引领行业?

2022-3-16 8:20:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索