今天下午参加了一个视频类的推荐系统技术分享,此处仅整理我觉的有用的地方,和我的一些想法。
1.怎样做过滤?
很多时候我们需要用到过滤。例如对于一个用户的检索/推荐来说,召回结果里首先不能含有他以前点击(观看)过的,也不能出现垃圾信息(广告、色情),同时对用户曾经拉黑、不喜欢的账号或内容也要做过滤。
问题一:过滤信息的可追踪性?
考虑这样一个场景:有一个很相关的视频没有被推荐给用户,经过查询发现被过滤了,现在我们想知道是在以上(看过、垃圾、用户拉黑)哪一步被过滤的?
(我们还没做)
答案是:他们的手段是,针对不同的过滤信息做编码。例如现在有3个过滤手段:看过、垃圾、用户拉黑。我们分别为其编码:
1 看过
2 垃圾
4 用户拉黑
现在有5个视频,其初始默认均为
$$[0, 0, 0, 0, 0]$$
经过步骤1:
$$[1, 0, 0, 1, 0]$$
说明视频1和4被看过。
接下来经过步骤2
$$[2, 2, 0, 0, 0]$$
同理经过步骤3
$$[4, 4, 0, 0, 0]$$
最后我们把这些进行累加,得到:
$$[7, 6, 0, 1, 0]$$
过滤非0的即可。实际追查起来,我们很容易根据"7"知道视频1过滤的原因是同时被看过、垃圾、用户拉黑,其他同理。
问题二:过滤信息的存储?
考虑要将每个用户近3个月看过的所有视频均存起来,非常耗存储量。我们可以考虑使用布隆过滤器。
(考虑将这个后续用在“过滤hr已查看人才”的存储)
一个bloom filter是一个有m bits的bit array,每一个bit位都初始化为0。然后使用k个hash函数,每个都以uniform random distribution将元素hash到m个不同位置中的一个(此处存在一个问题:当k很大时,怎么保证这k个hash函数的映射位置不重叠?)。
此处有提到:
当k很大时,设计k个独立的hash function是不现实并且困难的。对于一个输出范围很大的hash function(例如MD5产生的128 bits数),如果不同bit位的相关性很小,则可把此输出分割为k份。或者可将k个不同的初始值(例如0,1,2, … ,k-1)结合元素,feed给一个hash function从而产生k个不同的数。
add元素:使用这k个hash函数计算,映射在k个位置上,将m bit的这k位置1即可。
查询:用k个hash function将它hash得到k个bit位。若这k bits全为1,则存在。若任意元素不为1,则不存在。
由此我们知道,布隆过滤器永远不可能将“看过的判为没看过(毕竟已经存储过了啊)”,但可能将没看过的判为看过(这需要k个hash函数同时巧合地映射在对应位置)
2.视频中弹幕/评论的信息提取
首先用tf-idf过滤得到关键词,然后使用余弦相似度过滤距离较远的词。
这样两步,前一步的作用是提取核心词,后一步是过滤核心词中的“不正常”的词,例如在詹姆斯视频中提到“冰与火之歌”。
3.用户实时兴趣转移?
用户本来对动漫感兴趣,离线计算的结果也是,但此时他就是想看游戏视频怎么办?推荐应该给出实时的响应。
(我的引申思考)
目前我们的人才推荐,针对hr每天只推荐1次,未来考虑可以针对hr的每次搜索做推荐的动态更新:例如hr此时搜索了3次“php”相关职位,点击了几个“PHP后台”的简历,我们可以立即生成对“PHP后台”相关的推荐。假如hr平均每天搜10次,则我们可以使目前的人才推荐曝光量增加10倍。
当hr不搜索时(或30分钟后),人才推荐又恢复正常。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。