#研发解决方案介绍#Recsys-Evaluate(推荐评测),
#研发解决方案介绍#Recsys-Evaluate(推荐评测),
郑昀 基于刘金鑫文档 最后更新于2014/12/1 关键词:recsys、推荐评测、Evaluation of Recommender System、piwik、flume、kafka、storm、redis、mysql本文档适用人员:研发 推荐系统可不仅仅是围着推荐算法打转 先明确一下,我们属于工业领域。很多在学术论文里行之有效的新特奇算法,在工业界是行不通的。当年我们做语义聚合时,分词、聚类、相似性计算、实体词识别、情感分析等领域最终还都采用了工业界十几年前乃至于几十年前就流行的成熟算法。如果算法不能决定命运,那什么是关键呢? 算法+规则库+人工干预(整理语料、标识、调参数等),大都是脏活儿累活儿。 或者叫,特征+算法+人工干预,用特征缩小数据范围或降维。 我在2009年曾经写道:
在语义的世界里,可以近似地说:万事万物都是特征提取。 你只要找到特征,事情就好办。…… ……你期望毕其功于一役吗?自然语言处理的真实应用里是很难有什么场景找到一个通吃特征的。都是一层一层特征叠加的。 一层特征去掉一部分垃圾数据。如此反复,终成正果。注意方法论。梁斌在2012年微博说道:
统计粗且糙,乃大锤。规则细而精,乃小锤。先大场后细棋。
规则库怎么来的?得建设一些方便观测的外围系统,才能发现特征、建立规则、调整参数、观察效果。所以与此类似,做了推荐服务后,就需要推荐效果评测了。
推荐评测应用场景
电商推荐场景下有非常明确的指标:
那么推荐评测系统应具备的功能有:
- 暴露出来,让我们手工就可以提交,看看效果
- 如果配置为每新增一条日志就采集,那么 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
- 就一般情况而言,单条发射能扛得住
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) { |
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(); } } |
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
窝窝的解决方案介绍列表:
#研发解决方案#基于StatsD+Graphite的智能监控解决方案
#研发中间件介绍#定时任务调度与管理JobCenter
#研发解决方案介绍#Recsys-Evaluate(推荐评测)
#研发解决方案介绍#Tracing(鹰眼)
#研发解决方案介绍#基于持久化配置中心的业务降级
#研发中间件介绍#异步消息可靠推送Notify
#研发解决方案介绍#IdCenter(内部统一认证系统)
#研发解决方案介绍#基于ES的搜索+筛选+排序解决方案
#数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie 欢迎订阅我的微信订阅号『老兵笔记』,请扫描二维码关注:
评论暂时关闭