This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
<audio id="audio" title="21 | 构建一个科学的排行榜体系" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/7f/89/7fcdbf6ae0bb023daefabcc307d38f89.mp3"></audio>
前面的专栏文章中,我从最常见的内容推荐开始讲起,直到讲到了最复杂的深度学习在推荐系统中的应用原理,这些推荐算法都有一个特点:智能。
所谓智能,就是带有学习性质,能够和复杂的用户端形成互动,在互动过程中,算法参数得到更新和进化。
但是,智能这个高大上的词语,一定要以数据为前提的,我在专栏的第二篇文章中就和你透露过,推荐系统中有一个顽疾就是冷启动,冷启动就是没有数据,没有数据怎么和用户玩呢?
一个新用户来了,什么数据都还没有,推荐系统对其一无所知。这时候,你就需要一个排行榜了。
## 为什么要排行榜
排行榜,又名热门榜,听上去似乎是一个很常见的东西,原来它也算是推荐算法的一员?是的,它不但是,并且非常重要,而且其中也有不少的学问。
那么说排行榜到底有哪些用处呢?
1. 排行榜可以作为解决新用户冷启动问题的推荐策略。这个不难理解,当一个新用户刚注册时,可以把最近产品中热门的物品推荐给他。
1. 排行榜可以作为老用户的兴趣发现方式。即使是老用户,也可以在享受个性化推荐的同时去浏览热门的物品,从中看看哪些感兴趣,哪些不感兴趣,这些行为都是补充或者更新用户兴趣的数据来源。
1. 排行榜本身就是一个降级的推荐系统。推荐系统本身是一个软件,因此也会有出现问题的时候,也会有推荐不出来的时候,这个时候考虑到服务的可用性,用排行榜作为一种兜底策略,可以避免推荐位开天窗。
今天,我就和你聊聊如何根据自己的产品特点构建一个合理的排行榜。
## 排行榜算法
最简单的排行榜,就是直接统计某种指标,按照大小去排序。在社交网站上,按照点赞数、转发数、评论数去排序,这是一种最常见、最朴素的排行榜。
类似的做法还有,在电商网站上按照销量去排序。
这样的做法也算是推荐算法?当然我确实很难说它不是,因为确实简单,容易上线运行,但我只能说这样做不靠谱,不靠谱的原因在于以下的几个问题。
1. 非常容易被攻击,也就是被刷榜;
1. 马太效应一直存在,除非强制替换,否则一些破了纪录的物品会一直占据在榜单中;
1. 不能反映出排行榜随着时间的变化,这一点和马太效应有关。
既然朴素的排行榜有这些弊端,那么就针对他们来一一设计应对措施。
### 1.考虑时间因素
接下来,我要把用户给物品贡献的行为看做是用户在投票,这个很容易理解,好像热门的东西都是大多数人投票民主选举出来的。
排行榜中的物品,你可以想象它们每一个都是炙手可热的,都有一定的温度,那么这个温度按照热力学定律来讲,随着时间推移就一定会耗散到周围,温度就会下降。
或者,把排行榜想象成一个梯子,每个物品都在奋力往上爬,他们的动力来自用户的手动投票,物品本身都要承受一定的重力,会从梯子上掉下来,用户投票可以抵挡部分重力,投票数不及时或者不够,排行榜上的物品就会掉下来。
把这个规律反映在排行榜分数计算公式中就比简单统计数量再强制按照天更新要科学得多。Hacker News计算帖子的热度就用到了这个思想它们的做法用公式表达是下面这个样子。
$$\frac{P-1}{(T+2)^G}$$
公式中三个字母分别代表如下意义:
1. P得票数去掉帖子作者自己投票。
1. T帖子距离现在的小时数加上帖子发布到被转帖至Hacker News的平均时长。
1. G帖子热度的重力因子。
公式中,分子是简单的帖子数统计,一个小技巧是去掉了作者自己的投票。分母就是将前面说到的时间因素考虑在内,随着帖子的发表时间增加,分母会逐渐增大,帖子的热门程度分数会逐渐降低。
其中,重力因子的选择根据情况而定,重力因子越大,帖子的热度衰减越快,不同的重力因子对比如下图所示。
<img src="https://static001.geekbang.org/resource/image/8e/b1/8e2198331001233d2b93a877b412b0b1.png" alt="" />
可以看到,重力因子越大,衰减越快。
再看一下,相同重力因子选择的情形下,不同的得票数的对比。
<img src="https://static001.geekbang.org/resource/image/18/16/18d68d8218036fbbbd3222d033835516.png" alt="" />
这这个示意图可以看到,这个公式仍然能够反映出相同时间的帖子之间的相对热度差别。
另一个考虑时间因素的排行榜算法是牛顿冷却定律。物品受关注度如同温度一样,不输入能量的话它会自然冷却,而且物体的冷却速度和其当前温度与环境温度之差成正比。将这一定律表述为公式就是下面的样子:
$$ T(t) = H + C e^{-\alpha t} $$
公式中字母的意义如下。
- H为环境温度可以认为是平均票数比如电商中的平均销量由于不影响排序可以不使用。
- C为净剩票数即时刻t物品已经得到的票数也就是那个最朴素的统计量比如商品的销量。
- t为物品存在时间一般以小时为单位。
- $\alpha$ :是冷却系数,反映物品自然冷却的快慢。
问题来了,这个反映物品自然冷却快慢的 $\alpha$ 该如何确定呢有一个更直观的办法。假如一个物品在时间过去B个单位后因为增加了A个投票数而保持了热门程度不变那这样的话 $\alpha$ 应该是多少呢?简单把这个描述列成方程就是下面的样子。
$$ C e^{-\alpha t} = (C+A)e^{-\alpha (t + B)} $$
可以解得。
$$\alpha = \frac{1}{B}ln(1 + \frac{A}{C})$$
用这个公式加上自己产品的要求来确定 $alpha$ 就容易得多假如按照B = 24也就是过一天来看我来举几个例子。
<img src="https://static001.geekbang.org/resource/image/1d/bb/1dfbf15946ae2783807c074ca8eaf3bb.png" alt="" />
你可以在自己的产品中,设定一个假设,然后计算出相应的 $\alpha$ 来。
### 2.考虑三种投票
前面的热度计算方法,只考虑用户投票和用户弃权两种,虽然这种情况很常见,但是还有一些产品会存在运行用户投反对票的情形,比如问答网站中对答案的投票,既可以赞成,又可以反对。在这样的情形下,一般这样来考虑:
1. 同样多的总票数,支持赞成票多的,因为这符合平台的长期利益;
1. 同样多的赞成票数,支持最有价值的,同样这符合平台长期利益。
以国外某著名程序员问答网站为例,你就不要打听到底是哪个网站了,这个不重要,下面看一下他们对热门问题的热度计算公式:
$$ \frac{(log_{10}Qviews)\times{4} + \frac{Qanswers \times{Qscore}}{5} + \sum_{i}{Ascore_{i}}} {(\frac{Qage}{2}+\frac{Qupdated}{2}+1)^{1.5}} $$
这个公式有点复杂,其中的元素意义如下:
- Qviews: 问题的浏览次数。
- Qanswers:问题的回答数。
- Qscore问题的得分赞成数-反对数)。
- Ascore答案的得分。
- Qage: 问题发布距离当前的时间。
- Qupdated: 问题最后一次修改距离当前的时间。
这个问题热门程度计算方式,也考虑了时间因素。分母反映了问题的陈旧程度,修改问题可以让问题不要衰老过快。分子有三部分构成:
- 左边是问题的浏览量,反映了问题的受关注程度;
- 中间是问题的回答量和问题本身的质量分数的乘积,高质量、回答多的问题占优势;
- 右边是答案的总质量分。
### 3.考虑好评的平均程度
前面两种排行榜分数计算法都是以用户投票的绝对数量作为核心的那么换个思路来看从比例来看也是可以的。这也是一些点评网站常常采纳的模式比如电影点评网站通常会有一个Top250这也是一种排行榜以好评比例作为核心来计算排行榜分数。下面来看看这种排行榜。
一个经典的好评率估算公式,叫做威尔逊区间,它这样估算物品的好评率:
$$ \frac{\hat{p} + \frac{1}{2n}z^2_{1-\frac{\alpha}{2}} \pm z_{1-\frac{\alpha}{2}}\sqrt{\frac{\hat{p}(1-\hat{p})}{n} + \frac{z^2_{1-\frac{\alpha}{2}}}{4n^2}} }{1 + \frac{1}{n}z^2\_{1-\frac{\alpha}{2}}} $$
实在是对不起你啊,又给你搞出了一个超级复杂的公式。实际上,你照着公式中所需的元素去统计就可以计算出排行榜了。我解释一下这个公式中所需的元素,你就可以照着去搬砖了,可以不必理解其中的原理。
- $\hat{p}$ 就是好评率比如一百个点评的商品99个给了好评那么这个值就是0.99
- $z_{1-\frac{\alpha}{2}}$ 是一个置信水平为 $alpha$ Z统计量这个查表就可以得到。
威尔逊区间考虑了评价的样本数,样本不足时,置信区间很宽,样本很足时,置信区间很窄。那么这个统计量有哪些应用呢,比如说下面的几个情况。
1. 多大比例的人们会采取某种行为?
1. 多大比例的人认为这是一个Spam
1. 多大比例的人认为这是一个“值得推荐的”物品呢?
当你为每一个物品都计算一个威尔逊区间后你可以采用前面讲到的Bandit算法类似UCB的方式取出物品构建成一个略带变化的排行榜。
最后,为你呈上某电影点评网站为电影排行榜计算分数的公式,它是另一种对好评率的应用,针对评分类型数据的排行榜。
$$\frac{v}{v+m} R + \frac{m}{v + m} C$$
这个排行榜计算公式,也有一个响当当的名字,叫做“贝叶斯平均”。其中的元素意义描述如下:
- R物品的平均得分这个很简单有多少人评分把他们评分加起来除以人数就是了
- v参与为这个物品评分的人数
- m全局平均每个物品的评分人数
- C全局平均每个物品的平均得分
别看这个公式简单,它反映了这么几个思想在里面:
1. 如果物品没多少人为它投票也就是评价人数不足那么v就很小m就很大公式左边就很小右边就很大于是总分算出来很接近右边部分也就是接近全局平均分C
1. 如果物品投票人数很多那么v很大m很小分数就接近它自己的平均分R。
这个公式的好处是:所有的物品,不论有多少人为它评分,都可以统一地计算出一个合理的平均分数,它已经被国内外电影评分网站采纳在自己的排行榜体系中,当然,它们肯定各自都有根据实际情况的修改。
## 总结
今天,我主要讲到了三种构建排行榜分数的算法,因为排行榜的意义重大,所以不可以太随便对待,甚至应该比常规的推荐算法更加细心雕琢。
一个最最朴素的排行榜就是统计一下销量、阅读量等,但要让排行榜反映出热度的自然冷却,也要反映出用户赞成和反对之不同,还要反映出用户评价的平均水平。
你不要被前面那个非常大的一坨公式所吓倒,实际上,它统计起来很方便。这些公式都是在实际生产中演化而来的,你根据这些原理结合自己实际遇到的问题,也可以设计出符合自己业务要求的排行榜公式。
最后,提一个小问题给你,对于最后一个排行榜公式,如何改进才能防止水军刷榜?你可以给我留言,我们一起讨论。感谢你的收听,我们下次再见。
<img src="https://static001.geekbang.org/resource/image/87/b0/873b086966136189db14874181823fb0.jpg" alt="" />

View File

@@ -0,0 +1,112 @@
<audio id="audio" title="22 | 实用的加权采样算法" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/84/74/84f855c0a04dcefcac5dd8d0dac13974.mp3"></audio>
今天来讲一个非常轻松的话题,这个话题看似和推荐系统没什么关系,但肯定有用,只是在别的推荐系统相关话题里都没人会提。
## 一些场景
还记得前面讲到的用户画像吗?想象一个场景:你经过辛辛苦苦抓数据,清洗数据,收集用户行为,目的就是给用户计算兴趣标签。
这时候你可能会遇到一个两难的问题:如果给用户计算出兴趣标签的权重了,那应该保留多少标签呢?
保留太多的话,每次召回候选集时,计算复杂度可不低,只保留少部分吧,那真是手心手背都是肉,生怕丢弃的标签才是用户的真爱。
怎么办?这时候,你需要的一个简单的加权采样算法,每次召回时并不使用全部用户标签,而是按照权重采样一部分标签来使用,这样做的好处当然很明显:
1. 大大减少召回时的计算复杂度;
1. 可以保留更多的用户标签;
1. 每次召回计算时还能有所变化;
1. 虽然有变化,但是依然受标签的权重相对大小约束。
加权采样的应用不只这一个地方,比如在热门排行榜展示时,也可以用加权采样,而不仅仅按照排行榜分数顺序展示,采用加权采样的展示方法,会让排行榜每次刷新都略有变化,人民群众也会更加喜闻乐见。
下面介绍几种常用的加权采样算法及其原理,供你日常随手拿来使用。
## 加权采样
加权采样有两种情况,一种是能够已知全部样本的个数。这需要遍历整个样本,比如说用户标签采样输出,那么每次采样时仍然需要遍历所有的标签,来依次决定每一个标签输出的概率。
另一种是不知道总量样本是多大,或者总量很大,以至于你不愿意全部遍历之后再输出采样结果,这样的数据就是数据流,对应的就是流采样。
下面分别讲这两种采样方法。
### 1.有限数据集
等概率采样的方法非常简单,任意编程语言中都有伪随机数实现,就不在本文讨论范围内了。
现在假设你有用户标签若干每一个标签都有个权重w权重高低反映了用户对这个标签的感兴趣程度高低。你希望每次输出一部分标签用于召回推荐候选集每次输出时都不一样但是又能反映用户标签的权重输出的概率和权重成正比。
这时候你需要一个公式:
$$S_{i} = R^{\frac{1}{w_{i}}}$$
解释一下这个公式:
1. wi 是每个样本的权重,比如用户标签权重;
1. R是遍历每个样本时产生的0到1之间的随机数
1. Si就是每个样本的采样分数
遍历之后按照采样分数排序输出前k个结果就是你得到的采样结果。可以编程简单做个模拟比如下面有这样几个简单样本。
<img src="https://static001.geekbang.org/resource/image/70/7e/70e81cc194a14ba091a91ecb8bf2477e.png" alt="" />
模拟10000次后三个样本被采样次数如下
<img src="https://static001.geekbang.org/resource/image/dc/27/dc701147b5785fd40ad7205364feeb27.png" alt="" />
你可以看到,每个样本采样概率和它的权重成正比。
还有另一种加权采样方法,是利用指数分布。
我先给忘记了指数分布的人复习一下什么是指数分布。
假设你到银行去办业务,每个人办理业务的时间是不确定的,那每个人办理业务时间的概率分布就是指数分布,用教科书上的话说,就是两个事件发生的时间间隔。
指数分布的概率密度函数是:
<img src="https://static001.geekbang.org/resource/image/98/70/9894def1fc772650414574cbfbd55170.png" alt="" />
指数分布的参数Lambda它的倒数$\frac{1}{\lambda}$ 就是事件发生时间间隔的期望。把指数分布的这个意义放进标签中来考虑,标签的权重其实反映一个直觉:权重越大的标签,用户消费它就越频繁,也就是间隔时间就会短。
所以根据这个原理就有另一个加权采样的办法为每一个标签构造一个指数分布随机数这个指数分布的参数Lambda就是标签权重然后用这个指数分布的产生一个随机数再输出随机数最大的k个标签作为采样结果,是不是很完美?
还是上面的权重再来模拟10000次。<br />
<img src="https://static001.geekbang.org/resource/image/46/df/468fcee6b610b57649a62ad9904e75df.png" alt="" />
依然完美符合权重的相对大小。
### 2.无限数据集
上面的两种采样都是针对有限数据集的,也就是采样之前都要遍历一遍所有样本。那么如果面对的数据集无限大,或者不知道多大时,该怎么做加权采样呢?这就要讲到另一个采样算法了,名字叫蓄水池采样(也叫蓄水池抽样)。
蓄水池采样可以用在推荐系统的哪些地方呢?比如可以再模型融合之后加一层蓄水池抽样,或者在召回阶段加一层蓄水池采样,这样在不影响整个推荐流程和转化概率的前提下,降低计算复杂度和提升推荐多样性。
或者,在线阶段要使用用户的反馈行为做实时推荐,对于不同的用户,活跃程度不同,产生的反馈行为数量不同,你也可以用蓄水池采样,为每个用户取出固定数量的行为用于更新推荐结果。
下面,我先讲蓄水池采样,再讲加权蓄水池采样。
假如有一个数据集合一共有n条要从中采样取出k个那么每个样本被选中的概率就是 $\frac{k}{n}$ 。蓄水池采样的做法是:
1. 直接先取出前k个样本留着这k个就是随时准备最终要输出的
1. 从第k+1个开始每个都以 $\frac{k}{n}$ 的概率去替换那留着的k个样本中的一个。
这个过程随时可以取用那个k个集合作为输出结果任意时刻当总样本遍历了n个时他们的概率都是 $\frac{k}{n}$ 。这就是蓄水池采样蓄水池采样顾名思义k个元素的样本集合就是个蓄水池是任意时刻的采样结果可以随时取用。
现在回到我们今天的主题来,实际上更需要的是加权蓄水池采样。加权蓄水池采样利用的依然是在前面说的第一种加权采样方法,只不过结合了蓄水池采样的思想。
要从大数据集中采样k个其具体做法是这样的
1. 为每一个样本生成一个分数,分数还是用这个公式 $S_{i} = R^{\frac{1}{w_{i}}}$;
1. 如果结果不足k个直接保存到结果中
1. 如果结果中已经有k个了如果 $S_{i}$ 比已有的结果里最小那个分数大,就替换它。
## 总结
今天介绍的算法非常简单,但是在推荐系统中有很多的用途。尤其是面对的数据需要采样、需要有所变化时,加权采样本质上来说就是让权重影响采样概率。
前面的几种加权采样算法,都是让采样概率和权重成正比,这意味着你的样本权重之间的关系要合理。
那么,请思考另一个问题,如果你的样本权重有正有负,该如何加权采样呢?欢迎留言一起讨论。
感谢你的收听,我们下次再见。
<img src="https://static001.geekbang.org/resource/image/87/b0/873b086966136189db14874181823fb0.jpg" alt="" />

View File

@@ -0,0 +1,97 @@
<audio id="audio" title="23 | 推荐候选池的去重策略" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/8e/dc/8e55eaef05d421eadcf7e878e80c59dc.mp3"></audio>
今天依然要讲到两个问题,它们看似和推荐系统没有必然关系,但实际上,在你构建自己的推荐系统的时候,不可避免地会遇到这两个问题。
## 去重是刚需
在推荐系统中,有一个刚需就是去重,那么说在哪些地方有去重的需求呢?
主要是在两个地方:一个是内容源去重,另一个是不重复给用户推荐。
先说说内容源的去重,这部分以前几年的图文信息流推荐为典型的例子。
如果一个平台自己不生产内容,只是做内容搬运和聚合分发,那么从大量第三方的内容生产处抓取内容,就难免遇到相似甚至重复的内容。这就需要对内容做一个重复检测了。
对内容做重复检测,直观的思路是分词,然后提取关键词,再两两计算词向量之间的距离,距离小于一定阈值后就判定为重复。然而,这对于海量内容,比如几千万以上的内容来说简直就是灾难。
其实,内容源去重并不是仅在推荐系统中才首次出现,这早在搜索引擎时代就是一个刚需了,搜索引擎把整个互联网的网页都下载到自己的服务器上,这时,重复冗余的内容就需要被检测出来。
另一个需求是在内容阅读类推荐场景下,给用户推荐的内容不要重复,推荐过的内容就不再出现在推荐候选集中。
在你刷一个信息流产品时,不断看到重复的内容,想必不是使用感很好的一件事。因为以抓取作为主要内容来源的信息流产品,不同于社交网站上用户自发产生内容,除非遇到用户恶意发送,否则后者是不容易重复的。
以上两个场景,需要在你打造自己的推荐系统时予以考虑和应对。今天就介绍两种最常见的去重算法,两者有相通之处也有不同的之处,听我慢慢说来。
## Simhash
内容重复检测是搜索引擎公司最先遇到的所以Google在07年公开了他们内部的内容重复检测算法这个算法简单有效甚至造福了今天的信息流推荐产品。
对于很长的内容如果只是检测绝对重复也就是说完全一模一样的那种情况那么使用MD5这样的信息指纹方法非常高效无需再去分词、提取关键词和计算关键词向量之间的距离。
我们直接将原始的内容映射为一个短字符串,这个短字符串就是原始内容的指纹,虽然不是绝对保证和原始内容一一映射,但是不同内容能得到相同指纹的概率非常小。
只是这种信息指纹的方法有个非常明显的坏处就是,哪怕原始内容改一个字,得到的信息指纹就会截然不同。
这就没法愉快地玩耍了你一定希望的是只要主要内容不变就算一些不太重要的词句不同也仍然可以得到相近甚至相同的指纹。这才能更加灵活地进行内容重复检测。是否有这样的算法就是Simhash。
Simhash核心思想也是为每个内容生成一个整数表示的指纹然后用这个指纹去做重复或者相似的检测。下面这个示意图说明了Simhash如何把一个原始内容表示成一个整数指纹。
<img src="https://static001.geekbang.org/resource/image/de/4e/de7491eede4275a68a5ab8af17d6294e.png" alt="" />
好,现在详细说明一下这个过程。
1. 首先,对原始内容分词,并且计算每个词的权重;
1. 对每个词哈希成一个整数并且把这个整数对应的二进制序列中的0变成-11还是1得到一个1和-1组成的向量
1. 把每个词哈希后的向量乘以词的权重,得到一个新的加权向量;
1. 把每个词的加权向量相加,得到一个最终向量,这个向量中每个元素有正有负;
1. 把最终这个向量中元素为正的替换成1为负的替换成0这个向量变成一个二进制位序列也就是最终变成了一个整数。
最终这个整数就代表了原始的内容。这个Simhash奇妙在哪呢
看这个示意图中我故意加了一个不太重要的词“了”它的权重是1对应的加权向量元素不是1就是-1在上述的第四步中如果这个词对应的向量缺少了其实根本不影响最终得到那个整数因为它很难改变最终向量元素的正负。这就是为什么那些不太重要的词不影响内容之间的重复检测。
Simhash为每一个内容生成一个整数指纹其中的关键是把每个词哈希成一个整数这一步常常采用Jenkins算法。这里简单示意的整数只有8个二进制位实际上可能需要64个二进制位的整数甚至范围更大。
得到每个内容的Simhash指纹后可以两两计算汉明距离比较二进制位不同个数其实就是计算两个指纹的异或异或结果中如果包含3个以下的1则认为两条内容重复。
为了高效,也可以直接认为指纹相同才重复,视情况而定。
## Bloomfilter
除了内容重复检测还有一个需求是防止已经推荐的内容被重复推荐。这个刚需和上述内容重复相比最大的不同就是过滤对象不同上述Simhash过滤对象是内容本身而这里则一般是内容的ID。
内容的ID一般是用一个UUID表示是一个不太长的字符串或者整数。
对于这类形如模式串的去重,显然可以用单独专门的数据库来保存,为了高效,甚至可以为它建上索引。
但对于用户量巨大的情况下这个做法对存储的消耗则不可小看。实际上解决这类看一个字符串在不在一个集合中的问题有一个有点老但很好用的做法就是Bloomfilter有时候也被称为布隆过滤器。
布隆过滤器的原理也要用到哈希函数。它包含两部分一个很长的二进制位向量和一系列哈希函数。Bloomfilter是一个很巧妙的设计它先把原始要查询的集合映射到一个长度为m的二进制位向量上去它映射的方法是
1. 设计n个互相独立的哈希函数准备一个长度为m的二进制向量最开始全是0
1. 每个哈希函数把集合内的元素映射为一个不超过m的正整数km就是二进制向量的长度
1. 把这个二进制向量中的第k个位置设置为1也就是一个元素会在二进制向量中对应n个位置为1。
我放了一个示意图。
<img src="https://static001.geekbang.org/resource/image/ef/4f/ef000d86f72ca2341f95d8bc74ab854f.png" alt="" />
这个示意图中原始的模式串经过三个互相独立的哈希函数映射到8位二进制向量中的三个位置了。
原始的模式串集合经过这样的处理后就得到一个很大的二进制向量。在应用阶段时假如来了一个模式串s需要查询是否在这个集合中也需要经过同样的上述步骤。
每个哈希函数对这个模式串s哈希后都得到一个整数看看这个整数在二进制向量中所指示的位置是不是1如果每个哈希函数所指示的位置都是1就说明模式串s已经在集合中了。
需要说明的是Bloomfilter也并不是百分之百保证的有很小的概率把原本不存在集合中的模式串判断为存在。这样就会造成那些明明还没有推荐给用户的内容ID就再也不会推荐给用户了当然这个小概率是可以承受的。
## 总结
好了,今天介绍了两种去重算法。在推荐系统中,虽然我们十分关心推荐匹配的效果,但是别忘了,对原始内容的挖掘和清洗往往更加重要。这其中就包括对重复内容的检测。
两种去重策略都是牺牲一点误伤的概率换得大幅度的效率提升具体的做法都是要借助哈希函数。只是哈希函数的结果在两个算法中有不同的处理手段Simhash是加权Bloomfilter则是用来做寻址。
最后留给你一个思考题由于今天的内容比较简单留给你思考题也简单请你想一想如果要从Bloomfilter中去掉一个元素该怎么做欢迎给我留言我们一起讨论。
感谢你的收听,我们下次再见。
<img src="https://static001.geekbang.org/resource/image/76/02/76de8928fe8206b0467b8c773d6ced02.jpg" alt="" />