`
zhengyun_ustc
  • 浏览: 83084 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

#研发解决方案介绍#Recsys-Evaluate(推荐评测)

阅读更多
郑昀 基于刘金鑫文档 最后更新于2014/12/1
关键词:recsys、推荐评测、Evaluation of Recommender System、piwik、flume、kafka、storm、redis、mysql

本文档适用人员:研发
 
推荐系统可不仅仅是围着推荐算法打转
  先明确一下,我们属于工业领域。很多在学术论文里行之有效的新特奇算法,在工业界是行不通的。当年我们做语义聚合时,分词、聚类、相似性计算、实体词识 别、情感分析等领域最终还都采用了工业界十几年前乃至于几十年前就流行的成熟算法。如果算法不能决定命运,那什么是关键呢?
  算法+规则库+人工干预(整理语料、标识、调参数等),大都是脏活儿累活儿。
  或者叫,特征+算法+人工干预,用特征缩小数据范围或降维。
  我在2009年曾经写道
在语义的世界里,可以近似地说:万事万物都是特征提取。 你只要找到特征,事情就好办。……
……你期望毕其功于一役吗?自然语言处理的真实应用里是很难有什么场景找到一个通吃特征的。都是一层一层特征叠加的。 
一层特征去掉一部分垃圾数据。如此反复,终成正果。注意方法论。
  梁斌在2012年微博说道:
统计粗且糙,乃大锤。规则细而精,乃小锤。先大场后细棋。
  规则库怎么来的?得建设一些方便观测的外围系统,才能发现特征、建立规则、调整参数、观察效果。所以与此类似,做了推荐服务后,就需要推荐效果评测了。
 
推荐评测应用场景
  电商推荐场景下有非常明确的指标:
  1. 推荐位展示次数商品投放次数
  2. 推荐位展示点击率商品投放点击率
  3. 最重要的是下单转化率成单转化率(或叫支付转化率)这两个硬指标。
  那么推荐评测系统应具备的功能有:
  1. 实时(至少是近乎实时)统计几个展示性指标
  • 区分网站端和移动客户端的推荐展示效果
  • 进一步区分不同客户端,如 iOS 和 Android
  • 数据概览
  • 按推荐位类型或推荐算法归纳各种指标
    • 看了又看
    • 浏览过该商品的用户购买了
    • 您可能对以下商品感兴趣(猜你喜欢)
    • 商品周边商品(注:只能是本地生活服务类商品)
    • 签到弹窗推荐
    • 商品附近门店
    • 门店周边美食
    • 附近吃喝玩乐
    • ……
  • 常见的评测推荐效果的两种实验方法
    1. 离线试验:
    • 做法:从日志系统中取得用户的行为数据,然后将数据集分成训练数据和测试数据,比如80%的训练数据和20%的测试数据(还可以交叉验证),然后在训练数据集上训练用户的兴趣模型,在测试集上进行测试
    • 优点:它不需要实际用户的交互
    • 缺点:离线实验只能评测一个很狭窄的数据集切面,主要是关于算法预测或者评估的准确性
    • 目的:提前过滤掉性能较差的算法
  • AB测试:
    • 做法:通过一定的规则把用户随机分成几组,并对不同组的用户采用不同的推荐算法,这样的话能够比较公平地获得不同算法在实际在线时的一些性能指标
  • 推荐服务接口测试界面
    • 暴露出来,让我们手工就可以提交,看看效果
     
    推荐评测技术选型
      说到实时日志聚合和处理,还得是 flume+kafka+storm,所以技术选型是:
      Piwik+Flume+Kafka+Storm+Redis+MySQL
     
    推荐评测数据流转流程
    1. 数据上报:——Piwik
      1. 主站本身部署了 开源流量统计系统 Piwik,所以在网页的各种推荐位上按规则埋点即可
    • 实例:“浏览过该商品的用户还购买了”推荐栏第一位商品的a元素增加了wwe属性:wwe="t:goods,w:rec,id:ae45c145d1045c9d51c270c066018685,rec:101_01_103"
  • 浏览器完全加载完成后, Piwik JavaScript 会向服务器端发送埋点数据
  • Piwik 服务器端收到后,写磁盘日志文件
  • 数据采集:——Flume
    1. Piwik 集群的每一台服务器上都部署了 Flume Agent
    2. agent 会向 推荐数据收集 Flume 集群 推送日志,譬如配置为每增加一行日志就推送,或每5分钟推送一次
    3. 手机客户端的埋点日志则存放在无线服务器端的 MySQL 中,所以我们用脚本每分钟读取一次数据,放到 flume 的监控目录下
  • 数据接入:——Kafka
    1. 由于数据采集速度和数据处理速度不一定匹配,因此添加一个消息中间件 Linkedin Kafka 作为缓冲
    2. 数据流转方式为 Flume Source-->Flume Channel-->Flume Sink,那么我们写一个 Kafka Sink 作为消息生产者,将 sink 从 channel 里接收到的日志数据发送给消息消费者
    3. http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-%20%e5%89%af%e6%9c%ac35.png
  • 流式计算:——Storm
    1. Storm 负责对采集到的数据进行实时计算
    2. Storm Spout 负责从外部系统不间断地读取数据,并组装成 tuple 发射出去,tuple 被发射后在 Topology 中传播
    3. 所以我们要写一个 Kafka Spout 作为消息消费者拉日志数据
    4. 再写些 Storm Bolt 处理数据
    • http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-%20%e5%89%af%e6%9c%ac36.png,一个Topology的结构示意图
  • 数据输出:——Redis
    1. Storm Bolt 实时分析数据之后,将统计结果写入 Redis
  • 数据统计:——MySQL
    1. 评测系统实时数据直接从 Redis 中读取,并查询主站数据库追踪成单情况,同步到 MySQL 中,作为报表展示数据源
      简而言之,数据按如下方式流转:
    1. piwik javascript
    2. piwik servers
    3. flume agent
    4. 自定义 kafka sink
    5. 自定义 kafka spout
    6. 自定义 storm bolt
    7. redis
    8. 评测系统计算
    9. mysql
    10. 评测系统报表展示
     
    Flume+Kafka+Storm常见问题
      虽然我们的实时流量统计和推荐评测系统均采用了 flume+kafka+storm 方案,但要注意这个方案也有一些小坑。下面摘录一些第三方的结论
    • 如 果配置为每新增一条日志就采集,那么 flume 到 kafka 的实时数据可能会由于单条过快,造成 storm spout 消费 kafka 消息速率跟不上。延时可以是数据发射到 stream 中后进行 hbase 的计算操作引起的(注:hbase 的性能确实堪忧,不适合这种实时数据处理,尤其是加了较多索引之后);
      • 可参考的一个数据:storm 单条流水线的处理能力大约为 20000 tupe/s (每个tuple大小为1000字节);
      • tuple 过多,会由于 kafka 的 message 需要 new String() 进行获取,会报 gc 的异常;
      • tuple 在 stream 中的大量堆积,造成超时自动回调 fail() 的函数;
      • 可以进行多 tuple 结构的优化,把多个 log 打包成一个 tuple
      • 就一般情况而言,单条发射能扛得住
     
    Kafka Sink 消息生产者代码片段
    KafkaSink.java
    import kafka.javaapi.producer.Producer;
    ……
    public class KafkaSink extends AbstractSink implements Configurable {
    ……
     private Producer<String, byte[]> producer;
    ……
     @Override
     public Status process() throws EventDeliveryException {
      Channel channel = getChannel();
      Transaction tx = channel.getTransaction();
      try {
       tx.begin();
       Event e = channel.take();
       if (e == null) {
        tx.rollback();
        return Status.BACKOFF;
       }
       producer.send(new KeyedMessage<String, byte[]>(topic, e.getBody()));
       tx.commit(); 
       return Status.READY;
      } catch (Exception e) {
     
    Kafka Spout 消息消费者代码片段
    spout 有多个,我们挑 kafka spout 看下。
    KafkaSpout.java
    public abstract class KafkaSpout implements IRichSpout {
    ……
     @Override
     public void activate() {
    ……
       for (final KafkaStream<byte[], byte[]> stream : streamList) {
        executor.submit(new Runnable() {
         @Override
         public void run() {
          ConsumerIterator<byte[], byte[]> iterator = stream.iterator();
          while (iterator.hasNext()) {
           if (spoutPending.get() <= 0) {
            sleep(1000);
            continue;
           }
           MessageAndMetadata<byte[], byte[]> next = iterator.next();
           byte[] message = next.message();
           List<Object> tuple = null;
           try {
            tuple = generateTuple(message);
           } catch (Exception e) {
            e.printStackTrace();
           }
           if (tuple == null || tuple.size() != outputFieldsLength) {
            continue;
           }
           collector.emit(tuple);
           spoutPending.decrementAndGet();
          }
         }
     
    Storm Bolt 代码片段
    有多个自定义 bolt,挑一个看下。
    EvaluateBolt.java
    public class EvaluateBolt extends BaseBasicBolt {
    ……
     @Override
     public void execute(Tuple input, BasicOutputCollector collector) {
    ……
      if (LogWebsiteSpout.PAGE_EVENT_BROWSE.equals(event)) {
       if (LogWebsiteSpout.PAGE_TYPE_GOODS.equals(pageType)) {
        incrBaseStatistics(baseKeyMap, BROWSE_ALL, 1);
       } else if (LogWebsiteSpout.PAGE_TYPE_PAY1.equals(pageType)) {
        incrBaseStatistics(baseKeyMap, ORDER_ALL, 1);
       }
       String recDisplay = input.getStringByField(LogWebsiteSpout.FIELD_REC_DISPLAY);
       recDisplayStatistics(recDisplay, time, pageType, baseKeyMap);
      } else if (LogWebsiteSpout.PAGE_EVENT_CLICK.equals(event)) {
       String recType = input.getStringByField(LogWebsiteSpout.FIELD_REC_TYPE);
     
    评测指标定义:
    • 投放点击率:推荐浏览量/推荐商品投放量
    • 展现点击率:推荐浏览量/推荐位展现次数
    • 推荐展示率::推荐位展示次数/总浏览量
    • 推荐浏览量:经由推荐产生的浏览量
    • 推荐商品投放量:推荐位投放的推荐商品数量(如:用户浏览A商品,那在浏览或购买推荐位产生的推荐商品为5个,则推荐商品投放量+5)
    • 推荐位展现次数:如果推荐位有推荐商品并展示,计数+1
     
    -over-
    0
    0
    分享到:
    评论

    相关推荐

      RecSys-master.zip

      推荐系统(Recommendation System,简称RecSys)是信息过滤系统的一种,主要用于个性化推荐,帮助用户在海量信息中发现他们可能感兴趣的内容或产品。RecSys在电商、音乐、电影、新闻等多个领域都有广泛应用,极大地...

      JaniceWuo电影推荐项目复制中的问题与解决方案-CF recSys.zip

      JaniceWuo电影推荐项目复制中的问题与解决方案_CF recSys.zipJaniceWuo电影推荐项目复制中的问题与解决方案_CF recSys.zipJaniceWuo电影推荐项目复制中的问题与解决方案_CF recSys.zipJaniceWuo电影推荐项目复制中的...

      recsys-challenge2015.rar_data mining python_推荐系统_推荐系统实现

      在本资源"recsys-challenge2015.rar"中,包含了使用Python进行数据挖掘和构建推荐系统的一些关键脚本。这些脚本对于理解和实践推荐系统算法有着重要的价值。让我们逐一解析每个文件并探讨其中涉及的技术和概念。 1....

      推荐算法(MovieLens-RecSys-master)

      项亮所著的《[推荐系统实践](https://book.douban.com/subject/10769749/)》一书是非常优秀的推荐系统入门书籍,但书中只描述了单步的计算如何实现,缺乏一个完整的示例来展示推荐系统从建立数据集到评估模型的整个...

      recsys-offline:一个推荐系统的offline端

      Recsys-offline是一个推荐系统的离线计算部分,基础数据采用Swift采集的数据,它: 1.基于Hadoop,Mahout,HBase,Zookeeper开发的2.现有的算法只支持分布式,基于项目,Kmeans的推荐3.支持简单的可配置4.支持定时...

      Recsys-frontend:一个易于设置的推荐系统前端,用于研究、娱乐和科学

      #Recsys-前端Recsys-frontend 是一个易于设置的前端推荐系统 (recsys),由组合而成。 它提供了一个基于 HTML 的前端,允许浏览(最新)电影的目录,提供评级,点击按钮计算和可视化多个推荐算法的推荐结果。 查看...

      CF-Movie-Recsys.rar

      基于CF的电影推荐,使用标准数据集MovieLines,利用Python3实现,文档包括:MovieLines数据集,数据预处理程序,CF推荐,LFM推荐,Prank推荐。不需调试解压即可使用,亲测可用。谢谢大家支持

      Recsys-Spotify-2018-challenge:我们针对recsys-spotify 2018挑战的解决方案的源代码

      该存储库包含我们针对RecSys 2018挑战的解决方案的Python源代码。 资料准备 为了将我们提交的内容复制到RecSys 2018挑战赛,您首先需要从赛下载百万播放列表数据集和挑战赛集。 这两个数据集分别记录为JSON文件和...

      fc-recsys-lecture

      本项目“fc-recsys-lecture”专注于使用机器学习技术构建推荐引擎,旨在帮助用户发现感兴趣的内容或产品,从而提升用户体验和商业价值。这个项目与一场关于推荐系统的讲座紧密关联,提供了源代码和相关数据,以便...

      RecSys-master

      《推荐系统实现——深入解析RecSys-master》 在信息技术飞速发展的今天,推荐系统(Recommendation System,简称RecSys)已经成为了个性化信息服务的核心技术之一,广泛应用于电商、音乐、电影等众多领域。RecSys-...

      recsys-2019:推荐系统挑战库

      在2019年的推荐系统挑战(RecSys Challenge 2019)中,研究者们共享了一个数据集,以促进推荐算法的发展和评估。这个数据集被称为"recsys-2019",它包含丰富的用户行为信息,可以用于训练和测试推荐模型。 该挑战库...

      18a-RecSys-Zuoxin-2015:推荐系统课程作业

      【推荐系统概述】 推荐系统是信息技术领域中的一个重要分支,它主要负责在海量信息中为用户推荐最感兴趣、最有价值的内容或产品。这类系统广泛应用于电商、电影推荐、音乐流媒体等场景,通过分析用户的历史行为、...

      RecSys-Dev-Practice:推荐系统开发实战-以notebook形式展现

      在《推荐系统开发实战》一书中,作者高阳团队深入浅出地介绍了推荐系统的理论与实践,涵盖了从数据预处理、模型构建到效果评估的全过程。本实践项目基于该书内容,提供了实际操作的平台,帮助开发者更好地掌握推荐...

      recsys-challenge-2018:提交给RecSys Challenge 2018的最终解决方案的代码

      该存储库包含用于生成最终解决方案的脚本。 团队成员: , , ,Maksym Semikin,Meri Liis Treimann,Christian Safka。 产生提交 步骤0:创建一个新的Conda环境并安装所需的库 create conda --name recsys ...

      RecSys-Book-Notes:推荐系统读书笔记,思维导图等

      "RecSys-Book-Notes"是一个专注于推荐系统领域的学习资源集合,其中包含了多个相关书籍的笔记和思维导图,帮助读者深入理解这一领域的核心概念和技术。 首先,我们关注到《Python数据科学手册》。这本书是Python...

      awesome-RecSys-papers:推荐系统中的超赞经典论文!!! 祝每位RecSys学习者好运!

      推荐系统(Recommendation System,简称RecSys)是信息过滤系统的一种,它旨在预测用户可能感兴趣的物品或服务,以此提供个性化的推荐。在大数据时代,推荐系统已成为电子商务、社交媒体、在线娱乐等领域的重要组成...

      recsys-online:一个推荐系统的在线端

      Recsys-online是一个推荐系统的在线计算部分,接收,存储日志并生成用户首选,它: 1.基于Kafka,Storm,HBase,Zookeeper开发的2.总体只支持的流程:从Kafka中读取数据==&gt; Storm数据处理===&gt; HBase存储 当前版本...

      18a-RecSys-Wangshuyun-2015:推荐系统入门课程作业

      本项目“18a-RecSys-Wangshuyun-2015”是一个入门级别的推荐系统课程作业,旨在帮助初学者掌握推荐系统的基本原理和实现方法。在GitHub上开源,它提供了逐步学习和实践的机会。 项目工作分为三个部分:Work1、Work2...

      recsys-101-workshop:推荐系统互动研讨会

      在此交互式研讨会中,我们将介绍和实践有关推荐系统的最重要概念,即个性化体验背后的力量。 在研讨会结束之前,您将能够以非正式和互动的方式构建和评估自己的推荐系统,并在我们的导师的帮助下讨论结果。 如果您...

      RecSys-DAE-tensorflow:使用TensorFlow实现的使用降噪自动编码器的简单推荐系统

      在本项目"RecSys-DAE-tensorflow"中,我们关注的是利用TensorFlow框架构建一个基于降噪自编码器(Denoising Autoencoder, DAE)的推荐系统。降噪自编码器是一种深度学习模型,它在传统的自编码器基础上增加了噪声处理...

    Global site tag (gtag.js) - Google Analytics