推荐系统是一个很宽泛的概念,在各种广告算法,歌曲推荐上都有比较广泛的应用。当前公开的出版物中,至少刊登了上亿乃至十亿量级的各种论文。若有人要维护一堆论文,自然顺便也可以用推荐系统的思想处理下这些论文。据我所知,researchgate 和 semantic scholar 在这方面做得都不错,顺便的,我们 aminer 也在这方面做了一些小小的工作。偶然在蛤乎上被邀请答这个题,诚惶诚恐,准备了如下一些文字,作为回应,希望能对路过的谁有所帮助。
推荐系统以论文为场景下的应用,本质上还是推荐系统,因此推荐系统本身的内容都还能用,但是具体到论文本身,我们可以得到更多具体的特征。
先写我的看法之简略版:
- 论文是结构相对规范许多的实体, 哪怕不同领域的论文, 我们都可以找到 title, abstract, keyword, journal/conference, references , 其表意也是接近的. 这意味着我们可以更加轻松的得到很多维度的特征, 并且可以比较容易的通过调整权重来让结果更加符合期望
- 因为论文本身的结构化, 那么在它基础上的很多外部资料可以用. 比如 CCF, Google 等很多机构都有手工标注的领域相关特征. 我们可以很容易说, 我们要对我们手头的一亿论文跑一个 topic model , 聚类成 100 类, 那 100 类中已经有很多已有的数据集, 因为 CCF/Google 已经手工整理好.
- 论文是人写的, 而且大多有 journal/conference. 我们可以很容易把所有论文聚集起来, 然后形式化成 论文-人-论文, 或者 论文-journal/conferen-论文 等这样的图模型, 然后在这个图模型上再跑计算.
个人只是程序员, 虽然很高兴有人给我发了个 Data Scientist 的 HireLetter, 不过平心而论, 我最大的能力也就是看着别人的论文, 自己写个实现来, 或者在别人的模型下面改吧改吧, 打打比赛之类. 让我去证明还是力不从心的. 因此下文都是以个人的程序实现角度谈谈相比通常的推荐系统有什么不太一样的的感想什么的, 没有兴趣的可以散了.
--------------------------- 没有干货的分隔线 --------------------------
我们都知道,
- 论文都是人来写的
- 大多数情况下,一个人的论文所在领域会比较稳定
- 一个人的合作者论文也会比较稳定
- 一个 journal/conference 的主题往往会比较稳定,即便综合的 nature 或者 science,他们也有很多子刊,子刊的主题也会比较稳定
- 论文之间有引用,a若引用b,那么 a 和 b 之间的主题大多是相似乃至一致的。
- 论文本身有 title,abstract 和 keyword 它们之间出现某个文本代表的权重显然是不一样的。
那么,以此为前提,新来一个用户,我们可以通过他的历史,他的query 来做怎样的推荐呢?
先准备特征和候选内容
首先,我们需要收集论文。我们非常穷,我们不是数据生产者,我们是数据的搬运工。 论文数据来源有几种,其一是合作所得,就是别人把他们的数据打个包给我们一份,或者给个 api key,我们可以比匿名用户多搜几下,不过有人要为此买单,而且服务质量不评价。其二是有些网站自带 dump。在此谢谢良心的dblp,真给他们跪了。其三是直接爬一些网站的论文profile页面,这儿有个坑是我们不能用清华的机器去爬,清华每年给他们缴纳的大量的保护费,因此我们ip看到的内容会比外面看到的多一丢丢,但是若我们动用爬虫,那么后果是对方警告学校,学校通告批评我们亲爱的老板,亲爱的老板会对我狞笑。所以虽然可以通过代理,但是安全起见还是直接租外面的机器收集数据。
其次,我们要整合数据,比如 dblp 和 acm 的论文数据有大量的重合,那么我们就要整合异构数据,并去重。我的做法是每个数据源的原始记录先保存一份,然后再另外开表存放整合后的数据。首先通过 title 寻找相似的,然后用 edit distance 排除论文标题差异过大的,然后再比较作者,总之就是一堆 dirty work。顺便一说,传统的 ed 真的比较 ed,title 长点就要死要活的,所以我用的是方神的快速失败的改进方法,我特喜欢那方法,目前所有我会的语言我都实现过这个。然后就是普通的各种 rule based 比较什么的。
其三是 NA,就是两篇论文都有名叫 Jiawei Han的作者,这两个作者是不是同一个人呢? 就目前已知的信息,只能说大概是或者大概不是。这是很痛苦的操作,我们的事结果是过拆分与过合并并存,简直要跪。比如我生活中至少认识五个王伟或者同音的,在英文论文里都叫 Wei Wang,羞涩的表示到目前为止这个人我们还是没能做好这个人。有很长一段时间里,我们实验室某个又高又帅有妹子还会打篮球的博士生和亲爱的老板的对话是这样的: Q 我觉得这样效果还是不太好,你看谁谁谁,明显不对嘛 A 你觉得我怎么死比较痛快 (本对话为虚构,他们的讨论非常友好和谐,在下心理阴暗构陷他们的)
其四是其它各种相关特征准备。比如论文的 title 和 abstract,我们通过几种方法抽取了各种关键词,又通过维基和李涓子老师的语意工具给一些 topic 做了上下位词的结构化处理 (lda 什么的,抱歉不了解详情),另外给journal,conference等 assign 一些领域。(这个目前还非常粗糙,conference 本身的 entity binding 本身还比较 ugly )
以以上各种数据为特征,我们可以做一些微小的推荐。
其一是文本搜索,就是对历史(或者当前)关键词找论文,然后排个序,后面的随便排一下,对靠前的再用复杂度高点的算法 rerank 下。
其二是协同过滤,和你所想的一样,加点特征基本就上面说的
其三是 Social Network Analysis 方面。 其实也没啥大不了的,我们寻找并形式化已经 NA 完毕的作者之间在论文上的社交关系。比较简单的是以作者为Node,以 Co 一篇论文为 Edge。复杂点是以作者,论文作为不同的点,“写”为边。再复杂是加上 journal/conference。越复杂越能发论文,越简单越好实现然后丢线上跑全图看效果玩。不过2015发的kdd里有一篇是用最简单的关系,主题思想是利用类似 random walk的思想给前面说的最简单的图跑一下,然后预测一个点接近的其它点,可能是一度关系,也可能二度到三度关系。因为是随机乱跑,虽然理论上可以跑到步长那么远,不过最后 top n里面不太可能就是。 主要成果是这么 sampling 下,调一下参数,效果不必统计所有点和边要差多少,但速度可以快一个数量级,能在相关工作的模型已经跑不动的时候还能给个结果(论文: http://arxiv.org/abs/1504.02577 Demo: https://github.com/yuikns/panther)。当然,其实可以更加好一些的,不过我码力不足你懂的。
这样推荐论文就被悄悄换成了推荐人然后找论文再 rank 这种模式。
觅食加锻炼期间用手机完成本回答,因为不方便使用搜索,所以显然多有错误且缺少详细来源,欢迎各种打脸,等我回去写完代码后再努力补充一下,希望能对谁有所帮助。
补充: 刚刚体重计告诉我又胖了一公斤, 表示很伤心. 我在最上面做了个简单的总结, 这件事算告一段落, 详细补充什么等我有心情再说, 各位该骂骂,该反对反对, 反正我不会删评论, 以后有心情再讨论.