Linux 之父出席、干货分享、圆桌讨论,精彩尽在 OpenCloudOS 社区开放日,报名戳 了解详情
写点什么

用 Kiji 构建实时、个性化推荐系统

  • 2014 年 4 月 03 日
  • 本文字数:3739 字

    阅读完需:约 12 分钟

现在网上到处都有推荐。亚马逊等主流电子商务网站根据它们的页面属性以各种形式向用户推荐产品。Mint.com 之类的财务规划网站为用户提供很多建议,比如向用户推荐他们可能想要办理的信用卡,可以提供更好利率的银行。谷歌根据用户搜索历史记录的信息优化搜索结果,找到相关性更高的结果。

这些知名公司使用推荐提供情境化的、有相关性的用户体验,以提高转化率和用户满意度。这些建议原来一般由每天晚上、每周或每月生成新推荐的批处理作业计算提供。

然而对于某些类型的推荐,响应时间有必要比批量处理作业所需的时间更短,比如为消费者提供基于地理位置的推荐。比如电影推荐系统,若用户先前看过动作片,但现在要找一部喜剧片,批量推荐很可能会给出更多动作片,而不是最相关的喜剧片。本文将会介绍如何使用 Kiji 框架,它是一个用来构建大数据应用和实时推荐系统的开源框架。

Kiji,以实体为中心数据和 360 度视角

要构建实时推荐系统,首先需要一个能存储 360 视角客户的系统。此外,我们需要具备迅速获取与指定用户相关数据的能力,以便在用户与网站和移动应用交互时做出推荐。 Kiji 是一个构建实时应用的模块化开源框架,它收集,存储和分析这类数据。

一般情况下,一个 360 度视图所需的数据可以被称为以实体为中心的数据。一个实体可以是任意数量的东西,比如客户、用户、帐户,或者 POS 系统或移动设备之类更抽象的东西。

一个以实体为中心的存储系统要能在一行数据中存储与某个特定实体有关的一切信息。这对传统的关系型数据库来说是个挑战,因为这些信息可能既有状态型数据(如姓名,电子邮件地址等)又有事件流(如点击)。传统的系统需要把这些数据存放在多张表中,处理时再把这些表联接起来,这使得它很难做到实时处理。为了解决这个问题,Kiji 用了Apache HBase,它在四个维度 - 行、列族、列标识和时间戳- 存储数据。借助时间戳维度和HBase 存储多个版本Cell 的能力,Kiji 能够存储有更多状态的缓慢变化的事件流数据。

HBase 是 Apache Hadoop 使用的一个键 - 值存储系统,它构建在 HDFS 之上,为大数据解决方案提供了必需的可扩展性。在 HBase 上开发应用程序面临的巨大挑战是,它要求所有进出系统的数据都是字节数组。为了解决这个问题,Kiji 的最终核心组件是 Apache Avro,被 Kiji 用来存储易于处理的数据类型,如标准字符串和整数,以及由用户定义的更复杂的数据类型。 读写数据时,Kiji 为应用程序做必要的序列化和解序列化处理。

开发用在实时中的模型

Kiji 为开发模型提供了两套 API,Java 和 Scala,两套 API 都支持批量和实时组件。如此划分的目的是将模型执行划分为不同阶段。批量阶段是训练阶段,是一个典型的学习过程,在该过程中,将使用完整的数据集来训练模型。该阶段的输出可能是线性分类器的参数,或者聚类算法的群集位置,或在协同过滤系统中相互关联条目的相似性矩阵。实时阶段被称为评分阶段,取得经过训练的模型,并将它与实体数据相结合产生衍生信息。关键是这些衍生数据被当作一等公民,也就是说它可以存回到实体所在的行中,用于推荐,或作为后续计算的输入。

Java API 被称为 KijiMR, 而 Scala API 构成了 KijiExpress 工具的核心。 KijiExpress 利用 Scalding 库提供 API 来构建复杂的 MapReduce 工作流,同时避免了大量 Java 冗余代码,以及串联 MapReduce 作业所必需的任务调度和协作。

个体与总体

之所以要划分出批量训练和实时评分两个阶段,是因为 Kiji 观察到总体趋势变化缓慢,而个体趋势的变化迅速。

比如一个包含上千万次购买记录的用户总体数据集。多一次购买不太可能对总体趋势的好恶造成重大影响。但对于一个只有 10 次购买记录的特定用户而言,第 11 次购买将对系统判断用户兴趣产生巨大影响。鉴于这种主张,应用程序只需在收集到足以影响总体趋势的数据时再重新训练它的模型。但对于特定用户而言,我们可以通过实时响应用户的行为来改善推荐的相关性。

实时给模型评分

为了做到实时评分,KijiScoring 模块提供了一个惰性计算系统,应用程序可以只为经常与其交互的活跃用户生成最新推荐。通过惰性计算,Kiji 应用程序不必为那些不经常光顾或再没回来过的用户生成推荐。这还有些额外的好处,Kiji 可以在推荐时考虑像移动设备的位置之类的情境信息。

KijiScoring 的主要组件叫 Freshener。Freshener 实际上是另外两个 Kiji 组件的组合:ScoringFunctions 和 FreshnessPolicies。正如前面提到的,一个模型包括训练和评分两个阶段。ScoringFunction 是一段代码,描述了如何把经过训练的模型和单一实体的数据组合起来产生一个分数或建议。FreshnessPolicy 定义数据变得陈旧或过时的时间。比如说,普通的 FreshnessPolicy 会指出超过一个小时后数据就过期了。更复杂的策略可能会在实体经历过一定次数的事件后将其标记为过期,比如点击或产品访问等事件。最后,ScoringFunction 和 FreshnessPolicy 被附着在 Kiji 表中特定的列上,在必要时被触发来刷新数据。

进行实时评分的应用程序中包含一个服务器层,被称为 KijiScoring 服务器,它是负责刷新陈旧数据的执行层。当用户与应用程序交互时,请求将被传递到 KijiScoring 服务器层,它直接与 HBase 集群通信。KijiScoring 服务器将会请求数据,并且在获取到数据后根据 FreshnessPolicy 检查数据是否是最新的。如果是最新的数据,它将其直接返回给客户端。如果是过时的数据, KijiScoring 服务器将为发出请求的用户运行指定的 ScoringFunction。你需要掌握的要点是它只为发出请求的用户刷新数据或推荐;而不是执行批处理操作,刷新所有用户的数据。这样 Kiji 就可以只是做那些有必要做的工作。数据刷新完成后会被返回给用户,同时写回 HBase 以备后用。

一个典型的 Kiji 应用程序将包括一定数量的 KijiScoring 服务器,它们是可以向外扩展的无状态 Java 进程,并能够运行使用单一实体的数据作为输入的 ScoringFunction。Kiji 应用程序通过 KijiScoring 服务器过滤客户端请求,由它决定数据是否是最新的。若有必要,它会在把所有推荐传回客户端之前运行 ScoringFunction 进行刷新,并将重算后的数据写到 HBase 中,以备后用。

将模型部署到生产系统中

能够轻松迭代其底层的预测模型是实时推荐系统的一个重要目标,避免因为要将新的或改进过的模型部署到生产环境而停掉应用程序。Kiji 为此提供了 Kiji 模型库,它结合了描述模型以及用来训练模型和给模型评分的代码如何执行的元数据。KijiScoring 服务器需要知道什么样的列访问会触发刷新,要用的 FreshnessPolicy,以及将在用户数据上执行的 ScoringFunction,以及所有经过训练的模型的位置,或给模型评分所必需的外部数据。元数据也存在一个 Kiji 系统表中,只是另一种最底层的 HBase 表。此外,模型库在受管的 Maven 库中为已注册的模型存储代码工件。KijiScoring 服务器为新登记或未登记模型定期轮询模型库,按需加载或卸载代码。

整合到一起

使用协同过滤是一种非常常用的推荐提供方式。协同过滤算法通常会建立一个大型的相似矩阵,用来存放一个产品跟产品目录中其它产品的关联信息。矩阵中的每一行代表一个产品 Pi,每一列代表另一种产品 Pj。(Pi,Pj)中的值就是两个产品之间的相似度。

在 Kiji 中,相似矩阵是通过批量训练过程计算出来的,然后被存储在文件或 Kiji 表中。相似矩阵中的每一行都会被存放在 Kiji 产品表中某一行的单独列中。在实践中,这一列可能会变得非常大,因为其中放的是目录中所有产品的清单和相似性。通常情况下,批处理作业也会挑出相似度最高的条目存到表中。

相似矩阵在评分时是通过 KeyValueStore API 访问的,这个 API 可以访问外部数据。对于无法完全放在内存中的大型矩阵,可以把它们放在分布式的表中,这样应用程序可以只请求计算必需的数据,从而大幅降低对内存的需求。.

既然我们在评分阶段之前已经做了很多繁重的​​工作,那么评分自然成了一种相当简单的操作。如果我们想基于被查看的条目展示推荐信息,一个通用的评分函数只是从产品表中查找相关产品,并显示它们。

将该过程再推进一点并对结果做个性化处理是一个相对简单的任务。在个性化系统中,评分函数将会取得用户最近对产品的评级,并使用 KeyValueStore API 查找与用户评价过的产品相似的产品。结合评级和存储在产品表中的产品相似度,应用程序可以预测用户给相关条目下的评级,并将预测评级最高的产品推荐给用户。通过限制所用评级和所有已评级的相似产品的数量,系统在用户与应用程序进行交互时可以很轻松地处理上述操作。

结论

在本文中,我们可以了解到如何用 Kiji 开发一个可以实时刷新推荐的推荐系统。利用 HBase 进行低延迟处理,用 Avro 存储复杂的数据类型,使用 MapReduce 和 Scalding 处理数据,应用程序能够在实时情境中给用户提供相关推荐。如果你想看看这个系统的样例代码,请访问 WibiData Github

关于作者

Natkins**(@ nattyice)是WibiData的现场工程师,他专注于帮助用户在KijiWibiEnterprise之上构建大数据应用。在为WibiData工作之前,乔恩曾是ClouderaVertica系统的软件工程师。**


感谢吴海星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014 年 4 月 03 日 22:4619020

评论

发布
暂无评论
发现更多内容

springboot实战项目源码,java算法视频百度云盘,阿里P8亲自讲解

Java 程序员 后端

springcloud百度网盘,牛客网面试题,Java面试高频知识点

Java 程序员 后端

springmvc原理图解,尚硅谷ajax源码,Redis宕机数据丢失解决方案

Java 程序员 后端

Spring容器如何解决循环依赖的原理,Java编程教学视频

Java 程序员 后端

tomcat面试题,传智播客java就业班视频教程,Spring的XML解析原理

Java 程序员 后端

Redis灵魂14问,Java编程从入门到实践

Java 程序员 后端

rocketmq原理解析,尚硅谷深圳校区,万分膜拜!

Java 程序员 后端

springboot思维导图,尚学堂java300集,从头到尾,都是精华

Java 程序员 后端

SpringBoot,黑马java视频教程,绝对干货

Java 程序员 后端

spring全方位深入探索,2021Java开发社招面试解答之性能优化

Java 程序员 后端

spring教程,java程序设计基础教程,OMG

Java 程序员 后端

tomcat服务器面试题,java项目开发实训教程,Java编程教程视频下载

Java 程序员 后端

oppoJava面试题,开课吧高级架构师10期咋样,正式加入字节跳动

Java 程序员 后端

springcloud架构源码,慕课网极客学院,总结到位

Java 程序员 后端

spring教程,spring框架菜鸟教程,Java重点知识点

Java 程序员 后端

Spring是怎样巧用三级缓存解决循环依赖的,nginx实战百度网盘,面试必问!

Java 程序员 后端

RocketMQ避坑指南,java入门教程全套,实战篇

Java 程序员 后端

springcloud教程入门,极客时间kafka,4年小Java的心路历程

Java 程序员 后端

spring教程下载,linux入门基础教程,2021Java者未来的出路在哪里

Java 程序员 后端

tomcat面试题汇总,java设计模式菜鸟教程,linux内核教程

Java 程序员 后端

netty框架教程,mysql数据库教程视频指导版,HTTPS面试常问全解析

Java 程序员 后端

Nginx如何支持HTTPS,“重金求来”Alibaba技术官并发编程笔记

Java 程序员 后端

RPC的通信Netty的底层是Nio,在一家公司干多长时间跳槽才合适

Java 程序员 后端

netty源码剖析与实战百度云,牛客网搜题软件,字节跳动高级Java开发面试

Java 程序员 后端

Redis缓存:尚硅谷springboot百度云,Java中高级面试题总结

Java 程序员 后端

springcloud入门,动力节点与尚学堂,月薪30K

Java 程序员 后端

spring教程,java大学实用教程第四版作业题,中高级Java开发面试题

Java 程序员 后端

spring源码视频教程,java尚学堂,Java项目视频

Java 程序员 后端

netty架构图,linux教程视频,缓存+一致性哈希+分布式面试题

Java 程序员 后端

springboot教学视频,mysql破解版百度云,微盟Java笔试题

Java 程序员 后端

RocketMQ生产部署架构设计,Java面试超详细知识点

Java 程序员 后端

GPU容器虚拟化:用户态和内核态的技术和实践详解

GPU容器虚拟化:用户态和内核态的技术和实践详解

用Kiji构建实时、个性化推荐系统_大数据_Jon Natkins_InfoQ精选文章