随着移动互联网的发展,内容平台迎来了黄金时代。但也不可避免的,出现了很多问题和挑战。这些问题主要体现在两个方面:
第一,信息过载问题。技术的进步让我们接触到的信息越来越多,也越来越实时。但这也让超负荷接收信息成为一种常态。根据 IDC 预测,全球数据总量预计 2020 年达到 44 ZB。现实生活中,我们每个人每天处理的数据量也增长了很多。信息大爆炸,让我们花费更多的精力接收和处理信息,沉淀知识。
第二,是用户的内容消费升级。这些年,用户的内容品味越来越好。但是,优质、有用的信息一直是稀缺品,低质、无用的信息却很容易泛滥。如何大幅度提升优质内容的绝对数量,扩宽优质内容的覆盖领域,并同时减少低质内容的产生,是内容平台的共同难题。
这两个问题也是知乎这几年重点思考和解决的问题。
知乎合伙人、CTO 李大海在 ArchSummit 架构师峰会上分享了他的一些想法,以下是他演讲的全部内容。
知乎从问答起步,在解决这两个问题的过程中,成长为一个大规模的综合性知识内容平台,涵盖了 27 万个话题,有超过 3000 万个问题被提出,共收获超过 1.3 亿个回答,同时,知乎内还沉淀了数量众多的优质文章、电子书以及其它付费内容,月浏览量达到 290 亿。所以我认为我们至少部分解决了这两个问题。下面我来简单介绍一下我们如何做的。
知乎如何连接「人与内容」
知乎在解决内容平台遇到的两个问题中,做了很多的工作,本质上是在解决「人与内容」的连接问题,让人们更有效率的获得有价值的内容,让社区能够产生更多有价值的内容,并能更快更好地为我们所用。
知乎是怎么解决信息过载问题的呢?我们的答案是首页个性化推荐和搜索。这两个产品,一个主动一个被动,能够很好地帮助用户减少无关信息的打扰。
首页个性化推荐(即信息流)
1.Edge Rank 算法
知乎从 2013 年就已经上线了信息流产品。当时的主逻辑是一套叫做 Edge Rank 的算法。我们把用户关注的所有人和话题所产生的所有新内容,当成候选池,候选池里的每个内容的权重与三个因素相关,分别是表示用户对关注对象的关注度的权重,内容的类型,以及时效性权重。这套算法在知乎早期,还是非常管用的,它给用户的预期也很清晰,只有自己关注的内容才能进行信息流之中。
2.GBDT 算法
随着知乎体量的增长,Edge Rank 已经不能满足分发效率的需要。于是我们从 2016 年开始升级首页产品。我们首先使用 GBDT 来进行 CTR 预估,并以 CTR 预估值作为排序的主要考虑因素。GBDT 算法的引入,对知乎首页的分发效率提升是非常可观的。GBDT 的算法首次上线,用户停留时长就有了 12% 的提升,我们后续不断改进算法,一年时间里面,累积获得了 70% 的用户在线时长的增长。GBDT 的优势是可解释,并且需要的训练数据量级不算太大,GBDT 的研发、调试和训练成本都较低,从 0 开始构建的时间成本也比较可控,特别适合研发及计算资源比较受限、但又亟需使用机器学习改进业务的团队尝试。
3.深度学习技术
从 2017 年开始,我们又将深度学习技术引入了首页推荐产品之中。为什么要使用深度学习技术呢?因为在 GBDT 算法迭代的过程中,我们越来越感觉到,这种模型的容量和表示能力有很大的限制,当模型的训练样本量达到千万数量级时,再增加训练样本的规模,模型精确度已经得不到明显的改善。所以我们把目光转向了深度学习技术。
我们首先把 DNN 用在了召回上。知乎用户的兴趣通常都是非常广泛的,我们的线上数据显示,一个用户在知乎上往往会对几十、上百个话题感兴趣。在这种情况下,用传统的 content based 算法,会有大量的分发策略需要人工设计,例如兴趣的衰减、交叉、去重等。而要是用 ALS 之类的协同过滤算法,又会面临数据过于稀疏的问题,毕竟我们面对的是一个用户和内容都达到了上亿量级规模的推荐场景。
所以,我们参考了 word2vec 的设计思路,设计了一个 DNN 网络,希望把每个用户和每一篇内容都表示成同一个空间的向量。任意两个向量的距离越小,表示它们越相关,如果这两个向量一个是用户,一个是内容,那就代表该用户对该内容感兴趣的概率越高。有了这个表示之后,对于每个用户,都可以利用 ANN 算法(Approximate Nearest Neighbor,近似最近邻搜索)召回它可能喜欢的内容。
这个 DNN 网络结构比较简单,但作为召回系统的效益是非常明显的。我们衡量推荐系统的召回模块有效性时,看一个关键的指标,从几万条数据中挑出的 100 个结果的准确度有多少,这 100 个结果里有多少准确预测到用户下次点击的数据。在这个指标上, DNN 比起 ALS 来讲提升了 10 倍的量级。当然,这个 DNN 网络也有一个问题,那就是新内容的表示不会在老的网络中自动被学习到。为了保证新内容能够比较快地被感兴趣的用户看到,我们采用一个离线流水线来解决这个问题。这条流水线使用 spark streaming 来实现了内容 embedding 的批量更新。这个 spark streaming 应用会采集线上的数据,根据线上内容的分发状况,以及用户对这些内容的行为反馈情况,通过一个简单的、两层神经网络的梯度下降,快速更新内容库中内容的 embedding 表示。
当然,我们随后也把 DNN 用在了排序中。最初上线的 DNN 是一个比较简单的全连接版本。
在上线后我们又持续地对这个模型进行了各种优化,包括引入 FM 层作特征之间的自动交叉、利用卷积神经网络处理文本输入、利用 LSTM 处理时序序列数据等,都取得了较好的效果。采用 DNN 模型的召回和排序上线后,再结合这些持续不断地优化,Feed 流的人均阅读量和人均使用时长均增长了 50% 以上。
4.多目标学习
在首页的优化工作中,除了上面介绍的工作之外,我们也在进行多种方向的尝试。其中一个方向是多目标学习。从 GBDT 开始到现在的 DNN 网络,本质上都是 CTR 预估。不过在知乎上,除了「阅读」这种行为非常重要外,其他的一些交互动作,例如点赞、评论、分享、收藏等,也都是反映用户体验的重要的行为指征。所以我们设计了一个机制来进行多目标学习,抛弃只看点击率的局限性。具体来说,是使用丰富的阅读数据来训练一个基准网络,然后利用这个基准网络的前面一些层做参数共享,在后两层,分别对于不同的学习目标,进行参数的微调。这是一种迁移学习的思路,可以大大节省离线模型训练和线上多目标推断时的计算量。多目标排序目前在我们的实际应用中已经有一些初步的结果,我们小流量对比发现,使用多目标模型来排序,除阅读之外的行为量都能有 10% 左右的增长。
另外,我们也在探索如何在排序学习中体现推荐列表的多样性。CTR 预估实际上是一种 pointwise 的排序方法,可能造成的后果是,如果用户对很多内容感兴趣,在内容质量相当的情况下,这种排序会将「最喜欢的一类内容」全都排到最前面,造成用户阅读时的疲惫感和单调感。一般来说,线上都会使用一些 Rerank 的方法,例如打散、隔离等规则,来保证多样性。但人工规则既不精确,设计起来也非常容易出 badcase。所以,我们正在尝试利用 seq2seq 的方法,来为用户直接生成推荐内容的列表。在 seq2seq 模型中,会将用户已经看到的内容考虑进去做为模型的输入,来体现用户推荐列表的多样性。目前这个工作我们刚刚开始进行调研和尝试,还有很多细节需要打磨,如果大家在这方面有什么思路或者经验的话,欢迎和我们交流。
5.人机结合
需要特别说明的是,知乎推动 AI 应用,目的是构建一个符合知乎社区和内容价值观的平台。但到目前为止,机器学习算法并不完美,尤其是在 NLP 领域,在语义理解方向上,AI 技术还有很大的提升空间。所以在知乎,为了让用户得到更好的体验,这些 AI 应用自始至终都伴随着人的高度参与,人机结合是避免「算法偏见」出现的有效方法之一。知乎在今年启动了一项名为「泰戈尔」的计划,从标签定义、标签生产、质量审核、标签应用等方面,建立了一套对内容进行识别和应用的闭环,并明确了算法、运营、业务团队在这个闭环中的角色。这个计划启动以后,在机器识别方面,接入了领域识别、内容质量判定、内容时效性识别等多个维度的识别算法,同时,我们的内容运营同事在机器识别的基础上,每天都会对健康、影视、法律等多个领域的,成千上万篇内容进行标注和算法结果的纠正。
6.首页架构改进
除了算法方面的改进之外,首页推荐团队在架构上的改进,也是不可缺少的。这里简单介绍两个工作,一个是已读服务的升级。为了避免把用户已经看过的内容再次推荐给他,信息流产品通常需要记录下来哪些内容已经推荐给用户过,这个信息是一个 N X N 的大表,数据量非常大且稀疏,另一方面,这个服务在读写上都有很高的访问量,hbase 这样的服务在响应时间的稳定性上,不能达到我们的要求,所以团队实现了一个叫 rbase 的系统,这个系统综合利用了 MySQL 的存储能力和可靠性以及 Redis 的低时延和高吞吐。在缓存失效的情况下对同一个热键值的并发读取不会产生惊群效应。利用写通缓存的更新策略再加上变更下推来维护缓存的一致性,所以不需要对缓存数据设定过期时间。我们使用分层缓存来从空间维度和时间维度提高命中率。利用分层缓存还可以更有效的应对跨数据中心部署时带宽受限的问题。最重要的是 Rbase 提供了 BigTable 一样的数据模型,并且和 Hbase 的 API 在功能和用法上非常接近,方便大家的迁移。
另一个工作是推荐架构的改造。
知乎早期广泛采用 python 语言来进行开发,我们的首页推荐的业务框架也不例外。在经过长时间的功能叠加之后,老系统在响应时间优化以及可维护性等方面,已经很难提出比较高的要求。所以团队在 18 年使用 java 进行了系统的重写,不仅大幅度优化了响应时间,节约了比较多的机器资源,还引入了多队列召回的能力,允许我们从不同维度召回与用户相关的内容,进一步提高多样性。
以上是知乎首页推荐团队的一些技术内容。
知乎的搜索
搜索是知乎在壮大过程中逐步优化的一个功能。目前,我们采用深度学习与传统模型相结合的方式来解决召回和排序上的用户满意度问题。我们的文本相关性算法最早只有 BM25。到今天,已经发展成为一个融合模型。既使用了传统的 TF-IDF 等特征,也采用了诸如 DSSM, MatchPyramid, KNRM 等深度语义特征,最终通过集成学习的方法将各个特征融合起来,得到最终的排序得分。
1.搜索算法应用
以深度学习为代表的搜索相关性语义特征,在最近几年来获得了长足的发展,从最早的以 DSSM 为代表的 Query/Doc 分别提取深度表征的方法,到近期的以 MatchPyramid, KNRM 等为代表的 Query/Doc 相互交叉为相关度图再做计算的方法,再到这两类方法相互融合的方法,以及最近的 BERT 模型,知乎搜索在深度语义特征上从无到有,从零到一,从学术社区和业界汲取了很多的灵感。在知乎的实践过程中,我们发现 MatchPyramid, KNRM 等第二类方法的效果,普遍优于 DSSM 等第一类方法。深度语义特征上线之后,我们在头部、腰部、长尾的搜索点击比普遍提升了约 2% - 3% 不等。
下一步,除了实践更多的深度模型和调优已有的模型之外,我们还需要积累和挖掘更多高质的训练数据,不断迭代优化我们的搜索体验。除此之外,将深度学习应用到更多的搜索模块中,也是接下来我们的挑战之一。
2.搜索架构优化
除了算法方面的改进,我们也投入了不少人力在搜索的架构优化上。知乎早年采用 ES 作为我们的索引引擎,随着数据量的增加,我们遇到了 ES 集群的服务稳定性问题,以及 ES 对我们的排序算法支持不友好等问题。所以在 17 年,团队自己开发了一套在索引格式上完全兼容 ES 的引擎,逐步替换了在线上服务的 ES 集群。为什么要这样做呢?因为我们没有人力把所有事情停下来,完全重写一个同时支持索引构建和提供在线服务的引擎系统,所以把这个工作分成了两部分,第一个阶段先重写在线服务,直接使用 ES 生产出来的索引文件;第二个阶段再重写索引构建逻辑,完全解除对 ES 的依赖。这个系统使用 rust 开发。Rust 语言是一种类似于 C/C++ 的无 GC 语言,虽然 Rust 语言的学习曲线非常陡峭,但是在团队熟悉语言后,由于 Rust 能在编译器层面避免内存安全问题和并发安全问题,所以整体获得的收益是非常显著的。目前知乎全部的搜索请求都由新的索引服务支撑,在可用性达到了 5 个 9 的同时性能上也不输于 C++ 编写的类似系统所能达到的水平。
通过个性化推荐和搜索,我们尽可能缩短了用户和内容之间的距离,让用户在知乎摆脱信息过载带来的负担和压力。但这样还不够,我们还面临着另外一个挑战,用户的内容消费不断升级,知乎的解决方案是,从内容生产和内容治理等维度入手,加速优质、稀缺内容的生产,压缩低质内容的传播空间。
知乎问题路由
在社区运营中,内容创作者除了自我驱动之外,有没有来自社区的外力刺激,促使他更积极地投入创作呢?我们认为,让用户快速看到自己感兴趣的提问,激发他的创作欲望,是非常重要的。当一个问题被用户提出以后,我们采用人工审核、算法和运营策略相配合的方式,精准邀请相关领域的用户回答问题,尽可能地提高问题的回答率,从而丰富内容社区。问题路由在其中起到的就是提升匹配精准度和效率的作用。
问题路由实际上也是一个典型的推荐问题。但无论从数量级上来说,还是从重点考虑的特征来说,问题路由和首页个性化推荐是完全不同的问题,所以我们在推荐技术的使用上也略有不同。
具体来说,在召回阶段,我们重点考虑用户的创作行为,利用这些行为来构建用户的向量表示,并且将提问也嵌入到同一个向量空间中来,然后再用前面提到的 ANN 算法将与提问最相关的用户召回;在排序阶段,我们会综合考虑用户的长期兴趣和短期兴趣,以及用户在该领域下的资深程度和专业程度,等等特征,使用 gbrank 模型,找出当前最适合回答的用户,进行个性化的问题邀请。问题路由功能上线以来,由系统推荐带来的应邀回答数比过去提升了 400%。接下来,我们计划把 DeepFM 等 DNN 模型引入到路由排序工作中,同时,也会把优化的目标从全部问题中被回答问题的比例,扩展到应答率上来,确保回答者的体验。
算法机器人「瓦力」
要想提升优质内容的生产量,除了让大家有得聊之外,也需要我们理性讨论,好好说话。所以,构建一个良性的社区讨论氛围,对破坏社区氛围的低质、不友善行为和内容,进行及时的识别和处理,也是非常重要的工作。我们在人力运营的同时,通过 AI 算法在海量信息池中精准识别和处理违规内容,提升效率。
2016 年,我们对知乎评论系统进行了一次升级,推出了知乎算法机器人「瓦力」,上线了评论自动折叠功能。「瓦力」目前可以实时高效地处理很多场景:答非所问、阴阳怪气,以及歧视、恶意贴标签、辱骂等各种不友善行为,全力减少低质和无关内容对读者的干扰,降低网络暴力,为用户提供人文关怀。
1.「阴阳怪气」内容识别
这里举个例子,阴阳怪气是一种很明显的不友善行为,也称作反讽、讽刺。这一直都是情感分析领域的前沿问题。这种修辞手法使用正面的词汇表达负面的含义,需要对语义有更深入的理解才能很好地识别。例如经典的「呵呵」,由于双方不同关系、说话的不同场景和时间都会带来迥然不同的表意。即便是人工判定都存在标准化难度,算法模型的训练挑战就更为艰难。
这张图比较完备地展示了知乎识别阴阳怪气评论的技术方案。我们把评论和相应回答的文本特征、标点符、表情符统计特征、是否命中反讽词表等多维度 feature 作为模型的输入,采用 CNN 和 LSTM 相结合的网络拓朴结构训练二分类模型;在训练数据获取方面,我们使用站内有大量一致用户行为的语料,来自动生成二元的标注,为了提高模型泛化能力,我们通过 active learning 方法选取站内评论,经过人工标注加入训练集。今年 6 月,「瓦力」的阴阳怪气识别功能正式上线,在召回率 25% 的情况下,准确率达到了 95%。
2.「爆照」内容识别
除了上述的 NLP 领域的应用之外,「瓦力」也被应用在图片内容的识别和治理上。比如「爆照识别」功能。在知乎上,部分用户为了博取关注会在回答文章中粘贴自己的照片,据后台统计,每天大约有 2500 人发自拍照,这些内容往往以图片罗列的形式出现,不具有足够的传达信息作用,增加了知友们筛选有价值信息的成本。因此,过去一段时间,我们也在着力于提升瓦力对爆照类内容的识别能力。「瓦力」能够快速识别这些自拍照是否违规,是否需要做出处理。
在爆照识别方案中,「瓦力」首先基于图片的 HOG 特征做人脸检测,在全站图片库中识别出自拍照、明星照片、表情包等含有人脸的图片,再通过 Blinear CNN 细粒度分类模型过滤掉表情包,筛选出自拍照和明星照片。但是,部分修图后的自拍照与明星照仅从视觉特征难以区分,因此,我们结合图片上下文的文本,通过文本分类算法来区分这张照片到底是自拍照还是明星照。目前,瓦力的爆照识别算法覆盖率已达 83%,准确度可达 95%。
视频识别技术
另外一块和内容消费升级相关的工作,在视频上。在知乎,视频是信息传达的重要媒介。我们在这个领域的工作当前主要是短视频打标签和封面推荐,其中短视频封面推荐目前已达到可用状态。
视频封面选取的好坏直接影响用户看到视频时的点击决策。有些时候,用规则选取的帧,可能无法表达视频内容,甚至出现模糊、全黑的情况。
在视频封面抽取方案中,我们先提取每帧图片的 HSV 颜色特征,接下来通过改进的 Kmeans 聚类方法,抽取具有内容代表性的关键帧,然后在这些关键帧基础上以 WILDCAT 算法过滤掉模糊图片,筛选出高质量的图片作为候选封面。从评测效果来看,通过视频封面推荐,有 24% 的视频封面得到了改善。
知乎如何连接「人与人」
除了「人与内容」的连接,知乎的技术还应用在「人与人」的连接中。对于任何一个社区而言,用户与用户之间的连接是用户活跃度和归属感的重要影响因素。
在这个问题上,我们通过 Graph Embedding 模型对用户进行隐式表示的学习,计算出两个用户之间的亲密度、兴趣相似度,以此进行更精准的推荐,让用户更多地在社区里发生连接。Embeeding 模型基于不同的用户属性,可以呈现出不同的学习结果:
基于用户行为的 Embeeding 表示
基于用户行为的 Embeeding 表示,主要使用用户搜索内容、关注、收藏、点赞、阅读的回答、文章等对应的话题,作为用户的特征,整理成 0-1 的向量。使用变分自编码器(Variational Auto-Encoder,VAE) ,使样本对应到正态分布,计算此正态分布和标准正态分布的 KL 散度距离作为额外的 loss,最终为得到用户的 Embedding 表示。
###基于用户社交关系的 Embeeding 表示
基于用户社交关系的 Embeeding 表示,主要使用 skip-gram 模型,得到用户的特征表示,从用户关注优秀回答者的关注关系网络中抽取数据集,采用 Randomwalk 方法抽样有序的节点,从而将社交网络转化为有序节点进行学习。
Embedding 模型目前的使用场景也很丰富——
1.使用用户聚类来在推荐中做召回(user representation + Cluster + CF (for feed candidate )):使用用户 Embedding 表示,经过聚类计算后,得到用户的人群,我们可以把这个群体的高互动内容作为 feed 候选,放入到推荐系统当中。
2.用户亲密度 user affinity:使用用户 Embedding 表示 + 用户对用户的互动行为特征,可以预测用户的关注关系,得到用户亲密度值。这个值可以用在很多和社交相关的策略之中。
3.基于种子用户和 user representation 的人群扩展:人工给定或者策略圈定种子用户,使用用户 Embedding 表示计算得到和种子用户最相近的 top n 用户进行目标人群扩展,这个能力目前主要应用于我们的商业化产品中。
知乎如何连接「内容与内容」
有了「人与内容」、「人与人」的连接之后,我们很自然地会想到「内容」与「内容」的连接。目前,知乎在这部分的工作主要集中在知识图谱领域。
知识图谱
我们已经构建了以话题、实体为核心的百万级节点、千万级边,构建了话题相关性图谱、话题上下位图谱、话题与实体的关系图谱等。知乎上的问题和回答相当于半结构的文本组织,里面蕴含了大量的有价值信息,但这些信息缺乏一个结构化的整理,我们希望通过构建这样一个知识图谱,让知乎上越来越多的提问和回答中的有价值信息,能够以一种更结构化的形式表征出来。
长远来看,我们也会把知乎用户作为知识图谱的一个节点,并和话题、实体等语义节点建立连接关系。
目前,知乎的知识图谱已经在首页、推荐和搜索等实际业务中得到了应用。鉴于目前知乎知识图谱数据规模不算很大,我们部署了单机 neo4j,后续随着数据规模的扩增,我们再考虑腾讯知识图谱或者 neo4j 集群方案。
知乎「智能社区」
从引入机器学习开始,知乎逐步将 AI 算法贯穿到内容与用户的各个环节和体验中,构成了「人与内容」、「人与人」、「内容与内容」三个维度的连接。
通过这些技术应用尝试,我们希望每个用户的内容需求都能被快速满足,内容的价值能在流通中得到充分释放。我们希望整个知识生产的方式、节奏和效率都得到实质性的变化,这就是知乎下一步要达成的新的目标,构建新型的「智能社区」。
当然,由我们到目前为止的实践来看,算法还是不完美的,也有很多领域是算法能力不可达的。我们相信技术的快速演进,智能社区终将实现,但在这个过程中,为了保证用户体验,也不介意做一些 dirty work,或者人工介入。
评论