黄波:AI技术在知乎的应用实践
导语:本文根据知乎知乎AI团队技术负责人黄波于第十届中国系统架构师大会(SACC 2018)的现场演讲《知乎如何利用AI理解内容和用户》内容整理而成。
讲师介绍
黄波,知乎AI团队技术负责人。负责知乎NLP与用户画像相关技术与业务。硕士毕业于北京大学智能科学系,曾在JMLR、ICLR等国际顶级期刊及会议发表多篇学术论文。在加入知乎前,曾任百度自然语言处理部门高级算法工程师,从事智能交互、语义表示、语义标签、内容质量的研发工作,参与了度秘、百度feed流等产品的关键技术突破。
正文:
大家下午好,非常感谢SACC大会的邀请,我今天演讲的主题是AI技术在知乎的应用,内容重点介绍偏底层的相关技术,包括知识图谱、内容分析与用户分析。最后会简单介绍这三块技术在相关业务线的应用。
一、知识图谱的构建与应用
我们先来看一下知识图谱,知识图谱的构建包括三个核心要素:本体、本体属性以及本体间的关系。其构建过程大概分三步:第一步基于互联网上结构化和半结构化数据抽取本体信息,再通过知识融合构建统一的本体库,这里本体通常包括实体、概念、事件等;第二步我们会挖掘本体的属性以及本体间的关系,比如本体“勒布朗 詹姆斯”的类型属性是”人物”、领域属性是”体育“,与本体”德怀恩 韦德“有较强的相似性,与本体”NBA“属于上下位关系等;第三步是知识图谱的表征,我们可以利用离散的 RDF 规则语言和基于神经网络的 embedding 方式来表示知识图谱。
接下来看下知乎怎么做知识图谱的构建,我们主要围绕着知识图谱的要素来做,首先是一个本体,本体我们以知乎的话题为核心,同时会把互联网上百科词条相关的一些实体与话题进行融合,做一个映射。还有一个要素是内容,就是这个对象本身的一些名字、描述、解释。另外一个要素包括本体的类型,它是人物还是地点。然后所属的领域也是一个要素,是互联网、还是体育。最后更重要的是各种要素之间,我们可以去构建不同关系。
比如话题,我们可以构建两种关系。第一种是话题的上下位的关系,上图中可见,韦德的上位话题是NBA球员。另外话题之间也可以有一个相似度的一个关系,比如说韦德这个话题和詹姆斯这话题他们就相似的非常高。上下位是有方向的,相似度是没有方向的一个关系。另外我们话题和领域也都有一个单向的关系,詹姆斯属于二级领域,NBA它属于一级领域。话题和类型也有关系,如詹姆斯这一个话题是人物的类型。
我们围绕这些要素去做一个知识图谱的构建,构建完之后,需要对知识图谱进行表示。常用的知识图谱表示有两种,一种是离散的方法,我们可以通过各种RDF或者这种规则的方式去表示知识图谱。它的优点是表示方法很直观,可以很好地解释知识图谱的内部逻辑。另外通过各种复杂的规则,它也可以很好的支持很多很复杂的知识结构。这种离散的表示法有它自己的缺点,比如说非常稀疏,还有扩展性也比较差。
另外一个最近比较流行的是通过各种Embedding和神经网络的方法,对整个知识图谱做一个连续向量的表示,把知识图谱的关系或者说本体的一些概念映射到一个低维空间里面。它的优点就很直观了,就是我们得到表示是一个低维稠密的,对于各种深度学习模型非常友好。缺点是它得到的表示,可解释性没有离散表示强,表示能力也稍微弱一点,对于很复杂的知识结构不能够很好去支持。
我们知乎怎么去做这个知识表示的工作,我们主要围绕话题为核心来做语义表示。下图是一个例子,这是问题的标题,“科比和詹姆斯的区别在哪里?”会打上对应的五个话题,有NBA有科比,有詹姆斯……等等。这里我们模型的输入层包括一个话题的表示,以及一个窗口的构造词,把他们的Embedding加起来去预测窗口中心的词。另外在我们的目标层还有两个其他任务,一个是我们要通过这个话题去预测另外一个话题,这个也是我们模型的一个预测目标。另外是之前知识图谱构建的一个类型,也会放到我们这个目标里面来作为模型的预测。
最终这个模型训练完之后,我们的话题“詹姆斯”和所有的词以及其他话题都会映射到同一个语义空间里面。有什么用呢?就是大家都在同一个语义空间里了,最直观的用法就是我可以得到一个话题的相关性图谱,任何两个话题之间,都可以给你算一个相关性得分。比如说这里的话题Facebook,可以把跟Facebook这个话题很相关的其他话题拿出来,比如说扎克伯格、Facebook广告类似的这些话题。这里就可以用在用户推荐里面,用户感兴趣的一个图谱,或者说用户信息的一个扩展。
二、内容分析实践
讲完知识图谱,接下来讲内容分析。什么是内容分析呢?简单来说就是给内容打上各种各样的标签。比如说语义层面的一二级领域、话题、实体、关键词。举个例子,是关于物理的——“有哪些看似荒谬的事,却有着合理的物理解释?”话题。它的一级领域是自然科学,二级领域是物理学,同时会有其他细粒度话题,科普、物理科普、冷知识等等。除了语义标签这一个维度的标签以外,我们还会打上质量的标签。我们模型会判断某个回答是不是一个很专业的回答,给出一个专业性得分;另外还会去算这个回答跟问题的相关性,给出一个提问相关性的得分。然后,还会有一个时效性得分,可以用在推荐系统里面,做一些长期的推荐,如果是低时效的内容,可以一直在推荐系统里流通,如果是高时效的内容,过一段时间之后,我们不再让它流通了。
关于语义标签,我们由粗到细构建了一个语义标签体系。从领域、话题到实体/关键词,它们的粒度是从粗到细的。为什么要做这种多粒度的语义标签?其实在不同的业务场景,大家对于这种语义标签是有不同要求的,粒度越粗的,比如说一二级领域,我们希望它是一个粒度相对较粗,并且是一个尽量完备正交的分类体系,这样对于任何一个问题和文章,我们都能保证把它对应到某个一二级领域。话题这块我们希望的是模型能够高准确度地打出结果,并且同一个问题和文章可以打上多个话题。针对实体/关键词,也是类似的,我们只是要求模型的准确度比较高,优先保证热门的实体/关键词被召回就可以了。
接下来会具体展开讲几个模型,我们怎么去做内容分析的。
内容分析——领域分类
首先是领域分类,我们当时做的时候面临一个问题,我们梳理出一个分类体系了,但分类体系是没有训练数据的,短期内也不想通过人为去标很多训练数据,那要怎么构建训练数据?我们就是把原始语料和之前构建的知识图谱结合在一起,去构建一个带噪声的新的数据。如下面这个例子,“零基础如何学绘画?”这个问题关于绘画和自学,绘画在知识图谱里面所属的一级领域是艺术;自学所属的一级领域是教育。这样的话,这条训练数据就有两个level,一个是艺术,一个是教育。可以看到教育可能在这条数据上是错的,就是我们得到训练数据是带有噪声的。为了解除这种噪声,我们在设计的时候加入两个降噪层来对噪声进行降噪。同时预测阶段我们也用了一个ensemble的模型来进行模型的预测。
上图是我们文本分类的一个模型。文本分类有一个传统方法,就是我们去进行一些简单的预处理,然后加一些人工特征,再把这个特征出到上层的一个浅层模型。最近几年比较流行的是通过深度学习方法来做一个分类,比如说通过FastText,TextCNN和RNN/LSTM相关的一些模型。这个模型用在我们这个数据产品上有一个问题,它没办法去除我们训练数据里面的噪声,所以说我们单独设置了一个降噪的模型来对这个数据进行降噪。针对降噪层,我们加入两个东西,第一个是,这个模型最左边是问题的标题(question title),通过问题标题有一个embedding,embedding通过一个LSTM再过一个Attention得到这一个问题标记的一个表示。右边是对于问题的自带的话题(question topic),做一个话题的表示,再把话题表示加起来,然后通过一个Identity+L1的一个Noise的一个降噪层去得到这一个topic的表示。
这两个表示我们把它结合在一起去做一个损失函数计算。这个损失函数计算,我们包括两两层,第一层是一个交叉熵,通过交叉熵我们发现就有一个问题,因为之前构建的训练数据,同一个数据可能会出现多个标签,这种标签有些是对的、有些错的,单纯通过交叉熵模型去很难去降低这种噪声的影响。我们这里在损失函数里引入了一个降噪逻辑,具体来说是加入了sigmoid的损失和一个最小熵的正则。这里我可以详细解释一下,比如刚才“绘画”例子的数据,它打了两个标签,如果用交叉熵来算损失,这个是不太好计算的,噪声也没办法去除掉。我们通过sigmoid,不限制预测的结果,加起来等于1,大家都可以是1。比如说我的模型分类,你的数据是艺术教育,我模型都可以去分,这两个概率都接近1。加上这个之后又有一个问题,就是说模型倾向于把所有的数据都去打上1,那这样我们就加了一个最小熵的正则,这样我保证在最终输出才能得到结果。它是一个熵比较小的,也就是说某一个值比较大,其他比较小,这样就限制了模型把所有数据都打成1的情况。
在另外是一个在预测阶段,我们采用了ensemble的方式,这里是利用了知乎数据特有的特点。因为知乎的数据每一条数据带有话题,这个话题是人打的,有好有坏。人打的好处就是可以引入额外的一些知识,坏处是也会引入一些噪声,所以说我们就是把话题和标题两个模型去ensemble起来,进行预测。
内容分析——话题匹配
我们再看一下话题匹配。话题匹配是一个文本的做标签的任务,它的定义是给定一段文本,从给定话题集合中匹配出相应的话题。它的应用场景就非常直观,我们可以对问题和文章进行话题标注,比如这里有个例子,“如何评价美剧西部世界”,我们可以打“西部世界”、“西部世界第二季”、“美剧”、“人工智能”等。如果大家平时用知乎提问,你去梳理一个问题之后会推荐相应的候选集,那个也是整个话题的一个模型。
另外一个层面,我们针对用户输入搜索的一个Query,也可以去匹配出相应题。一方面可以用于搜索的一些特征,另外一方面也可以去沉淀出用户的兴趣画像,另外也可以对Live和私家课等相关的其它资源做一个相关的话题标注。
这一个话题匹配我们在做的时候,分析这个问题非常难,到底难在哪?我们大概把难点拆成三块:第一,话题本身语义粒度的差异特别大。大到领域级别的“娱乐”这种话题,小到“吴亦凡”这种实体级别话题,这样模型其实很难去学习这种差异性特别大的一个目标;第二,话题集合数也非常大,大概是10万量级,长尾话题(出现次数小于10)特别多,占比大概80%以上;第三,话题之间语义相似度特别高,比如说“Python”和“Java”,还有“插画”和“绘画”这种,通过深度学习模型很难去捕捉这种细微的差异。我们其实中间也尝试过很多端到端的深度学习方法来做这个事情,比如说通过FastText、Matching CNN和LSTM+Attention的方法来做。但这些方法都有一个问题,就是模型倾向于预测偏高频的一些话题,针对于低频的、针对长尾话题,它们效果都比较差。
我们在做的时候把这一个问题拆解成了一个系统性的工作,类似于推荐系统一样,我们把它做成一个召回+排序的一个过程。召回的逻辑是你先给一个资源过来,我们从标签库里面去召回出候选的数十个话题,再通过这数十个话题进行一个精细的排序模型,来得到最终的结果。最终我们这个效果是非常不错的,准确是93%,召回是83%。
具体来看我们怎么做的?在召回层分三个策略,第一个是比较简单,就是我直接去做一个AC多模匹配,把匹配出的话题作为候选集合;另外一个是比较有意思的,我们在经典的点互信息(PMI)的算法上做了一个优化,提出了一个两趟对齐算法,这个就能解决类似“Python”和“Java”的这种问题;还有一个是我们会利用之前构建的知识图谱,把话题的上位话题也作为候选集合召回回来。
在排序的时候,因为刚才提到了,单一的深度学习模型对于我们特定的话题匹配学这个问题是不太适用的,所以说我们在深度学习的模型基础上,也加入其他的一些规则,去做一个多策略融合的排序工作。这个深度学习排序模型比较经典,如上图,左侧是文本的词,过一个embedding,再过LSTM,再过一个Attention,得到这一个文本,这段我们表示。右侧是分别是这个话题的样本,这边是正样本的一个表示,上层再过一个全连接,跟着一个文本的表示算一个相似度。副样本也跟着一个,我们的表示算一个相似度,这两个像素之间再算一个损失。我们加的这三个规则分别是什么意思?第一个规则是说我这个话题需要跟候选召回回来的话题集合算一个相似度得分。其实有一个趋同效应,如果你这个话题是对的,你应该跟周围大部分话题都比较像。还有一个规则是我们通过话题图谱的权重有一个得分,另外一个规则就比较直观了,完全匹配的,这种我们会给他加权。
内容分析——专业性
剩下一个是内容专业性的分析。专业性这个非常重要,因为我们知乎其实鼓励大家去生产专业性的内容,同时去鼓励专业内容在知乎得到更多的流通,但是有个难点,机器怎么知道你那个内容是不是专业性,或者推荐算法怎么能知道这个内容是不专业的,那我们就需要去做一个前置的工作,去通过模型来判断这个文章是否专业。这个问题比较难,难在哪儿,第一个是专业性这个定义非常模糊,就是我给你一个数据,你可以告诉我它是不是专业性的,但是制定一个标准,什么东西是专业性的?这就非常难,因为专业性随着不同的领域差异特别大。另外一个是训练数据的获取成本也很大,因为标准不明,也很难去标一个高质量的训练数据。
我们在做的时候拆成两个阶段,第一个阶段是通过用户行为,这里主要是通过用户收藏的行为,因为我们发现专业性的内容,用户倾向于去收藏,然后通过用户收藏夹去做一个配置算法,去算出每一个收藏夹的一个权重和对应收藏夹里面的文章的一个权重,当做专业性的得分。
这个方法它的优点是准确度非常高,缺点是覆盖相对较低。因为是基于用户行为的,会有一定的滞后性,我们对于新的内容没法去判断它是不是专业。在第二个阶段,我们就用了一个纯的文本语义的模型来做。这里有没有传统的文本分类的一个方法,为什么不用深度学习来做专业性的识别?因为刚才提到训练数据成本很大,我们现在可能就只有几万条训练数据,专业性的回答和文章又特别强,如果你直接用深度学习不断地堆上去,直接就过拟合了。这里我们做了很多人工相关的特征,主要包括两个层面。第一个是文本风格的特征,包括词性,还有标点相关的。另外一个这个是非常重要的,语义特征,我们通过大量的数据去做一个词的聚类,把类簇当作专业性模型的一个基本特征,这个特征在我们后面随机森林模型里面特别重要。所以最终我们专业性的效果现在只是初版,针对专业性内容识别准确是84%,召回是60%。
三、用户分析实践
讲完内容层面,用户层面也类似,其实我们要做用户分析,也是想去给用户打上各种各样的标签,以及用户之间的一些关系,包括用户的姓名度。具体展开来讲,三个层面,包括用户的基本画像的一个预测,像性别年龄以及用户本身的一些登陆地、设备信息相关等等这种基本的属性。还有一个跟推荐系统相关的,就是用户兴趣的画像,这里我们分了三大块,第一大块是用户的一个被动兴趣,这可以解释下,我们把它叫做用户在推荐流里面的浏览和点击的行为,这种行为我们把它叫做被动兴趣。主动兴趣这里,因为知乎有它的特殊性,就是很多用户会去搜索,也会关注也会收藏,我会把单独这些行为在做一套兴趣出来,就是抽象成一个主动的兴趣。
另外根据之前的一些标签,比如专业的标签,我们可以去算出用户对于专业性内容的一个偏好以及对于类型的偏好,比如这里一个例子,“程序员张三”性别是男,兴趣标签有AI、机器学习,类型偏好是偏好于比较喜欢看专栏文章,对于回答和视频,他的偏好相对较弱,专业度内容偏好是0.8非常高,说明他在知乎里面可能只看专业性的内容。另外一个用户“运营小丽”她可能就是看一些综艺和电视剧相关的一些资讯,它对专业性内容偏好就叫弱。还有一个层面是用户社交的一个表示和挖掘,因为知乎它也有一定的有很强的社交属性。我们通过用户的社交行为去学习用户的一个表示,进而来做一些用户聚类、用户亲密度相关的一些工作。
用户分析这个问题,其实它离不开一个东西,是大数据的处理,因为用户的日志量其实太大,所以说我们需要做一个比较完善的服务架构,才能支撑我们上层很多用户画像的计算。这里我们大概设计了三大块,第一个是实时计算,包括用户实时行为的存储,用户实时兴趣的计算。另外是离线计算这一块,就是一些模型的预测,有可能是“天”级别的,有可能是“月”级别的,包括用户的基本发行的预测和用户表示,还有用户聚类与人群划分相关的工作。
最后是在线服务这一块,我可以解释一下Hbase多集群同步什么意思?因为离线计算是一个批量的过程,是我批量预测所有用户的性别或者说人群属性的结果,我需要“灌到”线上服务里面去让业务方去用,那这样我们不能直接灌到在线集群,你直接打到在线集群就崩了,所以说我们需要先灌到离线集群,再做一个流式的同步,去把离线集群的结果同步到在线平台,这样就能保证线上的服务是稳定的。另外我们也会去做一些缓存相关的工作,来支持一些线上高并发的请求。
下面讲的是我们通过streaming的方式来进行用户实时兴趣计算的流程。大概逻辑是,我们会把用户的点击日志、展现日志以及搜索日志拿过来做实时分析,抽象出用户和对应的内容的Token,以及它对应的行为,抽成一个三元组。这个三元组抽取完之后,我们再去对内容进行进一步的分析,提取这个内容对应的话题和关键词相关的一些标签。针对于问题、文章、回答,我们直接通过之前缓存算好的内容画像里面去获取它的标签就可以了。针对用户搜索的query,因为这个东西没有没办法提前算好,所以说我们这里需要去调用语义理解的相关一些模块,比如说关键词提取模块,以及话题匹配的这一个模块,得到query对应的话题和关键词。
提取了内容的标签之后,我们会得到一个用户以及标签,还有行为三元组的一个聚合结果,这个结果就作为最终用户兴趣计算的输入。用户信息计算在算什么?主要是包括一个新兴趣的叠加,还有老兴趣的衰减,这里会去做一些参数平滑以及打压热门,一些热门话题或者热门关键词的一些工作。
然后是用户表示和聚类,主要思想还是想通过一个神经网络或者各种embedding方法去把用户表示在一个低维空间里面,表示完之后我们就可以去做很多的应用。知乎在做这个事情,有必然的优势,我们训练数据非常多,第一个是用户社交关系,不管是单向还是双向的。还有用户有很多关注问题/专栏的数据,另外用户也会收藏相关的回答/文章,我们把这三种数据揉到一起就组成了一个图,针对这个图,我们利用了一个graph embedding方法去获取每个用户的表示。
四、典型业务应用场景
关于用户表示,它的应用场景非常多,第一个场景就是受众的扩展,第二个是我们可以得到一个简单的用户聚类,这个聚类如果进一步分析,就可以给每一个类打上一个人群的标签,用于做人群或者圈子的划分。
刚才提到了知识图谱,还有内容分析和用户分析,其实都是最终有应用目标的,它最大的一个应用目标就是在首页信息流的推荐。整个内容分析和用户分析会作为整个推荐系统的一个底层的很重要的特征,用于召回和排序。当然召回除了基于标签这种召回方式,也会有基于协同算法和最近比较流行的基于神经网络的一些召回方式来做。在排序的时候,我们不只可以去优化时长,CPR作为目标,也可以把我们标签识别出专业性的占比去做一个目标来进行优化。
刚才也提到,推荐系统不用这个标签也可以,用协同和神经网络也可以做,那么我们用标签来做推荐系统召回有什么优点和缺点?优点我这里列了四点,第一个,可解释性强,粒度越细越准确;第二、会越用越准,能积累长期兴趣;第三、可以对各种标签做比例的精准控制,比如说我就强制要求你召回,在这里面专业性的内容占比必须达到多少;第四,没有内容冷启的问题,任何一个内容我通过标签都可以被召回被推荐。
但是基于标签有它自己的缺点,就是泛化性相对较差一些,也不是所有内容都能打成这种形式的标签。
除了首页推荐的场景以外,我们这种标签也可以用于其他的一些数据分析和决策用,比如说我们可以去分析专业性内容在生产和消费的一个分布情况,另外也可以去按领域维度来对内容生产和消费进行分析,还有一个是我们可以按人群来看,比如说我可以看大学生对于各种内容的生产/消费情况。
这里是一个受众扩展的例子,就是我们把用户的表示训完之后,这是一个很直观的应用场景,就是我们有一些私教课,它有一批已经点击或者已经购买人群,现在我们需要在针对这个私家课会发一些优惠券,这个优惠券肯定不能发给已经支付的用户,我们需要发给跟这些已经点击或者已经购买的人比较相似的人,我们通过刚才的用户,对人群做一个受众扩展,再把优惠券发给相应的一些人群。这一个是跟知识图谱比较相关的,就是显示的一个用法,隐式的用法就是用在推荐系统里面的信息库,这里也是一个私家课的案例,比如说我有私家课是想推给演讲和口才相关的一个用户群,这里我们就会通过这两个话题去匹配对这个话题比较感兴趣的用户群出来,但是也不够,我们发现在知识图谱里面辩论跟演讲特别相关或者特别相似,这样我们也可以把这一个私家课推送给对辩论感兴趣的用户群,这样我们就把这个话题投放的人群做了一个扩展。
以上是我今天讲的内容,欢迎大家进一步交流,谢谢!
如需转载,请注明出处,否则将追究法律责任。